当前位置: 首页 > ds >正文

Qemu-NUC980(四):SDRAM Interface Controller

概述

本文描述了980 CPU下SDRAM 接口的qemu框架代码。为了便于阅读,我删除了部分代码,完整的代码请查看文后的工程链接。

添加步骤

1、在include/hw/misc/目录下创建nuc980_sdic.h,如下所示:

+号部分为新增加内容

diff --git a/include/hw/misc/nuc980_sdic.h b/include/hw/misc/nuc980_sdic.h
new file mode 100644
index 00000000..39564fe6
--- /dev/null
+++ b/include/hw/misc/nuc980_sdic.h
@@ -0,0 +1,60 @@
+/*
+ * NUC980 SDRAM Interface Controller emulation.
+ *
+ * Copyright (c) 2025 ~ by yanl1229@163.com.
+ * Written by yanl1229
+ *
+ * This code is licensed under the GPL.
+ */
+#ifndef NUC980_SDIC__H
+#define NUC980_SDIC__H
+
+#include "hw/sysbus.h"
+
+#define SDIC_OPMCTL             0x00
+#define SDIC_CMD                0x04
+#define SDIC_REFCTL             0x08
+#define SDIC_SIZE0              0x10
+#define SDIC_SIZE1              0x14
+#define SDIC_MR                 0x18
+#define SDIC_EMR                0x1c
+#define SDIC_EMR2               0x20
+#define SDIC_EMR3               0x24
+#define SDIC_TIME               0x28
+#define SDIC_DQSODS             0x30
+#define SDIC_CKDQSDS            0x34
+#define SDIC_DAENSEL            0x38
+
+#define SDRAM_BASE      0x0000000
+#define SDRAM_SIZE      (64 *1024 * 1024)
+
+#define SDRAM_SIZE_32M  (0x5 << 0)
+
+#define TYPE_NUC980_SDIC "nuc980-sdic"
+#define NUC980_SDIC(obj) \
+    OBJECT_CHECK(NUC980SDICState, (obj), TYPE_NUC980_SDIC)
+
+typedef struct {
+    /* <private> */
+    SysBusDevice parent_obj;
+
+    /* <public> */
+    MemoryRegion mmio;
+
+    uint32_t sdic_opmctl;
+    uint32_t sdic_cmd;
+    uint32_t sdic_refctl;
+    uint32_t sdic_size0;
+    uint32_t sdic_size1;
+    uint32_t sdic_mr;
+    uint32_t sdic_emr;
+    uint32_t sdic_emr2;
+    uint32_t sdic_emr3;
+    uint32_t sdic_time;
+    uint32_t sdic_dqsods;
+    uint32_t sdic_ckdqsds;
+    uint32_t sdic_daensel;
+
+} NUC980SDICState;
+
+#endif

2、在hw/misc/目录下创建nuc980_sdic.c,如下所示:

+号部分为新增加内容

