Gcd (global coherency domain) : 全局一致性域: 个人理解规定着CPU视角的所有地址空间;
这是UEFI_DXECORE的一个重要服务;
DxeMain 被安装时, 会调用 CoreInitializeGcdServices:
- 利用EFI_HOB_TYPE_CPU获取CPU的地址线, 创建Entry->Link (Entry->EndAddress).
- 遍历所有的Hob, 查找EFI_HOB_TYPE_RESOURCE_DESCRIPTOR(这里我们PcdRamRegionsBottom-PcdRamRegionsTop).
- 将ResourceHob使用AddMemorySpace添加到Gcd内.(包含描述Hob内的Attribute).(根据Hob的不同类信息区分不同Gcd设置).
- 向mGcdMemorySpaceMap插入Entry.
CoreInitializeGcdServices: 首先会使用PEI建立的EFI_HOB_TYPE_CPU来指定CPU可以看到的所有的Memory&IO的Spce, 在龙芯平台下, 虚拟地址的固件这里为64, 新世界物理地址固件这里为48, 即将Cpu的视角以1:1映射的关系看到48位;
这个初始化过程非常重要,整个地址空间被初始化为 EfiGcdMemoryTypeNonExistent 类型, 只要被Cpu看见的区域,后面不管AddMemoryRange添加内存区域还是使用所有AllocatePage分配内存以及添加Pcie_Memory Host资源都需要被包含在内,否则会被检测出错;
24 ///
25 /// Global Coherencey Domain types - Memory type.
26 ///
27 typedef enum {
28 ///
29 /// A memory region that is visible to the boot processor. However, there are no system
30 /// components that are currently decoding this memory region.
31 ///
32 EfiGcdMemoryTypeNonExistent,
33 ///
34 /// A memory region that is visible to the boot processor. This memory region is being
35 /// decoded by a system component, but the memory region is not considered to be either
36 /// system memory or memory-mapped I/O.
37 ///
38 EfiGcdMemoryTypeReserved,
39 ///
40 /// A memory region that is visible to the boot processor. A memory controller is
41 /// currently decoding this memory region and the memory controller is producing a
42 /// tested system memory region that is available to the memory services.
43 ///
44 EfiGcdMemoryTypeSystemMemory,
45 ///
46 /// A memory region that is visible to the boot processor. This memory region is
47 /// currently being decoded by a component as memory-mapped I/O that can be used to
48 /// access I/O devices in the platform.
49 ///
50 EfiGcdMemoryTypeMemoryMappedIo,
51 ///
52 /// A memory region that is visible to the boot processor.
53 /// This memory supports byte-addressable non-volatility.
54 ///
55 EfiGcdMemoryTypePersistent,
56 //
57 // Keep original one for the compatibility.
58 //
59 EfiGcdMemoryTypePersistentMemory = EfiGcdMemoryTypePersistent,
60 ///
61 /// A memory region that provides higher reliability relative to other memory in the
62 /// system. If all memory has the same reliability, then this bit is not used.
63 ///
64 EfiGcdMemoryTypeMoreReliable,
65 EfiGcdMemoryTypeMaximum
66 } EFI_GCD_MEMORY_TYPE;
以上这些类型都会在添加Gcd时从EfiGcdMemoryTypeNonExistent转换为对应类型, 比如AddMemorySpace(EfiGcdMemoryTypeMemoryMappedIo,…) 用来添加一段为MMIO的区域供PCIE枚举分配BAR资源使用;
还有一些Gcd的资源描述信息来自于PEI建立的Hob块, 比如PEI阶段添加的Reserved的区域描述等.
21 //
22 // HobType of EFI_HOB_GENERIC_HEADER.
23 //
24 #define EFI_HOB_TYPE_HANDOFF 0x0001
25 #define EFI_HOB_TYPE_MEMORY_ALLOCATION 0x0002
26 #define EFI_HOB_TYPE_RESOURCE_DESCRIPTOR 0x0003
27 #define EFI_HOB_TYPE_GUID_EXTENSION 0x0004
28 #define EFI_HOB_TYPE_FV 0x0005
29 #define EFI_HOB_TYPE_CPU 0x0006
30 #define EFI_HOB_TYPE_MEMORY_POOL 0x0007
31 #define EFI_HOB_TYPE_FV2 0x0009
32 #define EFI_HOB_TYPE_LOAD_PEIM_UNUSED 0x000A
33 #define EFI_HOB_TYPE_UEFI_CAPSULE 0x000B
34 #define EFI_HOB_TYPE_FV3 0x000C
35 #define EFI_HOB_TYPE_UNUSED 0xFFFE
36 #define EFI_HOB_TYPE_END_OF_HOB_LIST 0xFFFF
创建Hob: 根据HobLength创建Start,然后进行Copy, 并在此之前将GUID进行Copy到&Hob->Name.
其中不同的Hob,创建后的结构不同, 比如: MEMORY_ALLOCATION : 需要填写HOB的内存类型
CoreConvertSpace: 从GcdMapEntry中找到可包含BaseAddress+length这段空间的描述符.
分配一段Pool来存拆分掉的的Gcd描述符, 将新的描述符转换到Entry内并将这段描述符插入GcdMapEntry. ,作为操作, 设置Entry的Attribute.
分配DXECore的内存, 必须这段Base是EfiGcdMemoryTypeSystemMemory类型的描述符(即Add的内存空间用来加载DxeCore).
BuildMemoryHob: AllocatePage分配的时候会去分配该类型的地址,其中可以指定最大地址与具体的地址(后期详谈Allocate章节).
BuildGuidDataHob: GuidHob, 用一个Guid来分配一个块,用来存储一段数据给DXE使用;
19 ///
20 /// Enumeration of memory types introduced in UEFI.
21 ///
22 typedef enum {
23 ///
24 /// Not used.
25 ///
26 EfiReservedMemoryType,
27 ///
28 /// The code portions of a loaded application.
29 /// (Note that UEFI OS loaders are UEFI applications.)
30 ///
31 EfiLoaderCode,
32 ///
33 /// The data portions of a loaded application and the default data allocation
34 /// type used by an application to allocate pool memory.
35 ///
36 EfiLoaderData,
37 ///
38 /// The code portions of a loaded Boot Services Driver.
39 ///
40 EfiBootServicesCode,
41 ///
42 /// The data portions of a loaded Boot Serves Driver, and the default data
43 /// allocation type used by a Boot Services Driver to allocate pool memory.
44 ///
45 EfiBootServicesData,
46 ///
47 /// The code portions of a loaded Runtime Services Driver.
48 ///
49 EfiRuntimeServicesCode,
50 ///
51 /// The data portions of a loaded Runtime Services Driver and the default
52 /// data allocation type used by a Runtime Services Driver to allocate pool memory.
53 ///
54 EfiRuntimeServicesData,
55 ///
56 /// Free (unallocated) memory.
57 ///
58 EfiConventionalMemory,
59 ///
60 /// Memory in which errors have been detected.
61 ///
62 EfiUnusableMemory,
63 ///
64 /// Memory that holds the ACPI tables.
65 ///
66 EfiACPIReclaimMemory,
67 ///
68 /// Address space reserved for use by the firmware.
69 ///
70 EfiACPIMemoryNVS,
71 ///
72 /// Used by system firmware to request that a memory-mapped IO region
73 /// be mapped by the OS to a virtual address so it can be accessed by EFI runtime services.
74 ///
75 EfiMemoryMappedIO,
76 ///
77 /// System memory-mapped IO region that is used to translate memory
78 /// cycles to IO cycles by the processor.
79 ///
80 EfiMemoryMappedIOPortSpace,
81 ///
82 /// Address space reserved by the firmware for code that is part of the processor.
83 ///
84 EfiPalCode,
85 ///
86 /// A memory region that operates as EfiConventionalMemory,
87 /// however it happens to also support byte-addressable non-volatility.
88 ///
89 EfiPersistentMemory,
90 EfiMaxMemoryType
91 } EFI_MEMORY_TYPE;
Gcd维护着所有地址空间, memmap即可查看所有地址空间的具体使用情况;
下一章: 添加 PCI HostResource到GCD, 供PCI_BUS枚举ProgramBar.
详解不同平台下HostAddress和DeviceAddress不一致, 从而edk2在PciHostBridgeDxe和PciIo中添加Translation:
DeviceAddress维护在Gcd内,但是BarResource是Host的地址空间;