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:
Anup Patel
2021-09-21 07:56:49 +10:00
committed by Alistair Francis
parent cc63a18282
commit b8fb878aa2
8 changed files with 339 additions and 156 deletions
+259 -114
View File
File diff suppressed because it is too large Load Diff
+6 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+36 -18
View File
@@ -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