diff --git a/hw/misc/nuc980_sdic.c b/hw/misc/nuc980_sdic.c
new file mode 100644
index 00000000..488965fe
--- /dev/null
+++ b/hw/misc/nuc980_sdic.c
@@ -0,0 +1,219 @@
+/*
+ * NUC980 SDRAM Interface Controller emulation.
+ *
+ * Copyright (c) 2025 ~ by yanl1229@163.com.
+ * Written by yanl1229
+ *
+ * This code is licensed under the GPL.
+ */
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "hw/misc/nuc980_sdic.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "qemu/module.h"
+
+#ifndef ADC_ERR_DEBUG
+#define ADC_ERR_DEBUG 0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+    if (ADC_ERR_DEBUG >= lvl) { \
+        qemu_log("%s: " fmt, __func__, ## args); \
+    } \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void nuc980_sdic_reset(DeviceState *dev)
+{......
+}
+
+static uint64_t nuc980_sdic_read(void *opaque, hwaddr addr,
+                                     unsigned int size)
+{......
+}
+
+static void nuc980_sdic_write(void *opaque, hwaddr addr,
+                                uint64_t val64, unsigned int size)
+{......
+}
+
+static const MemoryRegionOps nuc980_sdic_ops = {
+    .read = nuc980_sdic_read,
+    .write = nuc980_sdic_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const VMStateDescription vmstate_nuc980_sdic = {
+    .name = TYPE_NUC980_SDIC,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(sdic_opmctl, NUC980SDICState),
+        VMSTATE_UINT32(sdic_cmd,    NUC980SDICState),
+        VMSTATE_UINT32(sdic_refctl, NUC980SDICState),
+        VMSTATE_UINT32(sdic_size0,  NUC980SDICState),
+        VMSTATE_UINT32(sdic_size1,  NUC980SDICState),
+        VMSTATE_UINT32(sdic_mr,     NUC980SDICState),
+        VMSTATE_UINT32(sdic_emr,    NUC980SDICState),
+        VMSTATE_UINT32(sdic_emr2,   NUC980SDICState),
+        VMSTATE_UINT32(sdic_emr3,   NUC980SDICState),
+        VMSTATE_UINT32(sdic_time,   NUC980SDICState),
+        VMSTATE_UINT32(sdic_dqsods, NUC980SDICState),
+        VMSTATE_UINT32(sdic_ckdqsds, NUC980SDICState),
+        VMSTATE_UINT32(sdic_daensel, NUC980SDICState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void nuc980_sdic_realize(DeviceState *dev, Error **errp)
+{
+    NUC980SDICState *s = NUC980_SDIC(dev);
+
+    memory_region_init_io(&s->mmio, OBJECT(s), &nuc980_sdic_ops, s,
+                          TYPE_NUC980_SDIC, 0x1000);
+    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
+}
+
+static void nuc980_sdic_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = nuc980_sdic_realize;
+    dc->reset = nuc980_sdic_reset;
+    dc->vmsd = &vmstate_nuc980_sdic;
+}
+
+static const TypeInfo nuc980_sdic_info = {
+    .name          = TYPE_NUC980_SDIC,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(NUC980SDICState),
+    .class_init    = nuc980_sdic_class_init,
+};
+
+static void nuc980_sdic_register_types(void)
+{
+    type_register_static(&nuc980_sdic_info);
+}
+
+type_init(nuc980_sdic_register_types)

3、修改hw/misc/目录下创建Kconfig,如下所示:

+号部分为新增加内容

diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index de6dc940..cc261841 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -131,4 +131,7 @@ config NUC980_SYSconfig NUC980_CLKbool+config NUC980_SDIC
+    bool
+    source macio/Kconfig

4、修改hw/misc目录下创建Makefile.objs,如下所示:

+号部分为新增加内容

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index c3c352d5..4c6fbfab 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -85,4 +85,5 @@ common-obj-$(CONFIG_GRLIB) += grlib_ahb_apb_pnp.oobj-$(CONFIG_NUC980_SYS) += nuc980_sys.oobj-$(CONFIG_NUC980_CLK) += nuc980_clk.o
+obj-$(CONFIG_NUC980_SDIC) += nuc980_sdic.o

5、修改hw/arm/目录下创建Kconfig,如下所示:

+号部分为新增加内容

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index db86365b..3d24f9f0 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -117,6 +117,7 @@ config NUC980boolselect NUC980_CLKselect NUC980_SYS
+    select NUC980_SDICconfig NUC980_EVBbool

6、修改hw/arm/目录下创建nuc980_soc.c,如下所示:

+号部分为新增加内容

diff --git a/hw/arm/nuc980_soc.c b/hw/arm/nuc980_soc.c
index 0223d550..1b0a05f2 100644
--- a/hw/arm/nuc980_soc.c
+++ b/hw/arm/nuc980_soc.c
@@ -31,6 +31,9 @@ static void nuc980_init(Object *obj)sysbus_init_child_obj(obj, "clk", &s->clk, sizeof(s->clk), TYPE_NUC980_CLK);/* system manage */sysbus_init_child_obj(obj, "sys", &s->sys, sizeof(s->sys), TYPE_NUC980_SYSTEM);
+    /* sdic*/
+    sysbus_init_child_obj(obj, "sdic", &s->sdic, sizeof(s->sdic), TYPE_NUC980_SDIC);
+}static void nuc980_realize(DeviceState *dev, Error **errp)
@@ -55,6 +58,13 @@ static void nuc980_realize(DeviceState *dev, Error **errp)/* system manage */sysbus_mmio_map(SYS_BUS_DEVICE(&s->sys), 0, SYSTEM_MANAGE_BASE);+    /* sdic */
+    object_property_set_bool(OBJECT(&s->sdic), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdic), 0, SDIC_BASE);}static void nuc980_class_init(ObjectClass *oc, void *data)

