mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
hw/intc: Upgrade the SiFive CLINT implementation to RISC-V ACLINT
The RISC-V ACLINT is more modular and backward compatible with original SiFive CLINT so instead of duplicating the original SiFive CLINT implementation we upgrade the current SiFive CLINT implementation to RISC-V ACLINT implementation. Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> Message-id: 20210831110603.338681-3-anup.patel@wdc.com Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
committed by
Alistair Francis
parent
cc63a18282
commit
b8fb878aa2
+259
-114
File diff suppressed because it is too large
Load Diff
@@ -234,9 +234,12 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
|
||||
memmap[MICROCHIP_PFSOC_BUSERR_UNIT4].size);
|
||||
|
||||
/* CLINT */
|
||||
sifive_clint_create(memmap[MICROCHIP_PFSOC_CLINT].base,
|
||||
memmap[MICROCHIP_PFSOC_CLINT].size, 0, ms->smp.cpus,
|
||||
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
|
||||
riscv_aclint_swi_create(memmap[MICROCHIP_PFSOC_CLINT].base,
|
||||
0, ms->smp.cpus, false);
|
||||
riscv_aclint_mtimer_create(
|
||||
memmap[MICROCHIP_PFSOC_CLINT].base + RISCV_ACLINT_SWI_SIZE,
|
||||
RISCV_ACLINT_DEFAULT_MTIMER_SIZE, 0, ms->smp.cpus,
|
||||
RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME,
|
||||
CLINT_TIMEBASE_FREQ, false);
|
||||
|
||||
/* L2 cache controller */
|
||||
|
||||
+7
-4
@@ -124,10 +124,13 @@ static void shakti_c_soc_state_realize(DeviceState *dev, Error **errp)
|
||||
SHAKTI_C_PLIC_CONTEXT_STRIDE,
|
||||
shakti_c_memmap[SHAKTI_C_PLIC].size);
|
||||
|
||||
sifive_clint_create(shakti_c_memmap[SHAKTI_C_CLINT].base,
|
||||
shakti_c_memmap[SHAKTI_C_CLINT].size, 0, 1,
|
||||
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
|
||||
SIFIVE_CLINT_TIMEBASE_FREQ, false);
|
||||
riscv_aclint_swi_create(shakti_c_memmap[SHAKTI_C_CLINT].base,
|
||||
0, 1, false);
|
||||
riscv_aclint_mtimer_create(shakti_c_memmap[SHAKTI_C_CLINT].base +
|
||||
RISCV_ACLINT_SWI_SIZE,
|
||||
RISCV_ACLINT_DEFAULT_MTIMER_SIZE, 0, 1,
|
||||
RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME,
|
||||
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, false);
|
||||
|
||||
qdev_prop_set_chr(DEVICE(&(sss->uart)), "chardev", serial_hd(0));
|
||||
if (!sysbus_realize(SYS_BUS_DEVICE(&sss->uart), errp)) {
|
||||
|
||||
+7
-4
@@ -207,10 +207,13 @@ static void sifive_e_soc_realize(DeviceState *dev, Error **errp)
|
||||
SIFIVE_E_PLIC_CONTEXT_BASE,
|
||||
SIFIVE_E_PLIC_CONTEXT_STRIDE,
|
||||
memmap[SIFIVE_E_DEV_PLIC].size);
|
||||
sifive_clint_create(memmap[SIFIVE_E_DEV_CLINT].base,
|
||||
memmap[SIFIVE_E_DEV_CLINT].size, 0, ms->smp.cpus,
|
||||
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
|
||||
SIFIVE_CLINT_TIMEBASE_FREQ, false);
|
||||
riscv_aclint_swi_create(memmap[SIFIVE_E_DEV_CLINT].base,
|
||||
0, ms->smp.cpus, false);
|
||||
riscv_aclint_mtimer_create(memmap[SIFIVE_E_DEV_CLINT].base +
|
||||
RISCV_ACLINT_SWI_SIZE,
|
||||
RISCV_ACLINT_DEFAULT_MTIMER_SIZE, 0, ms->smp.cpus,
|
||||
RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME,
|
||||
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, false);
|
||||
create_unimplemented_device("riscv.sifive.e.aon",
|
||||
memmap[SIFIVE_E_DEV_AON].base, memmap[SIFIVE_E_DEV_AON].size);
|
||||
sifive_e_prci_create(memmap[SIFIVE_E_DEV_PRCI].base);
|
||||
|
||||
+6
-3
@@ -884,9 +884,12 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
|
||||
serial_hd(0), qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_UART0_IRQ));
|
||||
sifive_uart_create(system_memory, memmap[SIFIVE_U_DEV_UART1].base,
|
||||
serial_hd(1), qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_UART1_IRQ));
|
||||
sifive_clint_create(memmap[SIFIVE_U_DEV_CLINT].base,
|
||||
memmap[SIFIVE_U_DEV_CLINT].size, 0, ms->smp.cpus,
|
||||
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
|
||||
riscv_aclint_swi_create(memmap[SIFIVE_U_DEV_CLINT].base, 0,
|
||||
ms->smp.cpus, false);
|
||||
riscv_aclint_mtimer_create(memmap[SIFIVE_U_DEV_CLINT].base +
|
||||
RISCV_ACLINT_SWI_SIZE,
|
||||
RISCV_ACLINT_DEFAULT_MTIMER_SIZE, 0, ms->smp.cpus,
|
||||
RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME,
|
||||
CLINT_TIMEBASE_FREQ, false);
|
||||
|
||||
if (!sysbus_realize(SYS_BUS_DEVICE(&s->prci), errp)) {
|
||||
|
||||
+9
-5
@@ -84,7 +84,7 @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
|
||||
|
||||
qemu_fdt_add_subnode(fdt, "/cpus");
|
||||
qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency",
|
||||
SIFIVE_CLINT_TIMEBASE_FREQ);
|
||||
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ);
|
||||
qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
|
||||
qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
|
||||
qemu_fdt_add_subnode(fdt, "/cpus/cpu-map");
|
||||
@@ -227,11 +227,15 @@ static void spike_board_init(MachineState *machine)
|
||||
sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_abort);
|
||||
|
||||
/* Core Local Interruptor (timer and IPI) for each socket */
|
||||
sifive_clint_create(
|
||||
riscv_aclint_swi_create(
|
||||
memmap[SPIKE_CLINT].base + i * memmap[SPIKE_CLINT].size,
|
||||
memmap[SPIKE_CLINT].size, base_hartid, hart_count,
|
||||
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
|
||||
SIFIVE_CLINT_TIMEBASE_FREQ, false);
|
||||
base_hartid, hart_count, false);
|
||||
riscv_aclint_mtimer_create(
|
||||
memmap[SPIKE_CLINT].base + i * memmap[SPIKE_CLINT].size +
|
||||
RISCV_ACLINT_SWI_SIZE,
|
||||
RISCV_ACLINT_DEFAULT_MTIMER_SIZE, base_hartid, hart_count,
|
||||
RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME,
|
||||
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, false);
|
||||
}
|
||||
|
||||
/* register system main memory (actual RAM) */
|
||||
|
||||
+9
-5
@@ -228,7 +228,7 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
|
||||
|
||||
qemu_fdt_add_subnode(fdt, "/cpus");
|
||||
qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency",
|
||||
SIFIVE_CLINT_TIMEBASE_FREQ);
|
||||
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ);
|
||||
qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
|
||||
qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
|
||||
qemu_fdt_add_subnode(fdt, "/cpus/cpu-map");
|
||||
@@ -613,11 +613,15 @@ static void virt_machine_init(MachineState *machine)
|
||||
sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_abort);
|
||||
|
||||
/* Per-socket CLINT */
|
||||
sifive_clint_create(
|
||||
riscv_aclint_swi_create(
|
||||
memmap[VIRT_CLINT].base + i * memmap[VIRT_CLINT].size,
|
||||
memmap[VIRT_CLINT].size, base_hartid, hart_count,
|
||||
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
|
||||
SIFIVE_CLINT_TIMEBASE_FREQ, true);
|
||||
base_hartid, hart_count, false);
|
||||
riscv_aclint_mtimer_create(
|
||||
memmap[VIRT_CLINT].base + i * memmap[VIRT_CLINT].size +
|
||||
RISCV_ACLINT_SWI_SIZE,
|
||||
RISCV_ACLINT_DEFAULT_MTIMER_SIZE, base_hartid, hart_count,
|
||||
RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME,
|
||||
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, true);
|
||||
|
||||
/* Per-socket PLIC hart topology configuration string */
|
||||
plic_hart_config = plic_hart_config_string(hart_count);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
/*
|
||||
* SiFive CLINT (Core Local Interruptor) interface
|
||||
* RISC-V ACLINT (Advanced Core Local Interruptor) interface
|
||||
*
|
||||
* Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
|
||||
* Copyright (c) 2017 SiFive, Inc.
|
||||
* Copyright (c) 2021 Western Digital Corporation or its affiliates.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -17,17 +18,17 @@
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HW_SIFIVE_CLINT_H
|
||||
#define HW_SIFIVE_CLINT_H
|
||||
#ifndef HW_RISCV_ACLINT_H
|
||||
#define HW_RISCV_ACLINT_H
|
||||
|
||||
#include "hw/sysbus.h"
|
||||
|
||||
#define TYPE_SIFIVE_CLINT "riscv.sifive.clint"
|
||||
#define TYPE_RISCV_ACLINT_MTIMER "riscv.aclint.mtimer"
|
||||
|
||||
#define SIFIVE_CLINT(obj) \
|
||||
OBJECT_CHECK(SiFiveCLINTState, (obj), TYPE_SIFIVE_CLINT)
|
||||
#define RISCV_ACLINT_MTIMER(obj) \
|
||||
OBJECT_CHECK(RISCVAclintMTimerState, (obj), TYPE_RISCV_ACLINT_MTIMER)
|
||||
|
||||
typedef struct SiFiveCLINTState {
|
||||
typedef struct RISCVAclintMTimerState {
|
||||
/*< private >*/
|
||||
SysBusDevice parent_obj;
|
||||
|
||||
@@ -35,28 +36,45 @@ typedef struct SiFiveCLINTState {
|
||||
MemoryRegion mmio;
|
||||
uint32_t hartid_base;
|
||||
uint32_t num_harts;
|
||||
uint32_t sip_base;
|
||||
uint32_t timecmp_base;
|
||||
uint32_t time_base;
|
||||
uint32_t aperture_size;
|
||||
uint32_t timebase_freq;
|
||||
qemu_irq *timer_irqs;
|
||||
qemu_irq *soft_irqs;
|
||||
} SiFiveCLINTState;
|
||||
} RISCVAclintMTimerState;
|
||||
|
||||
DeviceState *sifive_clint_create(hwaddr addr, hwaddr size,
|
||||
uint32_t hartid_base, uint32_t num_harts, uint32_t sip_base,
|
||||
DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size,
|
||||
uint32_t hartid_base, uint32_t num_harts,
|
||||
uint32_t timecmp_base, uint32_t time_base, uint32_t timebase_freq,
|
||||
bool provide_rdtime);
|
||||
|
||||
enum {
|
||||
SIFIVE_SIP_BASE = 0x0,
|
||||
SIFIVE_TIMECMP_BASE = 0x4000,
|
||||
SIFIVE_TIME_BASE = 0xBFF8
|
||||
};
|
||||
#define TYPE_RISCV_ACLINT_SWI "riscv.aclint.swi"
|
||||
|
||||
#define RISCV_ACLINT_SWI(obj) \
|
||||
OBJECT_CHECK(RISCVAclintSwiState, (obj), TYPE_RISCV_ACLINT_SWI)
|
||||
|
||||
typedef struct RISCVAclintSwiState {
|
||||
/*< private >*/
|
||||
SysBusDevice parent_obj;
|
||||
|
||||
/*< public >*/
|
||||
MemoryRegion mmio;
|
||||
uint32_t hartid_base;
|
||||
uint32_t num_harts;
|
||||
uint32_t sswi;
|
||||
qemu_irq *soft_irqs;
|
||||
} RISCVAclintSwiState;
|
||||
|
||||
DeviceState *riscv_aclint_swi_create(hwaddr addr, uint32_t hartid_base,
|
||||
uint32_t num_harts, bool sswi);
|
||||
|
||||
enum {
|
||||
SIFIVE_CLINT_TIMEBASE_FREQ = 10000000
|
||||
RISCV_ACLINT_DEFAULT_MTIMECMP = 0x0,
|
||||
RISCV_ACLINT_DEFAULT_MTIME = 0x7ff8,
|
||||
RISCV_ACLINT_DEFAULT_MTIMER_SIZE = 0x8000,
|
||||
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ = 10000000,
|
||||
RISCV_ACLINT_MAX_HARTS = 4095,
|
||||
RISCV_ACLINT_SWI_SIZE = 0x4000
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user