Skip to content

Commit

Permalink
SiFive RISC-V GPIO Device
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Fabien-Chouteau authored and palmer-dabbelt committed May 24, 2019
1 parent a7b21f6 commit 30efbf3
Show file tree
Hide file tree
Showing 7 changed files with 501 additions and 4 deletions.
1 change: 1 addition & 0 deletions Makefile.objs
Expand Up @@ -182,6 +182,7 @@ trace-events-subdirs += hw/virtio
trace-events-subdirs += hw/watchdog
trace-events-subdirs += hw/xen
trace-events-subdirs += hw/gpio
trace-events-subdirs += hw/riscv
trace-events-subdirs += migration
trace-events-subdirs += net
trace-events-subdirs += ui
Expand Down
1 change: 1 addition & 0 deletions hw/riscv/Makefile.objs
Expand Up @@ -2,6 +2,7 @@ obj-$(CONFIG_SPIKE) += riscv_htif.o
obj-$(CONFIG_HART) += riscv_hart.o
obj-$(CONFIG_SIFIVE_E) += sifive_e.o
obj-$(CONFIG_SIFIVE) += sifive_clint.o
obj-$(CONFIG_SIFIVE) += sifive_gpio.o
obj-$(CONFIG_SIFIVE) += sifive_prci.o
obj-$(CONFIG_SIFIVE) += sifive_plic.o
obj-$(CONFIG_SIFIVE) += sifive_test.o
Expand Down
28 changes: 26 additions & 2 deletions hw/riscv/sifive_e.c
Expand Up @@ -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();
Expand Down Expand Up @@ -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",
Expand Down

0 comments on commit 30efbf3

Please sign in to comment.