mirror of https://github.com/xemu-project/xemu.git
target/riscv: support the AIA device emulation with KVM enabled
In this patch, we create the APLIC and IMSIC FDT helper functions and remove M mode AIA devices when using KVM acceleration. Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com> Reviewed-by: Jim Shu <jim.shu@sifive.com> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Message-ID: <20230727102439.22554-2-yongxuan.wang@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
ae7d4d625c
commit
59a07d3c61
306
hw/riscv/virt.c
306
hw/riscv/virt.c
|
@ -516,79 +516,28 @@ static uint32_t imsic_num_bits(uint32_t count)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
|
static void create_fdt_one_imsic(RISCVVirtState *s, hwaddr base_addr,
|
||||||
uint32_t *phandle, uint32_t *intc_phandles,
|
uint32_t *intc_phandles, uint32_t msi_phandle,
|
||||||
uint32_t *msi_m_phandle, uint32_t *msi_s_phandle)
|
bool m_mode, uint32_t imsic_guest_bits)
|
||||||
{
|
{
|
||||||
int cpu, socket;
|
int cpu, socket;
|
||||||
char *imsic_name;
|
char *imsic_name;
|
||||||
MachineState *ms = MACHINE(s);
|
MachineState *ms = MACHINE(s);
|
||||||
int socket_count = riscv_socket_count(ms);
|
int socket_count = riscv_socket_count(ms);
|
||||||
uint32_t imsic_max_hart_per_socket, imsic_guest_bits;
|
uint32_t imsic_max_hart_per_socket;
|
||||||
uint32_t *imsic_cells, *imsic_regs, imsic_addr, imsic_size;
|
uint32_t *imsic_cells, *imsic_regs, imsic_addr, imsic_size;
|
||||||
|
|
||||||
*msi_m_phandle = (*phandle)++;
|
|
||||||
*msi_s_phandle = (*phandle)++;
|
|
||||||
imsic_cells = g_new0(uint32_t, ms->smp.cpus * 2);
|
imsic_cells = g_new0(uint32_t, ms->smp.cpus * 2);
|
||||||
imsic_regs = g_new0(uint32_t, socket_count * 4);
|
imsic_regs = g_new0(uint32_t, socket_count * 4);
|
||||||
|
|
||||||
/* M-level IMSIC node */
|
|
||||||
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
|
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
|
||||||
imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
|
imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
|
||||||
imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
|
imsic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
imsic_max_hart_per_socket = 0;
|
imsic_max_hart_per_socket = 0;
|
||||||
for (socket = 0; socket < socket_count; socket++) {
|
for (socket = 0; socket < socket_count; socket++) {
|
||||||
imsic_addr = memmap[VIRT_IMSIC_M].base +
|
imsic_addr = base_addr + socket * VIRT_IMSIC_GROUP_MAX_SIZE;
|
||||||
socket * VIRT_IMSIC_GROUP_MAX_SIZE;
|
|
||||||
imsic_size = IMSIC_HART_SIZE(0) * s->soc[socket].num_harts;
|
|
||||||
imsic_regs[socket * 4 + 0] = 0;
|
|
||||||
imsic_regs[socket * 4 + 1] = cpu_to_be32(imsic_addr);
|
|
||||||
imsic_regs[socket * 4 + 2] = 0;
|
|
||||||
imsic_regs[socket * 4 + 3] = cpu_to_be32(imsic_size);
|
|
||||||
if (imsic_max_hart_per_socket < s->soc[socket].num_harts) {
|
|
||||||
imsic_max_hart_per_socket = s->soc[socket].num_harts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imsic_name = g_strdup_printf("/soc/imsics@%lx",
|
|
||||||
(unsigned long)memmap[VIRT_IMSIC_M].base);
|
|
||||||
qemu_fdt_add_subnode(ms->fdt, imsic_name);
|
|
||||||
qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
|
|
||||||
"riscv,imsics");
|
|
||||||
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
|
|
||||||
FDT_IMSIC_INT_CELLS);
|
|
||||||
qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
|
|
||||||
NULL, 0);
|
|
||||||
qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
|
|
||||||
NULL, 0);
|
|
||||||
qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
|
|
||||||
imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
|
|
||||||
qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
|
|
||||||
socket_count * sizeof(uint32_t) * 4);
|
|
||||||
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
|
|
||||||
VIRT_IRQCHIP_NUM_MSIS);
|
|
||||||
if (socket_count > 1) {
|
|
||||||
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
|
|
||||||
imsic_num_bits(imsic_max_hart_per_socket));
|
|
||||||
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
|
|
||||||
imsic_num_bits(socket_count));
|
|
||||||
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
|
|
||||||
IMSIC_MMIO_GROUP_MIN_SHIFT);
|
|
||||||
}
|
|
||||||
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_m_phandle);
|
|
||||||
|
|
||||||
g_free(imsic_name);
|
|
||||||
|
|
||||||
/* S-level IMSIC node */
|
|
||||||
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
|
|
||||||
imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
|
|
||||||
imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
|
|
||||||
}
|
|
||||||
imsic_guest_bits = imsic_num_bits(s->aia_guests + 1);
|
|
||||||
imsic_max_hart_per_socket = 0;
|
|
||||||
for (socket = 0; socket < socket_count; socket++) {
|
|
||||||
imsic_addr = memmap[VIRT_IMSIC_S].base +
|
|
||||||
socket * VIRT_IMSIC_GROUP_MAX_SIZE;
|
|
||||||
imsic_size = IMSIC_HART_SIZE(imsic_guest_bits) *
|
imsic_size = IMSIC_HART_SIZE(imsic_guest_bits) *
|
||||||
s->soc[socket].num_harts;
|
s->soc[socket].num_harts;
|
||||||
imsic_regs[socket * 4 + 0] = 0;
|
imsic_regs[socket * 4 + 0] = 0;
|
||||||
|
@ -599,42 +548,116 @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
|
||||||
imsic_max_hart_per_socket = s->soc[socket].num_harts;
|
imsic_max_hart_per_socket = s->soc[socket].num_harts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
imsic_name = g_strdup_printf("/soc/imsics@%lx",
|
|
||||||
(unsigned long)memmap[VIRT_IMSIC_S].base);
|
imsic_name = g_strdup_printf("/soc/imsics@%lx", (unsigned long)base_addr);
|
||||||
qemu_fdt_add_subnode(ms->fdt, imsic_name);
|
qemu_fdt_add_subnode(ms->fdt, imsic_name);
|
||||||
qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
|
qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible", "riscv,imsics");
|
||||||
"riscv,imsics");
|
|
||||||
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
|
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
|
||||||
FDT_IMSIC_INT_CELLS);
|
FDT_IMSIC_INT_CELLS);
|
||||||
qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
|
qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller", NULL, 0);
|
||||||
NULL, 0);
|
qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller", NULL, 0);
|
||||||
qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
|
|
||||||
NULL, 0);
|
|
||||||
qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
|
qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
|
||||||
imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
|
imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
|
||||||
qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
|
qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
|
||||||
socket_count * sizeof(uint32_t) * 4);
|
socket_count * sizeof(uint32_t) * 4);
|
||||||
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
|
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
|
||||||
VIRT_IRQCHIP_NUM_MSIS);
|
VIRT_IRQCHIP_NUM_MSIS);
|
||||||
|
|
||||||
if (imsic_guest_bits) {
|
if (imsic_guest_bits) {
|
||||||
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,guest-index-bits",
|
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,guest-index-bits",
|
||||||
imsic_guest_bits);
|
imsic_guest_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (socket_count > 1) {
|
if (socket_count > 1) {
|
||||||
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
|
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
|
||||||
imsic_num_bits(imsic_max_hart_per_socket));
|
imsic_num_bits(imsic_max_hart_per_socket));
|
||||||
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
|
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
|
||||||
imsic_num_bits(socket_count));
|
imsic_num_bits(socket_count));
|
||||||
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
|
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
|
||||||
IMSIC_MMIO_GROUP_MIN_SHIFT);
|
IMSIC_MMIO_GROUP_MIN_SHIFT);
|
||||||
}
|
}
|
||||||
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_s_phandle);
|
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", msi_phandle);
|
||||||
g_free(imsic_name);
|
|
||||||
|
|
||||||
|
g_free(imsic_name);
|
||||||
g_free(imsic_regs);
|
g_free(imsic_regs);
|
||||||
g_free(imsic_cells);
|
g_free(imsic_cells);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
|
||||||
|
uint32_t *phandle, uint32_t *intc_phandles,
|
||||||
|
uint32_t *msi_m_phandle, uint32_t *msi_s_phandle)
|
||||||
|
{
|
||||||
|
*msi_m_phandle = (*phandle)++;
|
||||||
|
*msi_s_phandle = (*phandle)++;
|
||||||
|
|
||||||
|
if (!kvm_enabled()) {
|
||||||
|
/* M-level IMSIC node */
|
||||||
|
create_fdt_one_imsic(s, memmap[VIRT_IMSIC_M].base, intc_phandles,
|
||||||
|
*msi_m_phandle, true, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* S-level IMSIC node */
|
||||||
|
create_fdt_one_imsic(s, memmap[VIRT_IMSIC_S].base, intc_phandles,
|
||||||
|
*msi_s_phandle, false,
|
||||||
|
imsic_num_bits(s->aia_guests + 1));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
|
||||||
|
unsigned long aplic_addr, uint32_t aplic_size,
|
||||||
|
uint32_t msi_phandle,
|
||||||
|
uint32_t *intc_phandles,
|
||||||
|
uint32_t aplic_phandle,
|
||||||
|
uint32_t aplic_child_phandle,
|
||||||
|
bool m_mode)
|
||||||
|
{
|
||||||
|
int cpu;
|
||||||
|
char *aplic_name;
|
||||||
|
uint32_t *aplic_cells;
|
||||||
|
MachineState *ms = MACHINE(s);
|
||||||
|
|
||||||
|
aplic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
|
||||||
|
|
||||||
|
for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
|
||||||
|
aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
|
||||||
|
aplic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
|
||||||
|
qemu_fdt_add_subnode(ms->fdt, aplic_name);
|
||||||
|
qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
|
||||||
|
qemu_fdt_setprop_cell(ms->fdt, aplic_name,
|
||||||
|
"#interrupt-cells", FDT_APLIC_INT_CELLS);
|
||||||
|
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
|
||||||
|
|
||||||
|
if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
|
||||||
|
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
|
||||||
|
aplic_cells,
|
||||||
|
s->soc[socket].num_harts * sizeof(uint32_t) * 2);
|
||||||
|
} else {
|
||||||
|
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent", msi_phandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
|
||||||
|
0x0, aplic_addr, 0x0, aplic_size);
|
||||||
|
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
|
||||||
|
VIRT_IRQCHIP_NUM_SOURCES);
|
||||||
|
|
||||||
|
if (aplic_child_phandle) {
|
||||||
|
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,children",
|
||||||
|
aplic_child_phandle);
|
||||||
|
qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate",
|
||||||
|
aplic_child_phandle, 0x1,
|
||||||
|
VIRT_IRQCHIP_NUM_SOURCES);
|
||||||
|
}
|
||||||
|
|
||||||
|
riscv_socket_fdt_write_id(ms, aplic_name, socket);
|
||||||
|
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_phandle);
|
||||||
|
|
||||||
|
g_free(aplic_name);
|
||||||
|
g_free(aplic_cells);
|
||||||
|
}
|
||||||
|
|
||||||
static void create_fdt_socket_aplic(RISCVVirtState *s,
|
static void create_fdt_socket_aplic(RISCVVirtState *s,
|
||||||
const MemMapEntry *memmap, int socket,
|
const MemMapEntry *memmap, int socket,
|
||||||
uint32_t msi_m_phandle,
|
uint32_t msi_m_phandle,
|
||||||
|
@ -643,75 +666,33 @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
|
||||||
uint32_t *intc_phandles,
|
uint32_t *intc_phandles,
|
||||||
uint32_t *aplic_phandles)
|
uint32_t *aplic_phandles)
|
||||||
{
|
{
|
||||||
int cpu;
|
|
||||||
char *aplic_name;
|
char *aplic_name;
|
||||||
uint32_t *aplic_cells;
|
|
||||||
unsigned long aplic_addr;
|
unsigned long aplic_addr;
|
||||||
MachineState *ms = MACHINE(s);
|
MachineState *ms = MACHINE(s);
|
||||||
uint32_t aplic_m_phandle, aplic_s_phandle;
|
uint32_t aplic_m_phandle, aplic_s_phandle;
|
||||||
|
|
||||||
aplic_m_phandle = (*phandle)++;
|
aplic_m_phandle = (*phandle)++;
|
||||||
aplic_s_phandle = (*phandle)++;
|
aplic_s_phandle = (*phandle)++;
|
||||||
aplic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
|
|
||||||
|
|
||||||
/* M-level APLIC node */
|
if (!kvm_enabled()) {
|
||||||
for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
|
/* M-level APLIC node */
|
||||||
aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
|
aplic_addr = memmap[VIRT_APLIC_M].base +
|
||||||
aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
|
(memmap[VIRT_APLIC_M].size * socket);
|
||||||
|
create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_M].size,
|
||||||
|
msi_m_phandle, intc_phandles,
|
||||||
|
aplic_m_phandle, aplic_s_phandle,
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
aplic_addr = memmap[VIRT_APLIC_M].base +
|
|
||||||
(memmap[VIRT_APLIC_M].size * socket);
|
|
||||||
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
|
|
||||||
qemu_fdt_add_subnode(ms->fdt, aplic_name);
|
|
||||||
qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
|
|
||||||
qemu_fdt_setprop_cell(ms->fdt, aplic_name,
|
|
||||||
"#interrupt-cells", FDT_APLIC_INT_CELLS);
|
|
||||||
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
|
|
||||||
if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
|
|
||||||
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
|
|
||||||
aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2);
|
|
||||||
} else {
|
|
||||||
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent",
|
|
||||||
msi_m_phandle);
|
|
||||||
}
|
|
||||||
qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
|
|
||||||
0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_M].size);
|
|
||||||
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
|
|
||||||
VIRT_IRQCHIP_NUM_SOURCES);
|
|
||||||
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,children",
|
|
||||||
aplic_s_phandle);
|
|
||||||
qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate",
|
|
||||||
aplic_s_phandle, 0x1, VIRT_IRQCHIP_NUM_SOURCES);
|
|
||||||
riscv_socket_fdt_write_id(ms, aplic_name, socket);
|
|
||||||
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_m_phandle);
|
|
||||||
g_free(aplic_name);
|
|
||||||
|
|
||||||
/* S-level APLIC node */
|
/* S-level APLIC node */
|
||||||
for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
|
|
||||||
aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
|
|
||||||
aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
|
|
||||||
}
|
|
||||||
aplic_addr = memmap[VIRT_APLIC_S].base +
|
aplic_addr = memmap[VIRT_APLIC_S].base +
|
||||||
(memmap[VIRT_APLIC_S].size * socket);
|
(memmap[VIRT_APLIC_S].size * socket);
|
||||||
|
create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_S].size,
|
||||||
|
msi_s_phandle, intc_phandles,
|
||||||
|
aplic_s_phandle, 0,
|
||||||
|
false);
|
||||||
|
|
||||||
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
|
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
|
||||||
qemu_fdt_add_subnode(ms->fdt, aplic_name);
|
|
||||||
qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
|
|
||||||
qemu_fdt_setprop_cell(ms->fdt, aplic_name,
|
|
||||||
"#interrupt-cells", FDT_APLIC_INT_CELLS);
|
|
||||||
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
|
|
||||||
if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
|
|
||||||
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
|
|
||||||
aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2);
|
|
||||||
} else {
|
|
||||||
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent",
|
|
||||||
msi_s_phandle);
|
|
||||||
}
|
|
||||||
qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
|
|
||||||
0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_S].size);
|
|
||||||
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
|
|
||||||
VIRT_IRQCHIP_NUM_SOURCES);
|
|
||||||
riscv_socket_fdt_write_id(ms, aplic_name, socket);
|
|
||||||
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_s_phandle);
|
|
||||||
|
|
||||||
if (!socket) {
|
if (!socket) {
|
||||||
platform_bus_add_all_fdt_nodes(ms->fdt, aplic_name,
|
platform_bus_add_all_fdt_nodes(ms->fdt, aplic_name,
|
||||||
|
@ -722,7 +703,6 @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
|
||||||
|
|
||||||
g_free(aplic_name);
|
g_free(aplic_name);
|
||||||
|
|
||||||
g_free(aplic_cells);
|
|
||||||
aplic_phandles[socket] = aplic_s_phandle;
|
aplic_phandles[socket] = aplic_s_phandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1163,16 +1143,20 @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
|
||||||
int i;
|
int i;
|
||||||
hwaddr addr;
|
hwaddr addr;
|
||||||
uint32_t guest_bits;
|
uint32_t guest_bits;
|
||||||
DeviceState *aplic_m;
|
DeviceState *aplic_s = NULL;
|
||||||
bool msimode = (aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) ? true : false;
|
DeviceState *aplic_m = NULL;
|
||||||
|
bool msimode = aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
|
||||||
|
|
||||||
if (msimode) {
|
if (msimode) {
|
||||||
/* Per-socket M-level IMSICs */
|
if (!kvm_enabled()) {
|
||||||
addr = memmap[VIRT_IMSIC_M].base + socket * VIRT_IMSIC_GROUP_MAX_SIZE;
|
/* Per-socket M-level IMSICs */
|
||||||
for (i = 0; i < hart_count; i++) {
|
addr = memmap[VIRT_IMSIC_M].base +
|
||||||
riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0),
|
socket * VIRT_IMSIC_GROUP_MAX_SIZE;
|
||||||
base_hartid + i, true, 1,
|
for (i = 0; i < hart_count; i++) {
|
||||||
VIRT_IRQCHIP_NUM_MSIS);
|
riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0),
|
||||||
|
base_hartid + i, true, 1,
|
||||||
|
VIRT_IRQCHIP_NUM_MSIS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Per-socket S-level IMSICs */
|
/* Per-socket S-level IMSICs */
|
||||||
|
@ -1185,29 +1169,29 @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Per-socket M-level APLIC */
|
if (!kvm_enabled()) {
|
||||||
aplic_m = riscv_aplic_create(
|
/* Per-socket M-level APLIC */
|
||||||
memmap[VIRT_APLIC_M].base + socket * memmap[VIRT_APLIC_M].size,
|
aplic_m = riscv_aplic_create(memmap[VIRT_APLIC_M].base +
|
||||||
memmap[VIRT_APLIC_M].size,
|
socket * memmap[VIRT_APLIC_M].size,
|
||||||
(msimode) ? 0 : base_hartid,
|
memmap[VIRT_APLIC_M].size,
|
||||||
(msimode) ? 0 : hart_count,
|
(msimode) ? 0 : base_hartid,
|
||||||
VIRT_IRQCHIP_NUM_SOURCES,
|
(msimode) ? 0 : hart_count,
|
||||||
VIRT_IRQCHIP_NUM_PRIO_BITS,
|
VIRT_IRQCHIP_NUM_SOURCES,
|
||||||
msimode, true, NULL);
|
VIRT_IRQCHIP_NUM_PRIO_BITS,
|
||||||
|
msimode, true, NULL);
|
||||||
if (aplic_m) {
|
|
||||||
/* Per-socket S-level APLIC */
|
|
||||||
riscv_aplic_create(
|
|
||||||
memmap[VIRT_APLIC_S].base + socket * memmap[VIRT_APLIC_S].size,
|
|
||||||
memmap[VIRT_APLIC_S].size,
|
|
||||||
(msimode) ? 0 : base_hartid,
|
|
||||||
(msimode) ? 0 : hart_count,
|
|
||||||
VIRT_IRQCHIP_NUM_SOURCES,
|
|
||||||
VIRT_IRQCHIP_NUM_PRIO_BITS,
|
|
||||||
msimode, false, aplic_m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return aplic_m;
|
/* Per-socket S-level APLIC */
|
||||||
|
aplic_s = riscv_aplic_create(memmap[VIRT_APLIC_S].base +
|
||||||
|
socket * memmap[VIRT_APLIC_S].size,
|
||||||
|
memmap[VIRT_APLIC_S].size,
|
||||||
|
(msimode) ? 0 : base_hartid,
|
||||||
|
(msimode) ? 0 : hart_count,
|
||||||
|
VIRT_IRQCHIP_NUM_SOURCES,
|
||||||
|
VIRT_IRQCHIP_NUM_PRIO_BITS,
|
||||||
|
msimode, false, aplic_m);
|
||||||
|
|
||||||
|
return kvm_enabled() ? aplic_s : aplic_m;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_platform_bus(RISCVVirtState *s, DeviceState *irqchip)
|
static void create_platform_bus(RISCVVirtState *s, DeviceState *irqchip)
|
||||||
|
|
Loading…
Reference in New Issue