內存創建過程圖:
其具體實施過程如下:
1.openpic外部設備內存初始化
使用memory_region_init函數完成該設備內存的創建,其名稱爲openpic,大小爲ox40000
static void openpic_init(Object *obj)
{
OpenPICState *opp = OPENPIC(obj);
memory_region_init(&opp->mem, obj, "openpic", 0x40000);
}
2. IO內存讀寫的定義
使用如下函數完成接口回掉函數的初始化,確定大小端模式以及最大最小訪問字節數
static const MemoryRegionOps openpic_glb_ops_le = {
.write = openpic_gbl_write,
.read = openpic_gbl_read,
.endianness = DEVICE_LITTLE_ENDIAN,
.impl = {
.min_access_size = 4,
.max_access_size = 4,
},
};
3.完成內存映射
1>在openpic_realize函數中使用如下方式,將IO內存信息存儲memreg數組中
static const MemReg list_le[] = {
{"glb", &openpic_glb_ops_le,
OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE},
{"tmr", &openpic_tmr_ops_le,
OPENPIC_TMR_REG_START, OPENPIC_TMR_REG_SIZE},
{"src", &openpic_src_ops_le,
OPENPIC_SRC_REG_START, OPENPIC_SRC_REG_SIZE},
{"cpu", &openpic_cpu_ops_le,
OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE},
{NULL}
};
2>同樣在該函數中使用map_list函數完成
首先使用memory_region_init_io函數完成每一個io內存的創建,將其翻入sub_io_mem中,每完成一個IO內存的初始化count數加1,同時list的指針向後移動,移到下一個IO內存處(相當於移到數組中下一個元素的位置處)。接下來使用memory_region_add_subregion函數將完成創建的IO內存添加到OPENPIC設備的內存(opp->mem)中
map_list(opp, list_be, &list_count);
該函數原型爲:
static void map_list(OpenPICState *opp, const MemReg *list, int *count)
{
while (list->name) {
assert(*count < ARRAY_SIZE(opp->sub_io_mem));
memory_region_init_io(&opp->sub_io_mem[*count], OBJECT(opp), list->ops,
opp, list->name, list->size);
memory_region_add_subregion(&opp->mem, list->start_addr,
&opp->sub_io_mem[*count]);
(*count)++;
list++;
}
}