VOID\r
);\r
\r
-/**\r
- Build reserved memory range resource HOB.\r
-\r
- @param MemoryBase Reserved memory range base address.\r
- @param MemorySize Reserved memory range size.\r
-\r
-**/\r
-STATIC\r
-VOID\r
-AddReservedMemoryBaseSizeHob (\r
- EFI_PHYSICAL_ADDRESS MemoryBase,\r
- UINT64 MemorySize\r
- )\r
-{\r
- BuildResourceDescriptorHob (\r
- EFI_RESOURCE_MEMORY_RESERVED,\r
- EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
- EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
- EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
- EFI_RESOURCE_ATTRIBUTE_TESTED,\r
- MemoryBase,\r
- MemorySize\r
- );\r
-}\r
-\r
/**\r
Create memory range resource HOB using the memory base\r
address and size.\r
STATIC\r
VOID\r
AddMemoryBaseSizeHob (\r
- EFI_PHYSICAL_ADDRESS MemoryBase,\r
- UINT64 MemorySize\r
+ IN EFI_PHYSICAL_ADDRESS MemoryBase,\r
+ IN UINT64 MemorySize\r
)\r
{\r
BuildResourceDescriptorHob (\r
STATIC\r
VOID\r
AddMemoryRangeHob (\r
- EFI_PHYSICAL_ADDRESS MemoryBase,\r
- EFI_PHYSICAL_ADDRESS MemoryLimit\r
+ IN EFI_PHYSICAL_ADDRESS MemoryBase,\r
+ IN EFI_PHYSICAL_ADDRESS MemoryLimit\r
)\r
{\r
AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));\r
STATIC\r
VOID\r
InitializeRamRegions (\r
- EFI_PHYSICAL_ADDRESS SystemMemoryBase,\r
- UINT64 SystemMemorySize,\r
- EFI_PHYSICAL_ADDRESS MmodeResvBase,\r
- UINT64 MmodeResvSize\r
+ IN EFI_PHYSICAL_ADDRESS SystemMemoryBase,\r
+ IN UINT64 SystemMemorySize\r
)\r
{\r
- /*\r
- * M-mode FW can be loaded anywhere in memory but should not overlap\r
- * with the EDK2. This can happen if some other boot code loads the\r
- * M-mode firmware.\r
- *\r
- * The M-mode firmware memory should be marked as reserved memory\r
- * so that OS doesn't use it.\r
- */\r
- DEBUG ((\r
- DEBUG_INFO,\r
- "%a: M-mode FW Memory Start:0x%lx End:0x%lx\n",\r
- __FUNCTION__,\r
- MmodeResvBase,\r
- MmodeResvBase + MmodeResvSize\r
- ));\r
- AddReservedMemoryBaseSizeHob (MmodeResvBase, MmodeResvSize);\r
-\r
- if (MmodeResvBase > SystemMemoryBase) {\r
- AddMemoryRangeHob (SystemMemoryBase, MmodeResvBase);\r
- }\r
-\r
AddMemoryRangeHob (\r
- MmodeResvBase + MmodeResvSize,\r
+ SystemMemoryBase,\r
SystemMemoryBase + SystemMemorySize\r
);\r
}\r
\r
+/** Get the number of cells for a given property\r
+\r
+ @param[in] Fdt Pointer to Device Tree (DTB)\r
+ @param[in] Node Node\r
+ @param[in] Name Name of the property\r
+\r
+ @return Number of cells.\r
+**/\r
+STATIC\r
+INT32\r
+GetNumCells (\r
+ IN VOID *Fdt,\r
+ IN INT32 Node,\r
+ IN CONST CHAR8 *Name\r
+ )\r
+{\r
+ CONST INT32 *Prop;\r
+ INT32 Len;\r
+ UINT32 Val;\r
+\r
+ Prop = fdt_getprop (Fdt, Node, Name, &Len);\r
+ if (Prop == NULL) {\r
+ return Len;\r
+ }\r
+\r
+ if (Len != sizeof (*Prop)) {\r
+ return -FDT_ERR_BADNCELLS;\r
+ }\r
+\r
+ Val = fdt32_to_cpu (*Prop);\r
+ if (Val > FDT_MAX_NCELLS) {\r
+ return -FDT_ERR_BADNCELLS;\r
+ }\r
+\r
+ return (INT32)Val;\r
+}\r
+\r
+/** Mark reserved memory ranges in the EFI memory map\r
+\r
+ The M-mode firmware ranges should not be used by the\r
+ EDK2/OS. These ranges are passed via device tree using reserved\r
+ memory nodes. Parse the DT and mark those ranges as of\r
+ type EfiReservedMemoryType.\r
+\r
+ NOTE: Device Tree spec section 3.5.4 says reserved memory regions\r
+ without no-map property should be installed as EfiBootServicesData.\r
+ As per UEFI spec, memory of type EfiBootServicesData can be used\r
+ by the OS after ExitBootServices().\r
+ This is not an issue for DT since OS can parse the DT also along\r
+ with EFI memory map and avoid using these ranges. But with ACPI,\r
+ there is no such mechanisms possible.\r
+ Since EDK2 needs to support both DT and ACPI, we are deviating\r
+ from the DT spec and marking all reserved memory ranges as\r
+ EfiReservedMemoryType itself irrespective of no-map.\r
+\r
+ @param FdtPointer Pointer to FDT\r
+\r
+**/\r
+STATIC\r
+VOID\r
+AddReservedMemoryMap (\r
+ IN VOID *FdtPointer\r
+ )\r
+{\r
+ CONST INT32 *RegProp;\r
+ INT32 Node;\r
+ INT32 SubNode;\r
+ INT32 Len;\r
+ EFI_PHYSICAL_ADDRESS Addr;\r
+ UINT64 Size;\r
+ INTN NumRsv, i;\r
+ INT32 NumAddrCells, NumSizeCells;\r
+\r
+ NumRsv = fdt_num_mem_rsv (FdtPointer);\r
+\r
+ /* Look for an existing entry and add it to the efi mem map. */\r
+ for (i = 0; i < NumRsv; i++) {\r
+ if (fdt_get_mem_rsv (FdtPointer, i, &Addr, &Size) != 0) {\r
+ continue;\r
+ }\r
+\r
+ BuildMemoryAllocationHob (\r
+ Addr,\r
+ Size,\r
+ EfiReservedMemoryType\r
+ );\r
+ }\r
+\r
+ /* process reserved-memory */\r
+ Node = fdt_subnode_offset (FdtPointer, 0, "reserved-memory");\r
+ if (Node >= 0) {\r
+ NumAddrCells = GetNumCells (FdtPointer, Node, "#address-cells");\r
+ if (NumAddrCells <= 0) {\r
+ return;\r
+ }\r
+\r
+ NumSizeCells = GetNumCells (FdtPointer, Node, "#size-cells");\r
+ if (NumSizeCells <= 0) {\r
+ return;\r
+ }\r
+\r
+ fdt_for_each_subnode (SubNode, FdtPointer, Node) {\r
+ RegProp = fdt_getprop (FdtPointer, SubNode, "reg", &Len);\r
+\r
+ if ((RegProp != 0) && (Len == ((NumAddrCells + NumSizeCells) * sizeof (INT32)))) {\r
+ Addr = fdt32_to_cpu (RegProp[0]);\r
+\r
+ if (NumAddrCells > 1) {\r
+ Addr = (Addr << 32) | fdt32_to_cpu (RegProp[1]);\r
+ }\r
+\r
+ RegProp += NumAddrCells;\r
+ Size = fdt32_to_cpu (RegProp[0]);\r
+\r
+ if (NumSizeCells > 1) {\r
+ Size = (Size << 32) | fdt32_to_cpu (RegProp[1]);\r
+ }\r
+\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a: Adding Reserved Memory Addr = 0x%llx, Size = 0x%llx\n",\r
+ __func__,\r
+ Addr,\r
+ Size\r
+ ));\r
+\r
+ BuildMemoryAllocationHob (\r
+ Addr,\r
+ Size,\r
+ EfiReservedMemoryType\r
+ );\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
/**\r
Initialize memory hob based on the DTB information.\r
\r
INT32 Node, Prev;\r
INT32 Len;\r
VOID *FdtPointer;\r
- EFI_PHYSICAL_ADDRESS MmodeResvBase;\r
- UINT64 MmodeResvSize;\r
\r
FirmwareContext = NULL;\r
GetFirmwareContextPointer (&FirmwareContext);\r
return EFI_UNSUPPORTED;\r
}\r
\r
- /* try to locate the reserved memory opensbi node */\r
- Node = fdt_path_offset (FdtPointer, "/reserved-memory/mmode_resv0");\r
- if (Node >= 0) {\r
- RegProp = fdt_getprop (FdtPointer, Node, "reg", &Len);\r
- if ((RegProp != 0) && (Len == (2 * sizeof (UINT64)))) {\r
- MmodeResvBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));\r
- MmodeResvSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));\r
- }\r
- }\r
-\r
// Look for the lowest memory node\r
for (Prev = 0; ; Prev = Node) {\r
Node = fdt_next_node (FdtPointer, Prev, NULL);\r
CurBase + CurSize - 1\r
));\r
\r
- if ((MmodeResvBase >= CurBase) && ((MmodeResvBase + MmodeResvSize) <= (CurBase + CurSize))) {\r
- InitializeRamRegions (\r
- CurBase,\r
- CurSize,\r
- MmodeResvBase,\r
- MmodeResvSize\r
- );\r
- } else {\r
- AddMemoryBaseSizeHob (CurBase, CurSize);\r
- }\r
+ InitializeRamRegions (\r
+ CurBase,\r
+ CurSize\r
+ );\r
} else {\r
DEBUG ((\r
DEBUG_ERROR,\r
}\r
}\r
\r
+ AddReservedMemoryMap (FdtPointer);\r
+\r
InitMmu ();\r
\r
BuildMemoryTypeInformationHob ();\r