7、修改/include/hw/arm/目录下创建nuc980.h,如下所示:

+号部分为新增加内容

diff --git a/include/hw/arm/nuc980.h b/include/hw/arm/nuc980.h
index 353adb72..f24d5a82 100644
--- a/include/hw/arm/nuc980.h
+++ b/include/hw/arm/nuc980.h
@@ -15,6 +15,7 @@#include "hw/misc/nuc980_clk.h"#include "hw/misc/nuc980_sys.h"
+#include "hw/misc/nuc980_sdic.h"#define SDRAM_BASE      0x0000000#define SDRAM_SIZE      (64 *1024 * 1024)
@@ -25,6 +26,8 @@#define SDRAM_SIZE_32M  (0x5 << 0)+#define SDIC_BASE       0xb0002000
+#define TYPE_NUC980 "nuc980"#define NUC980(obj) OBJECT_CHECK(NUC980State, (obj), TYPE_NUC980)@@ -39,6 +42,7 @@ typedef struct NUC980State {NUC980ClockState clk;NUC980SystemState sys;
+    NUC980SDICState sdic;} NUC980State;

总结

本文描述了添加980 CPU中SDRAM Interface Controller的qemu框架代码的添加步骤,在描述过程中,删除了部分代码。

工程链接

https://gitee.com/yanl1229/qemu.git

http://www.xdnf.cn/news/20534.html

相关文章:

  • 什么是“二合一矫平机”?——一篇技术科普
  • 主流的开源协议(MIT,Apache,GPL v2/v3)
  • Qt编程之信号与槽
  • 吴恩达机器学习(八)
  • make时设置链接器选项的2种方法
  • 【操作系统-Day 25】死锁 (Deadlock):揭秘多线程编程的“终极杀手”
  • Zoom AI 技术架构研究:联合式方法与多模态集成
  • 【LeetCode热题100道笔记】翻转二叉树
  • python炒股
  • C++ 20 新增特性以及代码示例
  • 同态加密库(Google FHE)
  • 神经网络的初始化:权重与偏置的数学策略
  • C# WinForm分页控件实现与使用详解
  • B.50.10.09-RPC核心原理与电商应用
  • MATLAB R2025a安装配置及使用教程(超详细保姆级教程)
  • 什么是云手机?
  • Vue3 - Echarts自定义主题引入(Error:ECharts is not Loaded,Error:default ,Error:module)
  • 攻击服务器的方式有哪些,对应的应对策略有哪些?
  • 联邦学习论文分享:Towards Building the Federated GPT:Federated Instruction Tuning
  • Leetcode hot100 最长连续序列
  • rh134第五章复习总结
  • SDRAM详细分析-08 数据手册解读
  • AI + 办公工具 = 应用案例
  • (论文速读)视觉语言模型评价中具有挑战性的选择题的自动生成
  • 大模型推理时的加速思路?
  • RabbitMq 初步认识
  • 自动化运维之ansible
  • LwIP入门实战 — 3 LwIP的网络接口管理
  • HTB devvortex
  • 【混元AIGC+腾讯云智能体+首创Coze核心流思维导图MCP】:打造一个文思通-智能写作助手Agent