hw/riscv: Allow creating multiple instances of PLIC
We extend PLIC emulation to allow multiple instances of PLIC in a QEMU RISC-V machine. To achieve this, we remove first HART id zero assumption from PLIC emulation. Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-Id: <20200616032229.766089-3-anup.patel@wdc.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
3bf03f0899
commit
c9270e10a5
@ -200,7 +200,7 @@ static void sifive_e_soc_realize(DeviceState *dev, Error **errp)
|
|||||||
|
|
||||||
/* MMIO */
|
/* MMIO */
|
||||||
s->plic = sifive_plic_create(memmap[SIFIVE_E_PLIC].base,
|
s->plic = sifive_plic_create(memmap[SIFIVE_E_PLIC].base,
|
||||||
(char *)SIFIVE_E_PLIC_HART_CONFIG,
|
(char *)SIFIVE_E_PLIC_HART_CONFIG, 0,
|
||||||
SIFIVE_E_PLIC_NUM_SOURCES,
|
SIFIVE_E_PLIC_NUM_SOURCES,
|
||||||
SIFIVE_E_PLIC_NUM_PRIORITIES,
|
SIFIVE_E_PLIC_NUM_PRIORITIES,
|
||||||
SIFIVE_E_PLIC_PRIORITY_BASE,
|
SIFIVE_E_PLIC_PRIORITY_BASE,
|
||||||
|
@ -361,6 +361,7 @@ static const MemoryRegionOps sifive_plic_ops = {
|
|||||||
|
|
||||||
static Property sifive_plic_properties[] = {
|
static Property sifive_plic_properties[] = {
|
||||||
DEFINE_PROP_STRING("hart-config", SiFivePLICState, hart_config),
|
DEFINE_PROP_STRING("hart-config", SiFivePLICState, hart_config),
|
||||||
|
DEFINE_PROP_UINT32("hartid-base", SiFivePLICState, hartid_base, 0),
|
||||||
DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 0),
|
DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 0),
|
||||||
DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
|
DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
|
||||||
DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
|
DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
|
||||||
@ -409,10 +410,12 @@ static void parse_hart_config(SiFivePLICState *plic)
|
|||||||
}
|
}
|
||||||
hartid++;
|
hartid++;
|
||||||
|
|
||||||
/* store hart/mode combinations */
|
|
||||||
plic->num_addrs = addrid;
|
plic->num_addrs = addrid;
|
||||||
|
plic->num_harts = hartid;
|
||||||
|
|
||||||
|
/* store hart/mode combinations */
|
||||||
plic->addr_config = g_new(PLICAddr, plic->num_addrs);
|
plic->addr_config = g_new(PLICAddr, plic->num_addrs);
|
||||||
addrid = 0, hartid = 0;
|
addrid = 0, hartid = plic->hartid_base;
|
||||||
p = plic->hart_config;
|
p = plic->hart_config;
|
||||||
while ((c = *p++)) {
|
while ((c = *p++)) {
|
||||||
if (c == ',') {
|
if (c == ',') {
|
||||||
@ -438,8 +441,6 @@ static void sifive_plic_irq_request(void *opaque, int irq, int level)
|
|||||||
|
|
||||||
static void sifive_plic_realize(DeviceState *dev, Error **errp)
|
static void sifive_plic_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
MachineState *ms = MACHINE(qdev_get_machine());
|
|
||||||
unsigned int smp_cpus = ms->smp.cpus;
|
|
||||||
SiFivePLICState *plic = SIFIVE_PLIC(dev);
|
SiFivePLICState *plic = SIFIVE_PLIC(dev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -460,8 +461,8 @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
|
|||||||
* lost a interrupt in the case a PLIC is attached. The SEIP bit must be
|
* lost a interrupt in the case a PLIC is attached. The SEIP bit must be
|
||||||
* hardware controlled when a PLIC is attached.
|
* hardware controlled when a PLIC is attached.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < smp_cpus; i++) {
|
for (i = 0; i < plic->num_harts; i++) {
|
||||||
RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(i));
|
RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(plic->hartid_base + i));
|
||||||
if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
|
if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
|
||||||
error_report("SEIP already claimed");
|
error_report("SEIP already claimed");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -497,16 +498,17 @@ type_init(sifive_plic_register_types)
|
|||||||
* Create PLIC device.
|
* Create PLIC device.
|
||||||
*/
|
*/
|
||||||
DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
|
DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
|
||||||
uint32_t num_sources, uint32_t num_priorities,
|
uint32_t hartid_base, uint32_t num_sources,
|
||||||
uint32_t priority_base, uint32_t pending_base,
|
uint32_t num_priorities, uint32_t priority_base,
|
||||||
uint32_t enable_base, uint32_t enable_stride,
|
uint32_t pending_base, uint32_t enable_base,
|
||||||
uint32_t context_base, uint32_t context_stride,
|
uint32_t enable_stride, uint32_t context_base,
|
||||||
uint32_t aperture_size)
|
uint32_t context_stride, uint32_t aperture_size)
|
||||||
{
|
{
|
||||||
DeviceState *dev = qdev_new(TYPE_SIFIVE_PLIC);
|
DeviceState *dev = qdev_new(TYPE_SIFIVE_PLIC);
|
||||||
assert(enable_stride == (enable_stride & -enable_stride));
|
assert(enable_stride == (enable_stride & -enable_stride));
|
||||||
assert(context_stride == (context_stride & -context_stride));
|
assert(context_stride == (context_stride & -context_stride));
|
||||||
qdev_prop_set_string(dev, "hart-config", hart_config);
|
qdev_prop_set_string(dev, "hart-config", hart_config);
|
||||||
|
qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
|
||||||
qdev_prop_set_uint32(dev, "num-sources", num_sources);
|
qdev_prop_set_uint32(dev, "num-sources", num_sources);
|
||||||
qdev_prop_set_uint32(dev, "num-priorities", num_priorities);
|
qdev_prop_set_uint32(dev, "num-priorities", num_priorities);
|
||||||
qdev_prop_set_uint32(dev, "priority-base", priority_base);
|
qdev_prop_set_uint32(dev, "priority-base", priority_base);
|
||||||
|
@ -687,7 +687,7 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
|
|||||||
|
|
||||||
/* MMIO */
|
/* MMIO */
|
||||||
s->plic = sifive_plic_create(memmap[SIFIVE_U_PLIC].base,
|
s->plic = sifive_plic_create(memmap[SIFIVE_U_PLIC].base,
|
||||||
plic_hart_config,
|
plic_hart_config, 0,
|
||||||
SIFIVE_U_PLIC_NUM_SOURCES,
|
SIFIVE_U_PLIC_NUM_SOURCES,
|
||||||
SIFIVE_U_PLIC_NUM_PRIORITIES,
|
SIFIVE_U_PLIC_NUM_PRIORITIES,
|
||||||
SIFIVE_U_PLIC_PRIORITY_BASE,
|
SIFIVE_U_PLIC_PRIORITY_BASE,
|
||||||
|
@ -560,7 +560,7 @@ static void virt_machine_init(MachineState *machine)
|
|||||||
|
|
||||||
/* MMIO */
|
/* MMIO */
|
||||||
s->plic = sifive_plic_create(memmap[VIRT_PLIC].base,
|
s->plic = sifive_plic_create(memmap[VIRT_PLIC].base,
|
||||||
plic_hart_config,
|
plic_hart_config, 0,
|
||||||
VIRT_PLIC_NUM_SOURCES,
|
VIRT_PLIC_NUM_SOURCES,
|
||||||
VIRT_PLIC_NUM_PRIORITIES,
|
VIRT_PLIC_NUM_PRIORITIES,
|
||||||
VIRT_PLIC_PRIORITY_BASE,
|
VIRT_PLIC_PRIORITY_BASE,
|
||||||
|
@ -48,6 +48,7 @@ typedef struct SiFivePLICState {
|
|||||||
/*< public >*/
|
/*< public >*/
|
||||||
MemoryRegion mmio;
|
MemoryRegion mmio;
|
||||||
uint32_t num_addrs;
|
uint32_t num_addrs;
|
||||||
|
uint32_t num_harts;
|
||||||
uint32_t bitfield_words;
|
uint32_t bitfield_words;
|
||||||
PLICAddr *addr_config;
|
PLICAddr *addr_config;
|
||||||
uint32_t *source_priority;
|
uint32_t *source_priority;
|
||||||
@ -58,6 +59,7 @@ typedef struct SiFivePLICState {
|
|||||||
|
|
||||||
/* config */
|
/* config */
|
||||||
char *hart_config;
|
char *hart_config;
|
||||||
|
uint32_t hartid_base;
|
||||||
uint32_t num_sources;
|
uint32_t num_sources;
|
||||||
uint32_t num_priorities;
|
uint32_t num_priorities;
|
||||||
uint32_t priority_base;
|
uint32_t priority_base;
|
||||||
@ -70,10 +72,10 @@ typedef struct SiFivePLICState {
|
|||||||
} SiFivePLICState;
|
} SiFivePLICState;
|
||||||
|
|
||||||
DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
|
DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
|
||||||
uint32_t num_sources, uint32_t num_priorities,
|
uint32_t hartid_base, uint32_t num_sources,
|
||||||
uint32_t priority_base, uint32_t pending_base,
|
uint32_t num_priorities, uint32_t priority_base,
|
||||||
uint32_t enable_base, uint32_t enable_stride,
|
uint32_t pending_base, uint32_t enable_base,
|
||||||
uint32_t context_base, uint32_t context_stride,
|
uint32_t enable_stride, uint32_t context_base,
|
||||||
uint32_t aperture_size);
|
uint32_t context_stride, uint32_t aperture_size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user