mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 09:43:56 -06:00
SiFive RISC-V GPIO Device
QEMU model of the GPIO device on the SiFive E300 series SOCs. The pins are not used by a board definition yet, however this implementation can already be used to trigger GPIO interrupts from the software by configuring a pin as both output and input. Signed-off-by: Fabien Chouteau <chouteau@adacore.com> Reviewed-by: Palmer Dabbelt <palmer@sifive.com> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
This commit is contained in:
parent
a7b21f6762
commit
30efbf330a
7 changed files with 501 additions and 4 deletions
|
@ -146,11 +146,15 @@ static void riscv_sifive_e_soc_init(Object *obj)
|
|||
&error_abort);
|
||||
object_property_set_int(OBJECT(&s->cpus), smp_cpus, "num-harts",
|
||||
&error_abort);
|
||||
sysbus_init_child_obj(obj, "riscv.sifive.e.gpio0",
|
||||
&s->gpio, sizeof(s->gpio),
|
||||
TYPE_SIFIVE_GPIO);
|
||||
}
|
||||
|
||||
static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
const struct MemmapEntry *memmap = sifive_e_memmap;
|
||||
Error *err = NULL;
|
||||
|
||||
SiFiveESoCState *s = RISCV_E_SOC(dev);
|
||||
MemoryRegion *sys_mem = get_system_memory();
|
||||
|
@ -184,8 +188,28 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp)
|
|||
sifive_mmio_emulate(sys_mem, "riscv.sifive.e.aon",
|
||||
memmap[SIFIVE_E_AON].base, memmap[SIFIVE_E_AON].size);
|
||||
sifive_prci_create(memmap[SIFIVE_E_PRCI].base);
|
||||
sifive_mmio_emulate(sys_mem, "riscv.sifive.e.gpio0",
|
||||
memmap[SIFIVE_E_GPIO0].base, memmap[SIFIVE_E_GPIO0].size);
|
||||
|
||||
/* GPIO */
|
||||
|
||||
object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Map GPIO registers */
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, memmap[SIFIVE_E_GPIO0].base);
|
||||
|
||||
/* Pass all GPIOs to the SOC layer so they are available to the board */
|
||||
qdev_pass_gpios(DEVICE(&s->gpio), dev, NULL);
|
||||
|
||||
/* Connect GPIO interrupts to the PLIC */
|
||||
for (int i = 0; i < 32; i++) {
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), i,
|
||||
qdev_get_gpio_in(DEVICE(s->plic),
|
||||
SIFIVE_E_GPIO0_IRQ0 + i));
|
||||
}
|
||||
|
||||
sifive_uart_create(sys_mem, memmap[SIFIVE_E_UART0].base,
|
||||
serial_hd(0), qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_E_UART0_IRQ));
|
||||
sifive_mmio_emulate(sys_mem, "riscv.sifive.e.qspi0",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue