Replace the two unimplemented K230 SD controller regions with K230 SDHCI devices. Map them at 0x91580000 and 0x91581000 and connect their interrupts to PLIC inputs 142 and 144 respectively.
Create an SD card on each controller when a corresponding -drive if=sd,index=N backend is provided. Update the K230 machine documentation to list the controllers as supported and remove the instructions that disabled the SDHCI device tree nodes before booting Linux. Signed-off-by: Xin Xie <[email protected]> --- docs/system/riscv/k230.rst | 6 ++---- hw/riscv/Kconfig | 1 + hw/riscv/k230.c | 34 ++++++++++++++++++++++++++++++---- include/hw/riscv/k230.h | 4 ++++ 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/docs/system/riscv/k230.rst b/docs/system/riscv/k230.rst index cea8202e55..6e8286a0df 100644 --- a/docs/system/riscv/k230.rst +++ b/docs/system/riscv/k230.rst @@ -20,6 +20,7 @@ The ``k230`` machine supports the following devices: * Platform-Level Interrupt Controller (PLIC) * 2 K230 Watchdog Timer * 5 UART +* 2 SDHCI controllers Boot options ------------ @@ -100,14 +101,11 @@ Press Enter to stop autoboot. At the U-Boot prompt, run these commands: K230# fdt resize 8192 K230# fdt set /chosen linux,initrd-start <0x0 0xa100000> K230# fdt set /chosen linux,initrd-end <0x0 ${INITRD_END}> - K230# fdt set /soc/sdhci0@91580000 status disabled - K230# fdt set /soc/sdhci1@91581000 status disabled K230# bootm 0xc100000 - 0xa000000 Use ``setenv`` so ``bootm`` writes the kernel command line into ``/chosen/bootargs``. The ``fdt`` commands select the loaded DTB, add space for -edits, describe the initrd range in ``/chosen``, and disable SDHCI nodes because -this machine does not emulate those controllers yet. Replace ``${INITRD_END}`` +edits, and describe the initrd range in ``/chosen``. Replace ``${INITRD_END}`` with the host-calculated value above when typing the command. ``cma=0`` avoids the SDK kernel reserving too much of the little-core memory window for initramfs boot. diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index de37c08cae..e4a0616c16 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -162,3 +162,4 @@ config K230 select SERIAL_MM select UNIMP select K230_WDT + select K230_SDHCI diff --git a/hw/riscv/k230.c b/hw/riscv/k230.c index 656f28190c..7ea69084ae 100644 --- a/hw/riscv/k230.c +++ b/hw/riscv/k230.c @@ -110,6 +110,8 @@ static void k230_soc_init(Object *obj) object_initialize_child(obj, "c908-cpu", cpu0, TYPE_RISCV_HART_ARRAY); object_initialize_child(obj, "k230-wdt0", &s->wdt[0], TYPE_K230_WDT); object_initialize_child(obj, "k230-wdt1", &s->wdt[1], TYPE_K230_WDT); + object_initialize_child(obj, "sdhci0", &s->sdhci[0], TYPE_K230_SDHCI); + object_initialize_child(obj, "sdhci1", &s->sdhci[1], TYPE_K230_SDHCI); qdev_prop_set_uint32(DEVICE(cpu0), "hartid-base", 0); qdev_prop_set_string(DEVICE(cpu0), "cpu-type", TYPE_RISCV_CPU_THEAD_C908); @@ -343,11 +345,21 @@ static void k230_soc_realize(DeviceState *dev, Error **errp) create_unimplemented_device("usb1", memmap[K230_DEV_USB1].base, memmap[K230_DEV_USB1].size); - create_unimplemented_device("sd0", memmap[K230_DEV_SD0].base, - memmap[K230_DEV_SD0].size); + for (int i = 0; i < 2; i++) { + if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdhci[i]), errp)) { + return; + } + } + + sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci[0]), 0, + memmap[K230_DEV_SD0].base); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci[0]), 0, + qdev_get_gpio_in(s->c908_plic, K230_SD0_IRQ)); - create_unimplemented_device("sd1", memmap[K230_DEV_SD1].base, - memmap[K230_DEV_SD1].size); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci[1]), 0, + memmap[K230_DEV_SD1].base); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci[1]), 0, + qdev_get_gpio_in(s->c908_plic, K230_SD1_IRQ)); create_unimplemented_device("qspi0", memmap[K230_DEV_QSPI0].base, memmap[K230_DEV_QSPI0].size); @@ -490,6 +502,20 @@ static void k230_machine_init(MachineState *machine) TYPE_RISCV_K230_SOC); qdev_realize(DEVICE(&s->soc), NULL, &error_fatal); + for (int i = 0; i < 2; i++) { + DriveInfo *dinfo = drive_get(IF_SD, 0, i); + DeviceState *card; + + if (!dinfo) { + continue; + } + + card = qdev_new(TYPE_SD_CARD); + qdev_prop_set_drive_err(card, "drive", blk_by_legacy_dinfo(dinfo), + &error_fatal); + qdev_realize_and_unref(card, s->soc.sdhci[i].bus, &error_fatal); + } + /* Data Memory */ memory_region_add_subregion(sys_mem, memmap[K230_DEV_DDRC].base, machine->ram); diff --git a/include/hw/riscv/k230.h b/include/hw/riscv/k230.h index 592e1c26bf..8e73366e56 100644 --- a/include/hw/riscv/k230.h +++ b/include/hw/riscv/k230.h @@ -18,6 +18,7 @@ #include "hw/core/boards.h" #include "hw/riscv/riscv_hart.h" #include "hw/watchdog/k230_wdt.h" +#include "hw/sd/k230_sdhci.h" #define C908_CPU_HARTID (0) @@ -33,6 +34,7 @@ typedef struct K230SoCState { RISCVHartArrayState c908_cpu; /* Small core */ K230WdtState wdt[2]; + K230SDHCIState sdhci[2]; MemoryRegion sram; MemoryRegion bootrom; @@ -129,6 +131,8 @@ enum { K230_UART4_IRQ = 20, K230_WDT0_IRQ = 107, K230_WDT1_IRQ = 108, + K230_SD0_IRQ = 142, + K230_SD1_IRQ = 144, }; #define K230_UART_COUNT 5 -- 2.43.0
