Re: [PATCH 2/3] hw/riscv: Connect K230 DDR controller and PHY models

Daniel Henrique Barboza <[email protected]> Wed, 22 Jul 2026 17:08:48 -0300
Newsgroups org.nongnu.qemu-riscv,org.nongnu.qemu-devel
Message-ID <[email protected]>

On 7/16/2026 10:24 AM, Junze Cao wrote:
> Replace the unimplemented K230 DDR configuration region with the DDRC
> model and map the PHY model at 0x9a000000.
> 
> Connect the controller to the PHY so DFI status reflects PHY training and
> initialization state.
> 
> Signed-off-by: Junze Cao <[email protected]>
> ---

Reviewed-by: Daniel Henrique Barboza <[email protected]>

>   docs/system/riscv/k230.rst |  4 ++++
>   hw/riscv/k230.c            | 19 ++++++++++++++++---
>   include/hw/riscv/k230.h    |  4 ++++
>   3 files changed, 24 insertions(+), 3 deletions(-)
> 
> diff --git a/docs/system/riscv/k230.rst b/docs/system/riscv/k230.rst
> index cea8202e55..06a819fbdb 100644
> --- a/docs/system/riscv/k230.rst
> +++ b/docs/system/riscv/k230.rst
> @@ -20,12 +20,16 @@ The ``k230`` machine supports the following devices:
>   * Platform-Level Interrupt Controller (PLIC)
>   * 2 K230 Watchdog Timer
>   * 5 UART
> +* K230 DDRC CFG and DDR PHY
>   
>   Boot options
>   ------------
>   The ``k230`` machine supports K230 SDK boot through M-mode U-Boot, which then
>   starts OpenSBI/Linux with ``bootm``. It also supports direct Linux boot.
>   
> +The DDRC CFG and DDR PHY models allow the K230 SDK U-Boot SPL to complete DDR
> +initialization before loading the next boot stage.
> +
>   K230 SDK Linux kernels use T-HEAD C9xx private MAEE page table attributes. QEMU
>   does not implement MAEE in the generic RISC-V MMU, so such kernels need to be
>   built with standard RISC-V PTE bits before they can boot under QEMU.
> diff --git a/hw/riscv/k230.c b/hw/riscv/k230.c
> index 656f28190c..627150b463 100644
> --- a/hw/riscv/k230.c
> +++ b/hw/riscv/k230.c
> @@ -97,6 +97,7 @@ static const MemMapEntry memmap[] = {
>       [K230_DEV_SPI] =          { 0x91584000,  0x00001000 },
>       [K230_DEV_HI_SYS_CFG] =   { 0x91585000,  0x00000400 },
>       [K230_DEV_DDRC_CFG] =     { 0x98000000,  0x02000000 },
> +    [K230_DEV_DDR_PHY] =      { 0x9A000000,  0x00400000 },
>       [K230_DEV_FLASH] =        { 0xC0000000,  0x08000000 },
>       [K230_DEV_PLIC] =         { 0xF00000000, 0x00400000 },
>       [K230_DEV_CLINT] =        { 0xF04000000, 0x00400000 },
> @@ -108,6 +109,11 @@ static void k230_soc_init(Object *obj)
>       RISCVHartArrayState *cpu0 = &s->c908_cpu;
>   
>       object_initialize_child(obj, "c908-cpu", cpu0, TYPE_RISCV_HART_ARRAY);
> +    object_initialize_child(obj, "ddr-cfg", &s->ddr_cfg,
> +                            TYPE_K230_DDR_CFG);
> +    object_initialize_child(obj, "ddr-phy", &s->ddr_phy,
> +                            TYPE_K230_DDR_PHY);
> +    s->ddr_cfg.phy = &s->ddr_phy;
>       object_initialize_child(obj, "k230-wdt0", &s->wdt[0], TYPE_K230_WDT);
>       object_initialize_child(obj, "k230-wdt1", &s->wdt[1], TYPE_K230_WDT);
>   
> @@ -158,6 +164,16 @@ static void k230_soc_realize(DeviceState *dev, Error **errp)
>       int c908_cpus;
>   
>       sysbus_realize(SYS_BUS_DEVICE(&s->c908_cpu), &error_fatal);
> +    if (!sysbus_realize(SYS_BUS_DEVICE(&s->ddr_cfg), errp)) {
> +        return;
> +    }
> +    if (!sysbus_realize(SYS_BUS_DEVICE(&s->ddr_phy), errp)) {
> +        return;
> +    }
> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ddr_cfg), 0,
> +                    memmap[K230_DEV_DDRC_CFG].base);
> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ddr_phy), 0,
> +                    memmap[K230_DEV_DDR_PHY].base);
>   
>       c908_cpus = s->c908_cpu.num_harts;
>   
> @@ -361,9 +377,6 @@ static void k230_soc_realize(DeviceState *dev, Error **errp)
>       create_unimplemented_device("hi_sys_cfg", memmap[K230_DEV_HI_SYS_CFG].base,
>                                   memmap[K230_DEV_HI_SYS_CFG].size);
>   
> -    create_unimplemented_device("ddrc_cfg", memmap[K230_DEV_DDRC_CFG].base,
> -                                memmap[K230_DEV_DDRC_CFG].size);
> -
>       create_unimplemented_device("flash", memmap[K230_DEV_FLASH].base,
>                                   memmap[K230_DEV_FLASH].size);
>   }
> diff --git a/include/hw/riscv/k230.h b/include/hw/riscv/k230.h
> index 592e1c26bf..80ca16338c 100644
> --- a/include/hw/riscv/k230.h
> +++ b/include/hw/riscv/k230.h
> @@ -16,6 +16,7 @@
>   #define HW_K230_H
>   
>   #include "hw/core/boards.h"
> +#include "hw/misc/k230_ddr.h"
>   #include "hw/riscv/riscv_hart.h"
>   #include "hw/watchdog/k230_wdt.h"
>   
> @@ -32,6 +33,8 @@ typedef struct K230SoCState {
>       /*< public >*/
>       RISCVHartArrayState c908_cpu; /* Small core */
>   
> +    K230DDRCfgState ddr_cfg;
> +    K230DDRPhyState ddr_phy;
>       K230WdtState wdt[2];
>       MemoryRegion sram;
>       MemoryRegion bootrom;
> @@ -112,6 +115,7 @@ enum {
>       K230_DEV_SPI,
>       K230_DEV_HI_SYS_CFG,
>       K230_DEV_DDRC_CFG,
> +    K230_DEV_DDR_PHY,
>       K230_DEV_FLASH,
>       K230_DEV_PLIC,
>       K230_DEV_CLINT,