cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

sifive_u.c (42996B)


      1/*
      2 * QEMU RISC-V Board Compatible with SiFive Freedom U SDK
      3 *
      4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
      5 * Copyright (c) 2017 SiFive, Inc.
      6 * Copyright (c) 2019 Bin Meng <bmeng.cn@gmail.com>
      7 *
      8 * Provides a board compatible with the SiFive Freedom U SDK:
      9 *
     10 * 0) UART
     11 * 1) CLINT (Core Level Interruptor)
     12 * 2) PLIC (Platform Level Interrupt Controller)
     13 * 3) PRCI (Power, Reset, Clock, Interrupt)
     14 * 4) GPIO (General Purpose Input/Output Controller)
     15 * 5) OTP (One-Time Programmable) memory with stored serial number
     16 * 6) GEM (Gigabit Ethernet Controller) and management block
     17 * 7) DMA (Direct Memory Access Controller)
     18 * 8) SPI0 connected to an SPI flash
     19 * 9) SPI2 connected to an SD card
     20 * 10) PWM0 and PWM1
     21 *
     22 * This board currently generates devicetree dynamically that indicates at least
     23 * two harts and up to five harts.
     24 *
     25 * This program is free software; you can redistribute it and/or modify it
     26 * under the terms and conditions of the GNU General Public License,
     27 * version 2 or later, as published by the Free Software Foundation.
     28 *
     29 * This program is distributed in the hope it will be useful, but WITHOUT
     30 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     31 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
     32 * more details.
     33 *
     34 * You should have received a copy of the GNU General Public License along with
     35 * this program.  If not, see <http://www.gnu.org/licenses/>.
     36 */
     37
     38#include "qemu/osdep.h"
     39#include "qemu/error-report.h"
     40#include "qapi/error.h"
     41#include "qapi/visitor.h"
     42#include "hw/boards.h"
     43#include "hw/irq.h"
     44#include "hw/loader.h"
     45#include "hw/sysbus.h"
     46#include "hw/char/serial.h"
     47#include "hw/cpu/cluster.h"
     48#include "hw/misc/unimp.h"
     49#include "hw/ssi/ssi.h"
     50#include "target/riscv/cpu.h"
     51#include "hw/riscv/riscv_hart.h"
     52#include "hw/riscv/sifive_u.h"
     53#include "hw/riscv/boot.h"
     54#include "hw/char/sifive_uart.h"
     55#include "hw/intc/riscv_aclint.h"
     56#include "hw/intc/sifive_plic.h"
     57#include "chardev/char.h"
     58#include "net/eth.h"
     59#include "sysemu/device_tree.h"
     60#include "sysemu/runstate.h"
     61#include "sysemu/sysemu.h"
     62
     63#include <libfdt.h>
     64
     65/* CLINT timebase frequency */
     66#define CLINT_TIMEBASE_FREQ 1000000
     67
     68static const MemMapEntry sifive_u_memmap[] = {
     69    [SIFIVE_U_DEV_DEBUG] =    {        0x0,      0x100 },
     70    [SIFIVE_U_DEV_MROM] =     {     0x1000,     0xf000 },
     71    [SIFIVE_U_DEV_CLINT] =    {  0x2000000,    0x10000 },
     72    [SIFIVE_U_DEV_L2CC] =     {  0x2010000,     0x1000 },
     73    [SIFIVE_U_DEV_PDMA] =     {  0x3000000,   0x100000 },
     74    [SIFIVE_U_DEV_L2LIM] =    {  0x8000000,  0x2000000 },
     75    [SIFIVE_U_DEV_PLIC] =     {  0xc000000,  0x4000000 },
     76    [SIFIVE_U_DEV_PRCI] =     { 0x10000000,     0x1000 },
     77    [SIFIVE_U_DEV_UART0] =    { 0x10010000,     0x1000 },
     78    [SIFIVE_U_DEV_UART1] =    { 0x10011000,     0x1000 },
     79    [SIFIVE_U_DEV_PWM0] =     { 0x10020000,     0x1000 },
     80    [SIFIVE_U_DEV_PWM1] =     { 0x10021000,     0x1000 },
     81    [SIFIVE_U_DEV_QSPI0] =    { 0x10040000,     0x1000 },
     82    [SIFIVE_U_DEV_QSPI2] =    { 0x10050000,     0x1000 },
     83    [SIFIVE_U_DEV_GPIO] =     { 0x10060000,     0x1000 },
     84    [SIFIVE_U_DEV_OTP] =      { 0x10070000,     0x1000 },
     85    [SIFIVE_U_DEV_GEM] =      { 0x10090000,     0x2000 },
     86    [SIFIVE_U_DEV_GEM_MGMT] = { 0x100a0000,     0x1000 },
     87    [SIFIVE_U_DEV_DMC] =      { 0x100b0000,    0x10000 },
     88    [SIFIVE_U_DEV_FLASH0] =   { 0x20000000, 0x10000000 },
     89    [SIFIVE_U_DEV_DRAM] =     { 0x80000000,        0x0 },
     90};
     91
     92#define OTP_SERIAL          1
     93#define GEM_REVISION        0x10070109
     94
     95static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
     96                       uint64_t mem_size, const char *cmdline, bool is_32_bit)
     97{
     98    MachineState *ms = MACHINE(qdev_get_machine());
     99    void *fdt;
    100    int cpu;
    101    uint32_t *cells;
    102    char *nodename;
    103    uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1;
    104    uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
    105    static const char * const ethclk_names[2] = { "pclk", "hclk" };
    106    static const char * const clint_compat[2] = {
    107        "sifive,clint0", "riscv,clint0"
    108    };
    109    static const char * const plic_compat[2] = {
    110        "sifive,plic-1.0.0", "riscv,plic0"
    111    };
    112
    113    if (ms->dtb) {
    114        fdt = s->fdt = load_device_tree(ms->dtb, &s->fdt_size);
    115        if (!fdt) {
    116            error_report("load_device_tree() failed");
    117            exit(1);
    118        }
    119        goto update_bootargs;
    120    } else {
    121        fdt = s->fdt = create_device_tree(&s->fdt_size);
    122        if (!fdt) {
    123            error_report("create_device_tree() failed");
    124            exit(1);
    125        }
    126    }
    127
    128    qemu_fdt_setprop_string(fdt, "/", "model", "SiFive HiFive Unleashed A00");
    129    qemu_fdt_setprop_string(fdt, "/", "compatible",
    130                            "sifive,hifive-unleashed-a00");
    131    qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
    132    qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
    133
    134    qemu_fdt_add_subnode(fdt, "/soc");
    135    qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0);
    136    qemu_fdt_setprop_string(fdt, "/soc", "compatible", "simple-bus");
    137    qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2);
    138    qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2);
    139
    140    hfclk_phandle = phandle++;
    141    nodename = g_strdup_printf("/hfclk");
    142    qemu_fdt_add_subnode(fdt, nodename);
    143    qemu_fdt_setprop_cell(fdt, nodename, "phandle", hfclk_phandle);
    144    qemu_fdt_setprop_string(fdt, nodename, "clock-output-names", "hfclk");
    145    qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
    146        SIFIVE_U_HFCLK_FREQ);
    147    qemu_fdt_setprop_string(fdt, nodename, "compatible", "fixed-clock");
    148    qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
    149    g_free(nodename);
    150
    151    rtcclk_phandle = phandle++;
    152    nodename = g_strdup_printf("/rtcclk");
    153    qemu_fdt_add_subnode(fdt, nodename);
    154    qemu_fdt_setprop_cell(fdt, nodename, "phandle", rtcclk_phandle);
    155    qemu_fdt_setprop_string(fdt, nodename, "clock-output-names", "rtcclk");
    156    qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
    157        SIFIVE_U_RTCCLK_FREQ);
    158    qemu_fdt_setprop_string(fdt, nodename, "compatible", "fixed-clock");
    159    qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
    160    g_free(nodename);
    161
    162    nodename = g_strdup_printf("/memory@%lx",
    163        (long)memmap[SIFIVE_U_DEV_DRAM].base);
    164    qemu_fdt_add_subnode(fdt, nodename);
    165    qemu_fdt_setprop_cells(fdt, nodename, "reg",
    166        memmap[SIFIVE_U_DEV_DRAM].base >> 32, memmap[SIFIVE_U_DEV_DRAM].base,
    167        mem_size >> 32, mem_size);
    168    qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
    169    g_free(nodename);
    170
    171    qemu_fdt_add_subnode(fdt, "/cpus");
    172    qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency",
    173        CLINT_TIMEBASE_FREQ);
    174    qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
    175    qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
    176
    177    for (cpu = ms->smp.cpus - 1; cpu >= 0; cpu--) {
    178        int cpu_phandle = phandle++;
    179        nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
    180        char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
    181        char *isa;
    182        qemu_fdt_add_subnode(fdt, nodename);
    183        /* cpu 0 is the management hart that does not have mmu */
    184        if (cpu != 0) {
    185            if (is_32_bit) {
    186                qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv32");
    187            } else {
    188                qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
    189            }
    190            isa = riscv_isa_string(&s->soc.u_cpus.harts[cpu - 1]);
    191        } else {
    192            isa = riscv_isa_string(&s->soc.e_cpus.harts[0]);
    193        }
    194        qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa);
    195        qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv");
    196        qemu_fdt_setprop_string(fdt, nodename, "status", "okay");
    197        qemu_fdt_setprop_cell(fdt, nodename, "reg", cpu);
    198        qemu_fdt_setprop_string(fdt, nodename, "device_type", "cpu");
    199        qemu_fdt_add_subnode(fdt, intc);
    200        qemu_fdt_setprop_cell(fdt, intc, "phandle", cpu_phandle);
    201        qemu_fdt_setprop_string(fdt, intc, "compatible", "riscv,cpu-intc");
    202        qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
    203        qemu_fdt_setprop_cell(fdt, intc, "#interrupt-cells", 1);
    204        g_free(isa);
    205        g_free(intc);
    206        g_free(nodename);
    207    }
    208
    209    cells =  g_new0(uint32_t, ms->smp.cpus * 4);
    210    for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
    211        nodename =
    212            g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
    213        uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
    214        cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle);
    215        cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
    216        cells[cpu * 4 + 2] = cpu_to_be32(intc_phandle);
    217        cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
    218        g_free(nodename);
    219    }
    220    nodename = g_strdup_printf("/soc/clint@%lx",
    221        (long)memmap[SIFIVE_U_DEV_CLINT].base);
    222    qemu_fdt_add_subnode(fdt, nodename);
    223    qemu_fdt_setprop_string_array(fdt, nodename, "compatible",
    224        (char **)&clint_compat, ARRAY_SIZE(clint_compat));
    225    qemu_fdt_setprop_cells(fdt, nodename, "reg",
    226        0x0, memmap[SIFIVE_U_DEV_CLINT].base,
    227        0x0, memmap[SIFIVE_U_DEV_CLINT].size);
    228    qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
    229        cells, ms->smp.cpus * sizeof(uint32_t) * 4);
    230    g_free(cells);
    231    g_free(nodename);
    232
    233    nodename = g_strdup_printf("/soc/otp@%lx",
    234        (long)memmap[SIFIVE_U_DEV_OTP].base);
    235    qemu_fdt_add_subnode(fdt, nodename);
    236    qemu_fdt_setprop_cell(fdt, nodename, "fuse-count", SIFIVE_U_OTP_REG_SIZE);
    237    qemu_fdt_setprop_cells(fdt, nodename, "reg",
    238        0x0, memmap[SIFIVE_U_DEV_OTP].base,
    239        0x0, memmap[SIFIVE_U_DEV_OTP].size);
    240    qemu_fdt_setprop_string(fdt, nodename, "compatible",
    241        "sifive,fu540-c000-otp");
    242    g_free(nodename);
    243
    244    prci_phandle = phandle++;
    245    nodename = g_strdup_printf("/soc/clock-controller@%lx",
    246        (long)memmap[SIFIVE_U_DEV_PRCI].base);
    247    qemu_fdt_add_subnode(fdt, nodename);
    248    qemu_fdt_setprop_cell(fdt, nodename, "phandle", prci_phandle);
    249    qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x1);
    250    qemu_fdt_setprop_cells(fdt, nodename, "clocks",
    251        hfclk_phandle, rtcclk_phandle);
    252    qemu_fdt_setprop_cells(fdt, nodename, "reg",
    253        0x0, memmap[SIFIVE_U_DEV_PRCI].base,
    254        0x0, memmap[SIFIVE_U_DEV_PRCI].size);
    255    qemu_fdt_setprop_string(fdt, nodename, "compatible",
    256        "sifive,fu540-c000-prci");
    257    g_free(nodename);
    258
    259    plic_phandle = phandle++;
    260    cells =  g_new0(uint32_t, ms->smp.cpus * 4 - 2);
    261    for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
    262        nodename =
    263            g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
    264        uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
    265        /* cpu 0 is the management hart that does not have S-mode */
    266        if (cpu == 0) {
    267            cells[0] = cpu_to_be32(intc_phandle);
    268            cells[1] = cpu_to_be32(IRQ_M_EXT);
    269        } else {
    270            cells[cpu * 4 - 2] = cpu_to_be32(intc_phandle);
    271            cells[cpu * 4 - 1] = cpu_to_be32(IRQ_M_EXT);
    272            cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle);
    273            cells[cpu * 4 + 1] = cpu_to_be32(IRQ_S_EXT);
    274        }
    275        g_free(nodename);
    276    }
    277    nodename = g_strdup_printf("/soc/interrupt-controller@%lx",
    278        (long)memmap[SIFIVE_U_DEV_PLIC].base);
    279    qemu_fdt_add_subnode(fdt, nodename);
    280    qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 1);
    281    qemu_fdt_setprop_string_array(fdt, nodename, "compatible",
    282        (char **)&plic_compat, ARRAY_SIZE(plic_compat));
    283    qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
    284    qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
    285        cells, (ms->smp.cpus * 4 - 2) * sizeof(uint32_t));
    286    qemu_fdt_setprop_cells(fdt, nodename, "reg",
    287        0x0, memmap[SIFIVE_U_DEV_PLIC].base,
    288        0x0, memmap[SIFIVE_U_DEV_PLIC].size);
    289    qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
    290    qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
    291    plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
    292    g_free(cells);
    293    g_free(nodename);
    294
    295    gpio_phandle = phandle++;
    296    nodename = g_strdup_printf("/soc/gpio@%lx",
    297        (long)memmap[SIFIVE_U_DEV_GPIO].base);
    298    qemu_fdt_add_subnode(fdt, nodename);
    299    qemu_fdt_setprop_cell(fdt, nodename, "phandle", gpio_phandle);
    300    qemu_fdt_setprop_cells(fdt, nodename, "clocks",
    301        prci_phandle, PRCI_CLK_TLCLK);
    302    qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 2);
    303    qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
    304    qemu_fdt_setprop_cell(fdt, nodename, "#gpio-cells", 2);
    305    qemu_fdt_setprop(fdt, nodename, "gpio-controller", NULL, 0);
    306    qemu_fdt_setprop_cells(fdt, nodename, "reg",
    307        0x0, memmap[SIFIVE_U_DEV_GPIO].base,
    308        0x0, memmap[SIFIVE_U_DEV_GPIO].size);
    309    qemu_fdt_setprop_cells(fdt, nodename, "interrupts", SIFIVE_U_GPIO_IRQ0,
    310        SIFIVE_U_GPIO_IRQ1, SIFIVE_U_GPIO_IRQ2, SIFIVE_U_GPIO_IRQ3,
    311        SIFIVE_U_GPIO_IRQ4, SIFIVE_U_GPIO_IRQ5, SIFIVE_U_GPIO_IRQ6,
    312        SIFIVE_U_GPIO_IRQ7, SIFIVE_U_GPIO_IRQ8, SIFIVE_U_GPIO_IRQ9,
    313        SIFIVE_U_GPIO_IRQ10, SIFIVE_U_GPIO_IRQ11, SIFIVE_U_GPIO_IRQ12,
    314        SIFIVE_U_GPIO_IRQ13, SIFIVE_U_GPIO_IRQ14, SIFIVE_U_GPIO_IRQ15);
    315    qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
    316    qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,gpio0");
    317    g_free(nodename);
    318
    319    nodename = g_strdup_printf("/gpio-restart");
    320    qemu_fdt_add_subnode(fdt, nodename);
    321    qemu_fdt_setprop_cells(fdt, nodename, "gpios", gpio_phandle, 10, 1);
    322    qemu_fdt_setprop_string(fdt, nodename, "compatible", "gpio-restart");
    323    g_free(nodename);
    324
    325    nodename = g_strdup_printf("/soc/dma@%lx",
    326        (long)memmap[SIFIVE_U_DEV_PDMA].base);
    327    qemu_fdt_add_subnode(fdt, nodename);
    328    qemu_fdt_setprop_cell(fdt, nodename, "#dma-cells", 1);
    329    qemu_fdt_setprop_cells(fdt, nodename, "interrupts",
    330        SIFIVE_U_PDMA_IRQ0, SIFIVE_U_PDMA_IRQ1, SIFIVE_U_PDMA_IRQ2,
    331        SIFIVE_U_PDMA_IRQ3, SIFIVE_U_PDMA_IRQ4, SIFIVE_U_PDMA_IRQ5,
    332        SIFIVE_U_PDMA_IRQ6, SIFIVE_U_PDMA_IRQ7);
    333    qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
    334    qemu_fdt_setprop_cells(fdt, nodename, "reg",
    335        0x0, memmap[SIFIVE_U_DEV_PDMA].base,
    336        0x0, memmap[SIFIVE_U_DEV_PDMA].size);
    337    qemu_fdt_setprop_string(fdt, nodename, "compatible",
    338                            "sifive,fu540-c000-pdma");
    339    g_free(nodename);
    340
    341    nodename = g_strdup_printf("/soc/cache-controller@%lx",
    342        (long)memmap[SIFIVE_U_DEV_L2CC].base);
    343    qemu_fdt_add_subnode(fdt, nodename);
    344    qemu_fdt_setprop_cells(fdt, nodename, "reg",
    345        0x0, memmap[SIFIVE_U_DEV_L2CC].base,
    346        0x0, memmap[SIFIVE_U_DEV_L2CC].size);
    347    qemu_fdt_setprop_cells(fdt, nodename, "interrupts",
    348        SIFIVE_U_L2CC_IRQ0, SIFIVE_U_L2CC_IRQ1, SIFIVE_U_L2CC_IRQ2);
    349    qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
    350    qemu_fdt_setprop(fdt, nodename, "cache-unified", NULL, 0);
    351    qemu_fdt_setprop_cell(fdt, nodename, "cache-size", 2097152);
    352    qemu_fdt_setprop_cell(fdt, nodename, "cache-sets", 1024);
    353    qemu_fdt_setprop_cell(fdt, nodename, "cache-level", 2);
    354    qemu_fdt_setprop_cell(fdt, nodename, "cache-block-size", 64);
    355    qemu_fdt_setprop_string(fdt, nodename, "compatible",
    356                            "sifive,fu540-c000-ccache");
    357    g_free(nodename);
    358
    359    nodename = g_strdup_printf("/soc/spi@%lx",
    360        (long)memmap[SIFIVE_U_DEV_QSPI2].base);
    361    qemu_fdt_add_subnode(fdt, nodename);
    362    qemu_fdt_setprop_cell(fdt, nodename, "#size-cells", 0);
    363    qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
    364    qemu_fdt_setprop_cells(fdt, nodename, "clocks",
    365        prci_phandle, PRCI_CLK_TLCLK);
    366    qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_QSPI2_IRQ);
    367    qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
    368    qemu_fdt_setprop_cells(fdt, nodename, "reg",
    369        0x0, memmap[SIFIVE_U_DEV_QSPI2].base,
    370        0x0, memmap[SIFIVE_U_DEV_QSPI2].size);
    371    qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,spi0");
    372    g_free(nodename);
    373
    374    nodename = g_strdup_printf("/soc/spi@%lx/mmc@0",
    375        (long)memmap[SIFIVE_U_DEV_QSPI2].base);
    376    qemu_fdt_add_subnode(fdt, nodename);
    377    qemu_fdt_setprop(fdt, nodename, "disable-wp", NULL, 0);
    378    qemu_fdt_setprop_cells(fdt, nodename, "voltage-ranges", 3300, 3300);
    379    qemu_fdt_setprop_cell(fdt, nodename, "spi-max-frequency", 20000000);
    380    qemu_fdt_setprop_cell(fdt, nodename, "reg", 0);
    381    qemu_fdt_setprop_string(fdt, nodename, "compatible", "mmc-spi-slot");
    382    g_free(nodename);
    383
    384    nodename = g_strdup_printf("/soc/spi@%lx",
    385        (long)memmap[SIFIVE_U_DEV_QSPI0].base);
    386    qemu_fdt_add_subnode(fdt, nodename);
    387    qemu_fdt_setprop_cell(fdt, nodename, "#size-cells", 0);
    388    qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
    389    qemu_fdt_setprop_cells(fdt, nodename, "clocks",
    390        prci_phandle, PRCI_CLK_TLCLK);
    391    qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_QSPI0_IRQ);
    392    qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
    393    qemu_fdt_setprop_cells(fdt, nodename, "reg",
    394        0x0, memmap[SIFIVE_U_DEV_QSPI0].base,
    395        0x0, memmap[SIFIVE_U_DEV_QSPI0].size);
    396    qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,spi0");
    397    g_free(nodename);
    398
    399    nodename = g_strdup_printf("/soc/spi@%lx/flash@0",
    400        (long)memmap[SIFIVE_U_DEV_QSPI0].base);
    401    qemu_fdt_add_subnode(fdt, nodename);
    402    qemu_fdt_setprop_cell(fdt, nodename, "spi-rx-bus-width", 4);
    403    qemu_fdt_setprop_cell(fdt, nodename, "spi-tx-bus-width", 4);
    404    qemu_fdt_setprop(fdt, nodename, "m25p,fast-read", NULL, 0);
    405    qemu_fdt_setprop_cell(fdt, nodename, "spi-max-frequency", 50000000);
    406    qemu_fdt_setprop_cell(fdt, nodename, "reg", 0);
    407    qemu_fdt_setprop_string(fdt, nodename, "compatible", "jedec,spi-nor");
    408    g_free(nodename);
    409
    410    phy_phandle = phandle++;
    411    nodename = g_strdup_printf("/soc/ethernet@%lx",
    412        (long)memmap[SIFIVE_U_DEV_GEM].base);
    413    qemu_fdt_add_subnode(fdt, nodename);
    414    qemu_fdt_setprop_string(fdt, nodename, "compatible",
    415        "sifive,fu540-c000-gem");
    416    qemu_fdt_setprop_cells(fdt, nodename, "reg",
    417        0x0, memmap[SIFIVE_U_DEV_GEM].base,
    418        0x0, memmap[SIFIVE_U_DEV_GEM].size,
    419        0x0, memmap[SIFIVE_U_DEV_GEM_MGMT].base,
    420        0x0, memmap[SIFIVE_U_DEV_GEM_MGMT].size);
    421    qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
    422    qemu_fdt_setprop_string(fdt, nodename, "phy-mode", "gmii");
    423    qemu_fdt_setprop_cell(fdt, nodename, "phy-handle", phy_phandle);
    424    qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
    425    qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_GEM_IRQ);
    426    qemu_fdt_setprop_cells(fdt, nodename, "clocks",
    427        prci_phandle, PRCI_CLK_GEMGXLPLL, prci_phandle, PRCI_CLK_GEMGXLPLL);
    428    qemu_fdt_setprop_string_array(fdt, nodename, "clock-names",
    429        (char **)&ethclk_names, ARRAY_SIZE(ethclk_names));
    430    qemu_fdt_setprop(fdt, nodename, "local-mac-address",
    431        s->soc.gem.conf.macaddr.a, ETH_ALEN);
    432    qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
    433    qemu_fdt_setprop_cell(fdt, nodename, "#size-cells", 0);
    434
    435    qemu_fdt_add_subnode(fdt, "/aliases");
    436    qemu_fdt_setprop_string(fdt, "/aliases", "ethernet0", nodename);
    437
    438    g_free(nodename);
    439
    440    nodename = g_strdup_printf("/soc/ethernet@%lx/ethernet-phy@0",
    441        (long)memmap[SIFIVE_U_DEV_GEM].base);
    442    qemu_fdt_add_subnode(fdt, nodename);
    443    qemu_fdt_setprop_cell(fdt, nodename, "phandle", phy_phandle);
    444    qemu_fdt_setprop_cell(fdt, nodename, "reg", 0x0);
    445    g_free(nodename);
    446
    447    nodename = g_strdup_printf("/soc/pwm@%lx",
    448        (long)memmap[SIFIVE_U_DEV_PWM0].base);
    449    qemu_fdt_add_subnode(fdt, nodename);
    450    qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,pwm0");
    451    qemu_fdt_setprop_cells(fdt, nodename, "reg",
    452        0x0, memmap[SIFIVE_U_DEV_PWM0].base,
    453        0x0, memmap[SIFIVE_U_DEV_PWM0].size);
    454    qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
    455    qemu_fdt_setprop_cells(fdt, nodename, "interrupts",
    456                           SIFIVE_U_PWM0_IRQ0, SIFIVE_U_PWM0_IRQ1,
    457                           SIFIVE_U_PWM0_IRQ2, SIFIVE_U_PWM0_IRQ3);
    458    qemu_fdt_setprop_cells(fdt, nodename, "clocks",
    459                           prci_phandle, PRCI_CLK_TLCLK);
    460    qemu_fdt_setprop_cell(fdt, nodename, "#pwm-cells", 0);
    461    g_free(nodename);
    462
    463    nodename = g_strdup_printf("/soc/pwm@%lx",
    464        (long)memmap[SIFIVE_U_DEV_PWM1].base);
    465    qemu_fdt_add_subnode(fdt, nodename);
    466    qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,pwm0");
    467    qemu_fdt_setprop_cells(fdt, nodename, "reg",
    468        0x0, memmap[SIFIVE_U_DEV_PWM1].base,
    469        0x0, memmap[SIFIVE_U_DEV_PWM1].size);
    470    qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
    471    qemu_fdt_setprop_cells(fdt, nodename, "interrupts",
    472                           SIFIVE_U_PWM1_IRQ0, SIFIVE_U_PWM1_IRQ1,
    473                           SIFIVE_U_PWM1_IRQ2, SIFIVE_U_PWM1_IRQ3);
    474    qemu_fdt_setprop_cells(fdt, nodename, "clocks",
    475                           prci_phandle, PRCI_CLK_TLCLK);
    476    qemu_fdt_setprop_cell(fdt, nodename, "#pwm-cells", 0);
    477    g_free(nodename);
    478
    479    nodename = g_strdup_printf("/soc/serial@%lx",
    480        (long)memmap[SIFIVE_U_DEV_UART1].base);
    481    qemu_fdt_add_subnode(fdt, nodename);
    482    qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,uart0");
    483    qemu_fdt_setprop_cells(fdt, nodename, "reg",
    484        0x0, memmap[SIFIVE_U_DEV_UART1].base,
    485        0x0, memmap[SIFIVE_U_DEV_UART1].size);
    486    qemu_fdt_setprop_cells(fdt, nodename, "clocks",
    487        prci_phandle, PRCI_CLK_TLCLK);
    488    qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
    489    qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_UART1_IRQ);
    490
    491    qemu_fdt_setprop_string(fdt, "/aliases", "serial1", nodename);
    492    g_free(nodename);
    493
    494    nodename = g_strdup_printf("/soc/serial@%lx",
    495        (long)memmap[SIFIVE_U_DEV_UART0].base);
    496    qemu_fdt_add_subnode(fdt, nodename);
    497    qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,uart0");
    498    qemu_fdt_setprop_cells(fdt, nodename, "reg",
    499        0x0, memmap[SIFIVE_U_DEV_UART0].base,
    500        0x0, memmap[SIFIVE_U_DEV_UART0].size);
    501    qemu_fdt_setprop_cells(fdt, nodename, "clocks",
    502        prci_phandle, PRCI_CLK_TLCLK);
    503    qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
    504    qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_UART0_IRQ);
    505
    506    qemu_fdt_add_subnode(fdt, "/chosen");
    507    qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
    508    qemu_fdt_setprop_string(fdt, "/aliases", "serial0", nodename);
    509
    510    g_free(nodename);
    511
    512update_bootargs:
    513    if (cmdline) {
    514        qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
    515    }
    516}
    517
    518static void sifive_u_machine_reset(void *opaque, int n, int level)
    519{
    520    /* gpio pin active low triggers reset */
    521    if (!level) {
    522        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
    523    }
    524}
    525
    526static void sifive_u_machine_init(MachineState *machine)
    527{
    528    const MemMapEntry *memmap = sifive_u_memmap;
    529    SiFiveUState *s = RISCV_U_MACHINE(machine);
    530    MemoryRegion *system_memory = get_system_memory();
    531    MemoryRegion *main_mem = g_new(MemoryRegion, 1);
    532    MemoryRegion *flash0 = g_new(MemoryRegion, 1);
    533    target_ulong start_addr = memmap[SIFIVE_U_DEV_DRAM].base;
    534    target_ulong firmware_end_addr, kernel_start_addr;
    535    uint32_t start_addr_hi32 = 0x00000000;
    536    int i;
    537    uint32_t fdt_load_addr;
    538    uint64_t kernel_entry;
    539    DriveInfo *dinfo;
    540    DeviceState *flash_dev, *sd_dev;
    541    qemu_irq flash_cs, sd_cs;
    542
    543    /* Initialize SoC */
    544    object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_U_SOC);
    545    object_property_set_uint(OBJECT(&s->soc), "serial", s->serial,
    546                             &error_abort);
    547    object_property_set_str(OBJECT(&s->soc), "cpu-type", machine->cpu_type,
    548                             &error_abort);
    549    qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
    550
    551    /* register RAM */
    552    memory_region_init_ram(main_mem, NULL, "riscv.sifive.u.ram",
    553                           machine->ram_size, &error_fatal);
    554    memory_region_add_subregion(system_memory, memmap[SIFIVE_U_DEV_DRAM].base,
    555                                main_mem);
    556
    557    /* register QSPI0 Flash */
    558    memory_region_init_ram(flash0, NULL, "riscv.sifive.u.flash0",
    559                           memmap[SIFIVE_U_DEV_FLASH0].size, &error_fatal);
    560    memory_region_add_subregion(system_memory, memmap[SIFIVE_U_DEV_FLASH0].base,
    561                                flash0);
    562
    563    /* register gpio-restart */
    564    qdev_connect_gpio_out(DEVICE(&(s->soc.gpio)), 10,
    565                          qemu_allocate_irq(sifive_u_machine_reset, NULL, 0));
    566
    567    /* create device tree */
    568    create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
    569               riscv_is_32bit(&s->soc.u_cpus));
    570
    571    if (s->start_in_flash) {
    572        /*
    573         * If start_in_flash property is given, assign s->msel to a value
    574         * that representing booting from QSPI0 memory-mapped flash.
    575         *
    576         * This also means that when both start_in_flash and msel properties
    577         * are given, start_in_flash takes the precedence over msel.
    578         *
    579         * Note this is to keep backward compatibility not to break existing
    580         * users that use start_in_flash property.
    581         */
    582        s->msel = MSEL_MEMMAP_QSPI0_FLASH;
    583    }
    584
    585    switch (s->msel) {
    586    case MSEL_MEMMAP_QSPI0_FLASH:
    587        start_addr = memmap[SIFIVE_U_DEV_FLASH0].base;
    588        break;
    589    case MSEL_L2LIM_QSPI0_FLASH:
    590    case MSEL_L2LIM_QSPI2_SD:
    591        start_addr = memmap[SIFIVE_U_DEV_L2LIM].base;
    592        break;
    593    default:
    594        start_addr = memmap[SIFIVE_U_DEV_DRAM].base;
    595        break;
    596    }
    597
    598    if (riscv_is_32bit(&s->soc.u_cpus)) {
    599        firmware_end_addr = riscv_find_and_load_firmware(machine,
    600                                    RISCV32_BIOS_BIN, start_addr, NULL);
    601    } else {
    602        firmware_end_addr = riscv_find_and_load_firmware(machine,
    603                                    RISCV64_BIOS_BIN, start_addr, NULL);
    604    }
    605
    606    if (machine->kernel_filename) {
    607        kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc.u_cpus,
    608                                                         firmware_end_addr);
    609
    610        kernel_entry = riscv_load_kernel(machine->kernel_filename,
    611                                         kernel_start_addr, NULL);
    612
    613        if (machine->initrd_filename) {
    614            hwaddr start;
    615            hwaddr end = riscv_load_initrd(machine->initrd_filename,
    616                                           machine->ram_size, kernel_entry,
    617                                           &start);
    618            qemu_fdt_setprop_cell(s->fdt, "/chosen",
    619                                  "linux,initrd-start", start);
    620            qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
    621                                  end);
    622        }
    623    } else {
    624       /*
    625        * If dynamic firmware is used, it doesn't know where is the next mode
    626        * if kernel argument is not set.
    627        */
    628        kernel_entry = 0;
    629    }
    630
    631    /* Compute the fdt load address in dram */
    632    fdt_load_addr = riscv_load_fdt(memmap[SIFIVE_U_DEV_DRAM].base,
    633                                   machine->ram_size, s->fdt);
    634    if (!riscv_is_32bit(&s->soc.u_cpus)) {
    635        start_addr_hi32 = (uint64_t)start_addr >> 32;
    636    }
    637
    638    /* reset vector */
    639    uint32_t reset_vec[12] = {
    640        s->msel,                       /* MSEL pin state */
    641        0x00000297,                    /* 1:  auipc  t0, %pcrel_hi(fw_dyn) */
    642        0x02c28613,                    /*     addi   a2, t0, %pcrel_lo(1b) */
    643        0xf1402573,                    /*     csrr   a0, mhartid  */
    644        0,
    645        0,
    646        0x00028067,                    /*     jr     t0 */
    647        start_addr,                    /* start: .dword */
    648        start_addr_hi32,
    649        fdt_load_addr,                 /* fdt_laddr: .dword */
    650        0x00000000,
    651        0x00000000,
    652                                       /* fw_dyn: */
    653    };
    654    if (riscv_is_32bit(&s->soc.u_cpus)) {
    655        reset_vec[4] = 0x0202a583;     /*     lw     a1, 32(t0) */
    656        reset_vec[5] = 0x0182a283;     /*     lw     t0, 24(t0) */
    657    } else {
    658        reset_vec[4] = 0x0202b583;     /*     ld     a1, 32(t0) */
    659        reset_vec[5] = 0x0182b283;     /*     ld     t0, 24(t0) */
    660    }
    661
    662
    663    /* copy in the reset vector in little_endian byte order */
    664    for (i = 0; i < ARRAY_SIZE(reset_vec); i++) {
    665        reset_vec[i] = cpu_to_le32(reset_vec[i]);
    666    }
    667    rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
    668                          memmap[SIFIVE_U_DEV_MROM].base, &address_space_memory);
    669
    670    riscv_rom_copy_firmware_info(machine, memmap[SIFIVE_U_DEV_MROM].base,
    671                                 memmap[SIFIVE_U_DEV_MROM].size,
    672                                 sizeof(reset_vec), kernel_entry);
    673
    674    /* Connect an SPI flash to SPI0 */
    675    flash_dev = qdev_new("is25wp256");
    676    dinfo = drive_get_next(IF_MTD);
    677    if (dinfo) {
    678        qdev_prop_set_drive_err(flash_dev, "drive",
    679                                blk_by_legacy_dinfo(dinfo),
    680                                &error_fatal);
    681    }
    682    qdev_realize_and_unref(flash_dev, BUS(s->soc.spi0.spi), &error_fatal);
    683
    684    flash_cs = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
    685    sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.spi0), 1, flash_cs);
    686
    687    /* Connect an SD card to SPI2 */
    688    sd_dev = ssi_create_peripheral(s->soc.spi2.spi, "ssi-sd");
    689
    690    sd_cs = qdev_get_gpio_in_named(sd_dev, SSI_GPIO_CS, 0);
    691    sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.spi2), 1, sd_cs);
    692}
    693
    694static bool sifive_u_machine_get_start_in_flash(Object *obj, Error **errp)
    695{
    696    SiFiveUState *s = RISCV_U_MACHINE(obj);
    697
    698    return s->start_in_flash;
    699}
    700
    701static void sifive_u_machine_set_start_in_flash(Object *obj, bool value, Error **errp)
    702{
    703    SiFiveUState *s = RISCV_U_MACHINE(obj);
    704
    705    s->start_in_flash = value;
    706}
    707
    708static void sifive_u_machine_get_uint32_prop(Object *obj, Visitor *v,
    709                                             const char *name, void *opaque,
    710                                             Error **errp)
    711{
    712    visit_type_uint32(v, name, (uint32_t *)opaque, errp);
    713}
    714
    715static void sifive_u_machine_set_uint32_prop(Object *obj, Visitor *v,
    716                                             const char *name, void *opaque,
    717                                             Error **errp)
    718{
    719    visit_type_uint32(v, name, (uint32_t *)opaque, errp);
    720}
    721
    722static void sifive_u_machine_instance_init(Object *obj)
    723{
    724    SiFiveUState *s = RISCV_U_MACHINE(obj);
    725
    726    s->start_in_flash = false;
    727    s->msel = 0;
    728    object_property_add(obj, "msel", "uint32",
    729                        sifive_u_machine_get_uint32_prop,
    730                        sifive_u_machine_set_uint32_prop, NULL, &s->msel);
    731    object_property_set_description(obj, "msel",
    732                                    "Mode Select (MSEL[3:0]) pin state");
    733
    734    s->serial = OTP_SERIAL;
    735    object_property_add(obj, "serial", "uint32",
    736                        sifive_u_machine_get_uint32_prop,
    737                        sifive_u_machine_set_uint32_prop, NULL, &s->serial);
    738    object_property_set_description(obj, "serial", "Board serial number");
    739}
    740
    741static void sifive_u_machine_class_init(ObjectClass *oc, void *data)
    742{
    743    MachineClass *mc = MACHINE_CLASS(oc);
    744
    745    mc->desc = "RISC-V Board compatible with SiFive U SDK";
    746    mc->init = sifive_u_machine_init;
    747    mc->max_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + SIFIVE_U_COMPUTE_CPU_COUNT;
    748    mc->min_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 1;
    749    mc->default_cpu_type = SIFIVE_U_CPU;
    750    mc->default_cpus = mc->min_cpus;
    751
    752    object_class_property_add_bool(oc, "start-in-flash",
    753                                   sifive_u_machine_get_start_in_flash,
    754                                   sifive_u_machine_set_start_in_flash);
    755    object_class_property_set_description(oc, "start-in-flash",
    756                                          "Set on to tell QEMU's ROM to jump to "
    757                                          "flash. Otherwise QEMU will jump to DRAM "
    758                                          "or L2LIM depending on the msel value");
    759}
    760
    761static const TypeInfo sifive_u_machine_typeinfo = {
    762    .name       = MACHINE_TYPE_NAME("sifive_u"),
    763    .parent     = TYPE_MACHINE,
    764    .class_init = sifive_u_machine_class_init,
    765    .instance_init = sifive_u_machine_instance_init,
    766    .instance_size = sizeof(SiFiveUState),
    767};
    768
    769static void sifive_u_machine_init_register_types(void)
    770{
    771    type_register_static(&sifive_u_machine_typeinfo);
    772}
    773
    774type_init(sifive_u_machine_init_register_types)
    775
    776static void sifive_u_soc_instance_init(Object *obj)
    777{
    778    SiFiveUSoCState *s = RISCV_U_SOC(obj);
    779
    780    object_initialize_child(obj, "e-cluster", &s->e_cluster, TYPE_CPU_CLUSTER);
    781    qdev_prop_set_uint32(DEVICE(&s->e_cluster), "cluster-id", 0);
    782
    783    object_initialize_child(OBJECT(&s->e_cluster), "e-cpus", &s->e_cpus,
    784                            TYPE_RISCV_HART_ARRAY);
    785    qdev_prop_set_uint32(DEVICE(&s->e_cpus), "num-harts", 1);
    786    qdev_prop_set_uint32(DEVICE(&s->e_cpus), "hartid-base", 0);
    787    qdev_prop_set_string(DEVICE(&s->e_cpus), "cpu-type", SIFIVE_E_CPU);
    788    qdev_prop_set_uint64(DEVICE(&s->e_cpus), "resetvec", 0x1004);
    789
    790    object_initialize_child(obj, "u-cluster", &s->u_cluster, TYPE_CPU_CLUSTER);
    791    qdev_prop_set_uint32(DEVICE(&s->u_cluster), "cluster-id", 1);
    792
    793    object_initialize_child(OBJECT(&s->u_cluster), "u-cpus", &s->u_cpus,
    794                            TYPE_RISCV_HART_ARRAY);
    795
    796    object_initialize_child(obj, "prci", &s->prci, TYPE_SIFIVE_U_PRCI);
    797    object_initialize_child(obj, "otp", &s->otp, TYPE_SIFIVE_U_OTP);
    798    object_initialize_child(obj, "gem", &s->gem, TYPE_CADENCE_GEM);
    799    object_initialize_child(obj, "gpio", &s->gpio, TYPE_SIFIVE_GPIO);
    800    object_initialize_child(obj, "pdma", &s->dma, TYPE_SIFIVE_PDMA);
    801    object_initialize_child(obj, "spi0", &s->spi0, TYPE_SIFIVE_SPI);
    802    object_initialize_child(obj, "spi2", &s->spi2, TYPE_SIFIVE_SPI);
    803    object_initialize_child(obj, "pwm0", &s->pwm[0], TYPE_SIFIVE_PWM);
    804    object_initialize_child(obj, "pwm1", &s->pwm[1], TYPE_SIFIVE_PWM);
    805}
    806
    807static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
    808{
    809    MachineState *ms = MACHINE(qdev_get_machine());
    810    SiFiveUSoCState *s = RISCV_U_SOC(dev);
    811    const MemMapEntry *memmap = sifive_u_memmap;
    812    MemoryRegion *system_memory = get_system_memory();
    813    MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
    814    MemoryRegion *l2lim_mem = g_new(MemoryRegion, 1);
    815    char *plic_hart_config;
    816    size_t plic_hart_config_len;
    817    int i, j;
    818    NICInfo *nd = &nd_table[0];
    819
    820    qdev_prop_set_uint32(DEVICE(&s->u_cpus), "num-harts", ms->smp.cpus - 1);
    821    qdev_prop_set_uint32(DEVICE(&s->u_cpus), "hartid-base", 1);
    822    qdev_prop_set_string(DEVICE(&s->u_cpus), "cpu-type", s->cpu_type);
    823    qdev_prop_set_uint64(DEVICE(&s->u_cpus), "resetvec", 0x1004);
    824
    825    sysbus_realize(SYS_BUS_DEVICE(&s->e_cpus), &error_abort);
    826    sysbus_realize(SYS_BUS_DEVICE(&s->u_cpus), &error_abort);
    827    /*
    828     * The cluster must be realized after the RISC-V hart array container,
    829     * as the container's CPU object is only created on realize, and the
    830     * CPU must exist and have been parented into the cluster before the
    831     * cluster is realized.
    832     */
    833    qdev_realize(DEVICE(&s->e_cluster), NULL, &error_abort);
    834    qdev_realize(DEVICE(&s->u_cluster), NULL, &error_abort);
    835
    836    /* boot rom */
    837    memory_region_init_rom(mask_rom, OBJECT(dev), "riscv.sifive.u.mrom",
    838                           memmap[SIFIVE_U_DEV_MROM].size, &error_fatal);
    839    memory_region_add_subregion(system_memory, memmap[SIFIVE_U_DEV_MROM].base,
    840                                mask_rom);
    841
    842    /*
    843     * Add L2-LIM at reset size.
    844     * This should be reduced in size as the L2 Cache Controller WayEnable
    845     * register is incremented. Unfortunately I don't see a nice (or any) way
    846     * to handle reducing or blocking out the L2 LIM while still allowing it
    847     * be re returned to all enabled after a reset. For the time being, just
    848     * leave it enabled all the time. This won't break anything, but will be
    849     * too generous to misbehaving guests.
    850     */
    851    memory_region_init_ram(l2lim_mem, NULL, "riscv.sifive.u.l2lim",
    852                           memmap[SIFIVE_U_DEV_L2LIM].size, &error_fatal);
    853    memory_region_add_subregion(system_memory, memmap[SIFIVE_U_DEV_L2LIM].base,
    854                                l2lim_mem);
    855
    856    /* create PLIC hart topology configuration string */
    857    plic_hart_config_len = (strlen(SIFIVE_U_PLIC_HART_CONFIG) + 1) *
    858                           ms->smp.cpus;
    859    plic_hart_config = g_malloc0(plic_hart_config_len);
    860    for (i = 0; i < ms->smp.cpus; i++) {
    861        if (i != 0) {
    862            strncat(plic_hart_config, "," SIFIVE_U_PLIC_HART_CONFIG,
    863                    plic_hart_config_len);
    864        } else {
    865            strncat(plic_hart_config, "M", plic_hart_config_len);
    866        }
    867        plic_hart_config_len -= (strlen(SIFIVE_U_PLIC_HART_CONFIG) + 1);
    868    }
    869
    870    /* MMIO */
    871    s->plic = sifive_plic_create(memmap[SIFIVE_U_DEV_PLIC].base,
    872        plic_hart_config, ms->smp.cpus, 0,
    873        SIFIVE_U_PLIC_NUM_SOURCES,
    874        SIFIVE_U_PLIC_NUM_PRIORITIES,
    875        SIFIVE_U_PLIC_PRIORITY_BASE,
    876        SIFIVE_U_PLIC_PENDING_BASE,
    877        SIFIVE_U_PLIC_ENABLE_BASE,
    878        SIFIVE_U_PLIC_ENABLE_STRIDE,
    879        SIFIVE_U_PLIC_CONTEXT_BASE,
    880        SIFIVE_U_PLIC_CONTEXT_STRIDE,
    881        memmap[SIFIVE_U_DEV_PLIC].size);
    882    g_free(plic_hart_config);
    883    sifive_uart_create(system_memory, memmap[SIFIVE_U_DEV_UART0].base,
    884        serial_hd(0), qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_UART0_IRQ));
    885    sifive_uart_create(system_memory, memmap[SIFIVE_U_DEV_UART1].base,
    886        serial_hd(1), qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_UART1_IRQ));
    887    riscv_aclint_swi_create(memmap[SIFIVE_U_DEV_CLINT].base, 0,
    888        ms->smp.cpus, false);
    889    riscv_aclint_mtimer_create(memmap[SIFIVE_U_DEV_CLINT].base +
    890            RISCV_ACLINT_SWI_SIZE,
    891        RISCV_ACLINT_DEFAULT_MTIMER_SIZE, 0, ms->smp.cpus,
    892        RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME,
    893        CLINT_TIMEBASE_FREQ, false);
    894
    895    if (!sysbus_realize(SYS_BUS_DEVICE(&s->prci), errp)) {
    896        return;
    897    }
    898    sysbus_mmio_map(SYS_BUS_DEVICE(&s->prci), 0, memmap[SIFIVE_U_DEV_PRCI].base);
    899
    900    qdev_prop_set_uint32(DEVICE(&s->gpio), "ngpio", 16);
    901    if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
    902        return;
    903    }
    904    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, memmap[SIFIVE_U_DEV_GPIO].base);
    905
    906    /* Pass all GPIOs to the SOC layer so they are available to the board */
    907    qdev_pass_gpios(DEVICE(&s->gpio), dev, NULL);
    908
    909    /* Connect GPIO interrupts to the PLIC */
    910    for (i = 0; i < 16; i++) {
    911        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), i,
    912                           qdev_get_gpio_in(DEVICE(s->plic),
    913                                            SIFIVE_U_GPIO_IRQ0 + i));
    914    }
    915
    916    /* PDMA */
    917    sysbus_realize(SYS_BUS_DEVICE(&s->dma), errp);
    918    sysbus_mmio_map(SYS_BUS_DEVICE(&s->dma), 0, memmap[SIFIVE_U_DEV_PDMA].base);
    919
    920    /* Connect PDMA interrupts to the PLIC */
    921    for (i = 0; i < SIFIVE_PDMA_IRQS; i++) {
    922        sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), i,
    923                           qdev_get_gpio_in(DEVICE(s->plic),
    924                                            SIFIVE_U_PDMA_IRQ0 + i));
    925    }
    926
    927    qdev_prop_set_uint32(DEVICE(&s->otp), "serial", s->serial);
    928    if (!sysbus_realize(SYS_BUS_DEVICE(&s->otp), errp)) {
    929        return;
    930    }
    931    sysbus_mmio_map(SYS_BUS_DEVICE(&s->otp), 0, memmap[SIFIVE_U_DEV_OTP].base);
    932
    933    /* FIXME use qdev NIC properties instead of nd_table[] */
    934    if (nd->used) {
    935        qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
    936        qdev_set_nic_properties(DEVICE(&s->gem), nd);
    937    }
    938    object_property_set_int(OBJECT(&s->gem), "revision", GEM_REVISION,
    939                            &error_abort);
    940    if (!sysbus_realize(SYS_BUS_DEVICE(&s->gem), errp)) {
    941        return;
    942    }
    943    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gem), 0, memmap[SIFIVE_U_DEV_GEM].base);
    944    sysbus_connect_irq(SYS_BUS_DEVICE(&s->gem), 0,
    945                       qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_GEM_IRQ));
    946
    947    /* PWM */
    948    for (i = 0; i < 2; i++) {
    949        if (!sysbus_realize(SYS_BUS_DEVICE(&s->pwm[i]), errp)) {
    950            return;
    951        }
    952        sysbus_mmio_map(SYS_BUS_DEVICE(&s->pwm[i]), 0,
    953                                memmap[SIFIVE_U_DEV_PWM0].base + (0x1000 * i));
    954
    955        /* Connect PWM interrupts to the PLIC */
    956        for (j = 0; j < SIFIVE_PWM_IRQS; j++) {
    957            sysbus_connect_irq(SYS_BUS_DEVICE(&s->pwm[i]), j,
    958                               qdev_get_gpio_in(DEVICE(s->plic),
    959                                        SIFIVE_U_PWM0_IRQ0 + (i * 4) + j));
    960        }
    961    }
    962
    963    create_unimplemented_device("riscv.sifive.u.gem-mgmt",
    964        memmap[SIFIVE_U_DEV_GEM_MGMT].base, memmap[SIFIVE_U_DEV_GEM_MGMT].size);
    965
    966    create_unimplemented_device("riscv.sifive.u.dmc",
    967        memmap[SIFIVE_U_DEV_DMC].base, memmap[SIFIVE_U_DEV_DMC].size);
    968
    969    create_unimplemented_device("riscv.sifive.u.l2cc",
    970        memmap[SIFIVE_U_DEV_L2CC].base, memmap[SIFIVE_U_DEV_L2CC].size);
    971
    972    sysbus_realize(SYS_BUS_DEVICE(&s->spi0), errp);
    973    sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi0), 0,
    974                    memmap[SIFIVE_U_DEV_QSPI0].base);
    975    sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi0), 0,
    976                       qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_QSPI0_IRQ));
    977    sysbus_realize(SYS_BUS_DEVICE(&s->spi2), errp);
    978    sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi2), 0,
    979                    memmap[SIFIVE_U_DEV_QSPI2].base);
    980    sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi2), 0,
    981                       qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_QSPI2_IRQ));
    982}
    983
    984static Property sifive_u_soc_props[] = {
    985    DEFINE_PROP_UINT32("serial", SiFiveUSoCState, serial, OTP_SERIAL),
    986    DEFINE_PROP_STRING("cpu-type", SiFiveUSoCState, cpu_type),
    987    DEFINE_PROP_END_OF_LIST()
    988};
    989
    990static void sifive_u_soc_class_init(ObjectClass *oc, void *data)
    991{
    992    DeviceClass *dc = DEVICE_CLASS(oc);
    993
    994    device_class_set_props(dc, sifive_u_soc_props);
    995    dc->realize = sifive_u_soc_realize;
    996    /* Reason: Uses serial_hds in realize function, thus can't be used twice */
    997    dc->user_creatable = false;
    998}
    999
   1000static const TypeInfo sifive_u_soc_type_info = {
   1001    .name = TYPE_RISCV_U_SOC,
   1002    .parent = TYPE_DEVICE,
   1003    .instance_size = sizeof(SiFiveUSoCState),
   1004    .instance_init = sifive_u_soc_instance_init,
   1005    .class_init = sifive_u_soc_class_init,
   1006};
   1007
   1008static void sifive_u_soc_register_types(void)
   1009{
   1010    type_register_static(&sifive_u_soc_type_info);
   1011}
   1012
   1013type_init(sifive_u_soc_register_types)