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,