Skip to content

Commit

Permalink
hw/riscv/sifive_u: Connect the Cadence GEM Ethernet device
Browse files Browse the repository at this point in the history
Connect the Cadence GEM ethernet device. This also requires us to
expose the plic interrupt lines.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Michael Clark <mjc@sifive.com>
  • Loading branch information
alistair23 committed Jul 5, 2018
1 parent bde3ab9 commit 5a7f76a
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 2 deletions.
2 changes: 2 additions & 0 deletions default-configs/riscv32-softmmu.mak
Expand Up @@ -3,3 +3,5 @@
CONFIG_SERIAL=y
CONFIG_VIRTIO_MMIO=y
include virtio.mak

CONFIG_CADENCE=y
2 changes: 2 additions & 0 deletions default-configs/riscv64-softmmu.mak
Expand Up @@ -3,3 +3,5 @@
CONFIG_SERIAL=y
CONFIG_VIRTIO_MMIO=y
include virtio.mak

CONFIG_CADENCE=y
50 changes: 50 additions & 0 deletions hw/riscv/sifive_u.c
Expand Up @@ -60,8 +60,11 @@ static const struct MemmapEntry {
[SIFIVE_U_UART0] = { 0x10013000, 0x1000 },
[SIFIVE_U_UART1] = { 0x10023000, 0x1000 },
[SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
[SIFIVE_U_GEM] = { 0x100900FC, 0x2000 },
};

#define GEM_REVISION 0x10070109

static uint64_t load_kernel(const char *kernel_filename)
{
uint64_t kernel_entry, kernel_high;
Expand Down Expand Up @@ -194,6 +197,27 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
g_free(cells);
g_free(nodename);

nodename = g_strdup_printf("/soc/ethernet@%lx",
(long)memmap[SIFIVE_U_GEM].base);
qemu_fdt_add_subnode(fdt, nodename);
qemu_fdt_setprop_string(fdt, nodename, "compatible", "cdns,macb");
qemu_fdt_setprop_cells(fdt, nodename, "reg",
0x0, memmap[SIFIVE_U_GEM].base,
0x0, memmap[SIFIVE_U_GEM].size);
qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
qemu_fdt_setprop_string(fdt, nodename, "phy-mode", "gmii");
qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
qemu_fdt_setprop_cells(fdt, nodename, "interrupts", SIFIVE_U_GEM_IRQ);
qemu_fdt_setprop_cells(fdt, nodename, "#address-cells", 1);
qemu_fdt_setprop_cells(fdt, nodename, "#size-cells", 0);
g_free(nodename);

nodename = g_strdup_printf("/soc/ethernet@%lx/ethernet-phy@0",
(long)memmap[SIFIVE_U_GEM].base);
qemu_fdt_add_subnode(fdt, nodename);
qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x0);
g_free(nodename);

nodename = g_strdup_printf("/soc/uart@%lx",
(long)memmap[SIFIVE_U_UART0].base);
qemu_fdt_add_subnode(fdt, nodename);
Expand Down Expand Up @@ -286,6 +310,9 @@ static void riscv_sifive_u_soc_init(Object *obj)
&error_abort);
object_property_set_int(OBJECT(&s->cpus), smp_cpus, "num-harts",
&error_abort);

object_initialize(&s->gem, sizeof(s->gem), TYPE_CADENCE_GEM);
qdev_set_parent_bus(DEVICE(&s->gem), sysbus_get_default());
}

static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
Expand All @@ -294,6 +321,10 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
const struct MemmapEntry *memmap = sifive_u_memmap;
MemoryRegion *system_memory = get_system_memory();
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
qemu_irq plic_gpios[SIFIVE_U_PLIC_NUM_SOURCES];
int i;
Error *err = NULL;
NICInfo *nd = &nd_table[0];

object_property_set_bool(OBJECT(&s->cpus), true, "realized",
&error_abort);
Expand Down Expand Up @@ -324,6 +355,25 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
sifive_clint_create(memmap[SIFIVE_U_CLINT].base,
memmap[SIFIVE_U_CLINT].size, smp_cpus,
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);

for (i = 0; i < SIFIVE_U_PLIC_NUM_SOURCES; i++) {
plic_gpios[i] = qdev_get_gpio_in(DEVICE(s->plic), i);
}

if (nd->used) {
qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
qdev_set_nic_properties(DEVICE(&s->gem), nd);
}
object_property_set_int(OBJECT(&s->gem), GEM_REVISION, "revision",
&error_abort);
object_property_set_bool(OBJECT(&s->gem), true, "realized", &err);
if (err) {
error_propagate(errp, err);
return;
}
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gem), 0, memmap[SIFIVE_U_GEM].base);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gem), 0,
plic_gpios[SIFIVE_U_GEM_IRQ]);
}

static void riscv_sifive_u_machine_init(MachineClass *mc)
Expand Down
9 changes: 7 additions & 2 deletions include/hw/riscv/sifive_u.h
Expand Up @@ -19,6 +19,8 @@
#ifndef HW_SIFIVE_U_H
#define HW_SIFIVE_U_H

#include "hw/net/cadence_gem.h"

#define TYPE_RISCV_U_SOC "riscv.sifive.u.soc"
#define RISCV_U_SOC(obj) \
OBJECT_CHECK(SiFiveUSoCState, (obj), TYPE_RISCV_U_SOC)
Expand All @@ -30,6 +32,7 @@ typedef struct SiFiveUSoCState {
/*< public >*/
RISCVHartArrayState cpus;
DeviceState *plic;
CadenceGEMState gem;
} SiFiveUSoCState;

typedef struct SiFiveUState {
Expand All @@ -49,12 +52,14 @@ enum {
SIFIVE_U_PLIC,
SIFIVE_U_UART0,
SIFIVE_U_UART1,
SIFIVE_U_DRAM
SIFIVE_U_DRAM,
SIFIVE_U_GEM
};

enum {
SIFIVE_U_UART0_IRQ = 3,
SIFIVE_U_UART1_IRQ = 4
SIFIVE_U_UART1_IRQ = 4,
SIFIVE_U_GEM_IRQ = 0x35
};

enum {
Expand Down

0 comments on commit 5a7f76a

Please sign in to comment.