On 8/14/20 6:40 PM, Bin Meng wrote: > From: Bin Meng <bin.m...@windriver.com> > > Microchip PolarFire SoC integrates one Cadence SDHCI controller. > On the Icicle Kit board, one eMMC chip and an external SD card > connect to this controller depending on different configuration. > > As QEMU does not support eMMC yet, we just emulate the SD card > configuration. To test this, the Hart Software Services (HSS) > should choose the SD card configuration: > > $ cp boards/icicle-kit-es/def_config.sdcard .config > $ make BOARD=icicle-kit-es > > The SD card image can be built from the Yocto BSP at: > https://github.com/polarfire-soc/meta-polarfire-soc-yocto-bsp > > Note the generated SD card image should be resized before use: > $ qemu-img resize /path/to/sdcard.img 4G > > Launch QEMU with the following command: > $ qemu-system-riscv64 -nographic -M microchip-icicle-kit -sd sdcard.img > > Signed-off-by: Bin Meng <bin.m...@windriver.com> > --- > > hw/riscv/Kconfig | 1 + > hw/riscv/microchip_pfsoc.c | 26 ++++++++++++++++++++++++++ > include/hw/riscv/microchip_pfsoc.h | 4 ++++ > 3 files changed, 31 insertions(+) > > diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig > index ceb7c16..7412db9 100644 > --- a/hw/riscv/Kconfig > +++ b/hw/riscv/Kconfig > @@ -55,3 +55,4 @@ config MICROCHIP_PFSOC > select SIFIVE > select UNIMP > select MCHP_PFSOC_MMUART > + select CADENCE_SDHCI > diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c > index f6b375c..7c09078 100644 > --- a/hw/riscv/microchip_pfsoc.c > +++ b/hw/riscv/microchip_pfsoc.c > @@ -12,6 +12,7 @@ > * 1) PLIC (Platform Level Interrupt Controller) > * 2) eNVM (Embedded Non-Volatile Memory) > * 3) MMUARTs (Multi-Mode UART) > + * 4) Cadence eMMC/SDHC controller and an SD card connected to it > * > * This board currently generates devicetree dynamically that indicates at > least > * two harts and up to five harts. > @@ -75,6 +76,7 @@ static const struct MemmapEntry { > [MICROCHIP_PFSOC_MMUART0] = { 0x20000000, 0x1000 }, > [MICROCHIP_PFSOC_SYSREG] = { 0x20002000, 0x2000 }, > [MICROCHIP_PFSOC_MPUCFG] = { 0x20005000, 0x1000 }, > + [MICROCHIP_PFSOC_EMMC_SD] = { 0x20008000, 0x1000 }, > [MICROCHIP_PFSOC_MMUART1] = { 0x20100000, 0x1000 }, > [MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 }, > [MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 }, > @@ -111,6 +113,11 @@ static void microchip_pfsoc_soc_instance_init(Object > *obj) > qdev_prop_set_string(DEVICE(&s->u_cpus), "cpu-type", > TYPE_RISCV_CPU_SIFIVE_U54); > qdev_prop_set_uint64(DEVICE(&s->u_cpus), "resetvec", RESET_VECTOR); > + > + object_initialize_child(obj, "sd-controller", &s->sdhci, > + TYPE_CADENCE_SDHCI); > + object_initialize_child(OBJECT(&s->sdhci), "sd-controller.sdhci", > + &s->sdhci.slot, TYPE_SYSBUS_SDHCI);
OK now I see this patch, so NAck. TYPE_SYSBUS_SDHCI has to be initialized in TYPE_CADENCE_SDHCI, not in all TYPE_CADENCE_SDHCI users. > } > > static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp) > @@ -223,6 +230,13 @@ static void microchip_pfsoc_soc_realize(DeviceState > *dev, Error **errp) > memmap[MICROCHIP_PFSOC_MPUCFG].base, > memmap[MICROCHIP_PFSOC_MPUCFG].size); > > + /* SDHCI */ Consider setting the SDHCI DMA MR here. > + sysbus_realize(SYS_BUS_DEVICE(&s->sdhci), errp); > + sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci), 0, > + memmap[MICROCHIP_PFSOC_EMMC_SD].base); > + sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci.slot), 0, > + qdev_get_gpio_in(DEVICE(s->plic), MICROCHIP_PFSOC_EMMC_SD_IRQ)); > + > /* MMUARTs */ > s->serial0 = mchp_pfsoc_mmuart_create(system_memory, > memmap[MICROCHIP_PFSOC_MMUART0].base, > @@ -290,6 +304,7 @@ static void > microchip_icicle_kit_machine_init(MachineState *machine) > MicrochipIcicleKitState *s = MICROCHIP_ICICLE_KIT_MACHINE(machine); > MemoryRegion *system_memory = get_system_memory(); > MemoryRegion *main_mem = g_new(MemoryRegion, 1); > + DriveInfo *dinfo = drive_get_next(IF_SD); > > /* Sanity check on RAM size */ > if (machine->ram_size < mc->default_ram_size) { > @@ -312,6 +327,17 @@ static void > microchip_icicle_kit_machine_init(MachineState *machine) > > /* Load the firmware */ > riscv_find_and_load_firmware(machine, BIOS_FILENAME, RESET_VECTOR, NULL); > + > + /* Attach an SD card */ > + if (dinfo) { > + SDHCIState *sdhci = &(s->soc.sdhci.slot); NAck again, you are not supposed to access this field here. This is why in the previous patch I asked why the "sd-bus" property was not propagated from child to parent. Thanks, Phil. > + DeviceState *card = qdev_new(TYPE_SD_CARD); > + BusState *bus = qdev_get_child_bus(DEVICE(sdhci), "sd-bus"); > + > + qdev_prop_set_drive_err(card, "drive", blk_by_legacy_dinfo(dinfo), > + &error_fatal); > + qdev_realize_and_unref(card, bus, &error_fatal); > + } > } > > static void microchip_icicle_kit_machine_class_init(ObjectClass *oc, void > *data) > diff --git a/include/hw/riscv/microchip_pfsoc.h > b/include/hw/riscv/microchip_pfsoc.h > index a5efa1d..d810ee8 100644 > --- a/include/hw/riscv/microchip_pfsoc.h > +++ b/include/hw/riscv/microchip_pfsoc.h > @@ -23,6 +23,7 @@ > #define HW_MICROCHIP_PFSOC_H > > #include "hw/char/mchp_pfsoc_mmuart.h" > +#include "hw/sd/cadence_sdhci.h" > > typedef struct MicrochipPFSoCState { > /*< private >*/ > @@ -39,6 +40,7 @@ typedef struct MicrochipPFSoCState { > MchpPfSoCMMUartState *serial2; > MchpPfSoCMMUartState *serial3; > MchpPfSoCMMUartState *serial4; > + CadenceSDHCIState sdhci; > } MicrochipPFSoCState; > > #define TYPE_MICROCHIP_PFSOC "microchip.pfsoc" > @@ -74,6 +76,7 @@ enum { > MICROCHIP_PFSOC_MMUART0, > MICROCHIP_PFSOC_SYSREG, > MICROCHIP_PFSOC_MPUCFG, > + MICROCHIP_PFSOC_EMMC_SD, > MICROCHIP_PFSOC_MMUART1, > MICROCHIP_PFSOC_MMUART2, > MICROCHIP_PFSOC_MMUART3, > @@ -85,6 +88,7 @@ enum { > }; > > enum { > + MICROCHIP_PFSOC_EMMC_SD_IRQ = 88, > MICROCHIP_PFSOC_MMUART0_IRQ = 90, > MICROCHIP_PFSOC_MMUART1_IRQ = 91, > MICROCHIP_PFSOC_MMUART2_IRQ = 92, >