\r
#include "UefiShellDebug1CommandsLib.h"\r
\r
+typedef struct {\r
+ UINT32 Type;\r
+ UINT64 NumberOfPages;\r
+ LIST_ENTRY Link;\r
+} MEMORY_LENGTH_ENTRY;\r
+\r
+/**\r
+ Add the length of the specified type to List.\r
+\r
+ @param List A list to hold all pairs of <Type, NumberOfPages>.\r
+ @param Type Memory type.\r
+ @param NumberOfPages Number of pages.\r
+**/\r
+VOID\r
+AddMemoryLength (\r
+ LIST_ENTRY *List,\r
+ UINT32 Type,\r
+ UINT64 NumberOfPages\r
+ )\r
+{\r
+ MEMORY_LENGTH_ENTRY *Entry;\r
+ MEMORY_LENGTH_ENTRY *NewEntry;\r
+ LIST_ENTRY *Link;\r
+\r
+ Entry = NULL;\r
+ for (Link = GetFirstNode (List); !IsNull (List, Link); Link = GetNextNode (List, Link)) {\r
+ Entry = BASE_CR (Link, MEMORY_LENGTH_ENTRY, Link);\r
+ if (Entry->Type >= Type) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if ((Entry != NULL) && (Entry->Type == Type)) {\r
+ //\r
+ // The Entry is the one we look for.\r
+ //\r
+ NewEntry = Entry;\r
+ } else {\r
+ //\r
+ // The search operation breaks due to:\r
+ // 1. Type of every entry < Type --> Insert to tail\r
+ // 2. Type of an entry > Type --> Insert to previous of this entry\r
+ //\r
+ NewEntry = AllocatePool (sizeof (*NewEntry));\r
+ if (NewEntry == NULL) {\r
+ return;\r
+ }\r
+ NewEntry->Type = Type;\r
+ NewEntry->NumberOfPages = 0;\r
+ InsertTailList (Link, &NewEntry->Link);\r
+ }\r
+\r
+ NewEntry->NumberOfPages += NumberOfPages;\r
+}\r
+\r
/**\r
Function for 'memmap' command.\r
\r
UINT64 PersistentPages;\r
UINT64 PersistentPagesSize;\r
BOOLEAN Sfo;\r
+ LIST_ENTRY MemoryList;\r
+ MEMORY_LENGTH_ENTRY *Entry;\r
+ LIST_ENTRY *Link;\r
\r
AcpiReclaimPages = 0;\r
AcpiNvsPages = 0;\r
Descriptors = NULL;\r
ShellStatus = SHELL_SUCCESS;\r
Status = EFI_SUCCESS;\r
+ InitializeListHead (&MemoryList);\r
\r
//\r
// initialize the shell lib (we must be in non-auto-init...)\r
PalCodePages += Walker->NumberOfPages;\r
break;\r
default:\r
- ASSERT(FALSE);\r
+ //\r
+ // Shell Spec defines the SFO format.\r
+ // Do not print the OEM/OS memory usage in the SFO format, to avoid conflict with Shell Spec.\r
+ //\r
+ if (!Sfo) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MEMMAP_LIST_ITEM_OTHER), gShellDebug1HiiHandle, Walker->Type, Walker->PhysicalStart, Walker->PhysicalStart + MultU64x64 (SIZE_4KB, Walker->NumberOfPages) - 1, Walker->NumberOfPages, Walker->Attribute);\r
+ }\r
+ TotalPages += Walker->NumberOfPages;\r
+ AddMemoryLength (&MemoryList, Walker->Type, Walker->NumberOfPages);\r
+ break;\r
}\r
}\r
//\r
MmioPortPages, MmioPortPagesSize,\r
PalCodePages, PalCodePagesSize,\r
AvailPages, AvailPagesSize,\r
- PersistentPages, PersistentPagesSize,\r
+ PersistentPages, PersistentPagesSize\r
+ );\r
+\r
+ //\r
+ // Print out the total memory usage for OEM/OS types in the order of type.\r
+ //\r
+ for (Link = GetFirstNode (&MemoryList); !IsNull (&MemoryList, Link); Link = GetNextNode (&MemoryList, Link)) {\r
+ Entry = BASE_CR (Link, MEMORY_LENGTH_ENTRY, Link);\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MEMMAP_LIST_SUMM_OTHER), gShellDebug1HiiHandle,\r
+ Entry->Type, Entry->NumberOfPages, MultU64x64 (SIZE_4KB, Entry->NumberOfPages)\r
+ );\r
+ }\r
+\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MEMMAP_LIST_SUMM2), gShellDebug1HiiHandle,\r
DivU64x32(MultU64x64(SIZE_4KB,TotalPages), SIZE_1MB), TotalPagesSize\r
);\r
} else {\r
FreePool(Descriptors);\r
}\r
\r
+ //\r
+ // Free the memory list.\r
+ //\r
+ for (Link = GetFirstNode (&MemoryList); !IsNull (&MemoryList, Link); ) {\r
+ Link = RemoveEntryList (Link);\r
+ }\r
+\r
return (ShellStatus);\r
}\r
\r