]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellDebug1CommandsLib/MemMap.c
ShellPkg/for: Fix potential null pointer deference
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / MemMap.c
index 4e35760aa07c5d05f3ed2efdb3022be0a7719874..c856661917aedd1e1f551f6903a0a6e6678c0d44 100644 (file)
@@ -1,8 +1,9 @@
 /** @file\r
   Main file for Mode shell Debug1 function.\r
 \r
+  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
   (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>\r
-  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which acModeanies this distribution.  The full text of the license may be found at\r
@@ -47,6 +48,61 @@ STATIC CONST CHAR16 NameEfiMemoryMappedIOPortSpaceShort[] = L"MMIO_Port";
 \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
@@ -65,11 +121,11 @@ ShellCommandRunMemMap (
   CHAR16              *ProblemParam;\r
   SHELL_STATUS        ShellStatus;\r
   UINTN               Size;\r
-  EFI_MEMORY_DESCRIPTOR *Buffer;\r
+  EFI_MEMORY_DESCRIPTOR *Descriptors;\r
   UINTN               MapKey;\r
   UINTN               ItemSize;\r
   UINT32              Version;\r
-  UINT8               *Walker;\r
+  EFI_MEMORY_DESCRIPTOR *Walker;\r
   UINT64              ReservedPages;\r
   UINT64              LoadCodePages;\r
   UINT64              LoadDataPages;\r
@@ -100,7 +156,12 @@ ShellCommandRunMemMap (
   UINT64              UnusableMemoryPagesSize;\r
   UINT64              PalCodePages;\r
   UINT64              PalCodePagesSize;\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
@@ -117,10 +178,12 @@ ShellCommandRunMemMap (
   MmioPortPages       = 0;\r
   UnusableMemoryPages = 0;\r
   PalCodePages        = 0;\r
+  PersistentPages     = 0;\r
   Size                = 0;\r
-  Buffer              = NULL;\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
@@ -148,11 +211,11 @@ ShellCommandRunMemMap (
       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"memmap");  \r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
     } else {\r
-      Status = gBS->GetMemoryMap(&Size, Buffer, &MapKey, &ItemSize, &Version);\r
+      Status = gBS->GetMemoryMap(&Size, Descriptors, &MapKey, &ItemSize, &Version);\r
       if (Status == EFI_BUFFER_TOO_SMALL){\r
         Size += SIZE_1KB;\r
-        Buffer = AllocateZeroPool(Size);\r
-        Status = gBS->GetMemoryMap(&Size, Buffer, &MapKey, &ItemSize, &Version);\r
+        Descriptors = AllocateZeroPool(Size);\r
+        Status = gBS->GetMemoryMap(&Size, Descriptors, &MapKey, &ItemSize, &Version);\r
       }\r
       if (EFI_ERROR(Status)) {\r
         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MEMMAP_GET_FAILED), gShellDebug1HiiHandle, L"memmap");  \r
@@ -167,81 +230,93 @@ ShellCommandRunMemMap (
           ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellDebug1HiiHandle, L"memmap");\r
         }\r
 \r
-        for (Walker = (UINT8*)Buffer; Walker < (((UINT8*)Buffer)+Size) && Walker != NULL; Walker += ItemSize){\r
-          switch (((EFI_MEMORY_DESCRIPTOR*)Walker)->Type) {\r
+        for ( Walker = Descriptors\r
+            ; (Walker < (EFI_MEMORY_DESCRIPTOR *) ((UINT8*)Descriptors + Size)) && (Walker != NULL)\r
+            ; Walker = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *)Walker + ItemSize)\r
+            ){\r
+          switch (Walker->Type) {\r
             case  EfiReservedMemoryType:\r
-              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiReservedMemoryType, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart+MultU64x64(SIZE_4KB,((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages)-1, ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages, ((EFI_MEMORY_DESCRIPTOR*)Walker)->Attribute);\r
-              ReservedPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
+              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiReservedMemoryType, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute);\r
+              ReservedPages += Walker->NumberOfPages;\r
               break;\r
             case EfiLoaderCode:\r
-              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiLoaderCode, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart+MultU64x64(SIZE_4KB,((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages)-1, ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages, ((EFI_MEMORY_DESCRIPTOR*)Walker)->Attribute);\r
-              LoadCodePages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
-              TotalPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
+              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiLoaderCode, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute);\r
+              LoadCodePages += Walker->NumberOfPages;\r
+              TotalPages += Walker->NumberOfPages;\r
               break;\r
             case EfiLoaderData:\r
-              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiLoaderData, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart+MultU64x64(SIZE_4KB,((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages)-1, ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages, ((EFI_MEMORY_DESCRIPTOR*)Walker)->Attribute);\r
-              LoadDataPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
-              TotalPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
+              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiLoaderData, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute);\r
+              LoadDataPages += Walker->NumberOfPages;\r
+              TotalPages += Walker->NumberOfPages;\r
               break;\r
             case EfiBootServicesCode:\r
-              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiBootServicesCodeShort:NameEfiBootServicesCode, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart+MultU64x64(SIZE_4KB,((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages)-1, ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages, ((EFI_MEMORY_DESCRIPTOR*)Walker)->Attribute);\r
-              BSCodePages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
-              TotalPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
+              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiBootServicesCodeShort:NameEfiBootServicesCode, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute);\r
+              BSCodePages += Walker->NumberOfPages;\r
+              TotalPages += Walker->NumberOfPages;\r
               break;\r
             case EfiBootServicesData:\r
-              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiBootServicesDataShort:NameEfiBootServicesData, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart+MultU64x64(SIZE_4KB,((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages)-1, ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages, ((EFI_MEMORY_DESCRIPTOR*)Walker)->Attribute);\r
-              BSDataPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
-              TotalPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
+              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiBootServicesDataShort:NameEfiBootServicesData, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute);\r
+              BSDataPages += Walker->NumberOfPages;\r
+              TotalPages += Walker->NumberOfPages;\r
               break;\r
             case EfiRuntimeServicesCode:\r
-              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiRuntimeServicesCodeShort:NameEfiRuntimeServicesCode, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart+MultU64x64(SIZE_4KB,((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages)-1, ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages, ((EFI_MEMORY_DESCRIPTOR*)Walker)->Attribute);\r
-              RTCodePages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
-              TotalPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
+              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiRuntimeServicesCodeShort:NameEfiRuntimeServicesCode, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute);\r
+              RTCodePages += Walker->NumberOfPages;\r
+              TotalPages += Walker->NumberOfPages;\r
               break;\r
             case EfiRuntimeServicesData:\r
-              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiRuntimeServicesDataShort:NameEfiRuntimeServicesData, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart+MultU64x64(SIZE_4KB,((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages)-1, ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages, ((EFI_MEMORY_DESCRIPTOR*)Walker)->Attribute);\r
-              RTDataPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
-              TotalPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
+              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiRuntimeServicesDataShort:NameEfiRuntimeServicesData, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute);\r
+              RTDataPages += Walker->NumberOfPages;\r
+              TotalPages += Walker->NumberOfPages;\r
               break;\r
             case EfiConventionalMemory:\r
-              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiConventionalMemory, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart+MultU64x64(SIZE_4KB,((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages)-1, ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages, ((EFI_MEMORY_DESCRIPTOR*)Walker)->Attribute);\r
-              AvailPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
-              TotalPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
+              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiConventionalMemory, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute);\r
+              AvailPages += Walker->NumberOfPages;\r
+              TotalPages += Walker->NumberOfPages;\r
               break;\r
             case EfiPersistentMemory:\r
-              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiPersistentMemory, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart+MultU64x64(SIZE_4KB,((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages)-1, ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages, ((EFI_MEMORY_DESCRIPTOR*)Walker)->Attribute);\r
-              AvailPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
-              TotalPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
+              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiPersistentMemory, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute);\r
+              PersistentPages += Walker->NumberOfPages;\r
+              TotalPages      += Walker->NumberOfPages;\r
               break;\r
             case EfiUnusableMemory:\r
-              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiUnusableMemoryShort:NameEfiUnusableMemory, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart+MultU64x64(SIZE_4KB,((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages)-1, ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages, ((EFI_MEMORY_DESCRIPTOR*)Walker)->Attribute);\r
-              UnusableMemoryPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
+              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiUnusableMemoryShort:NameEfiUnusableMemory, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute);\r
+              UnusableMemoryPages += Walker->NumberOfPages;\r
               break;\r
             case EfiACPIReclaimMemory:\r
-              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiACPIReclaimMemoryShort:NameEfiACPIReclaimMemory, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart+MultU64x64(SIZE_4KB,((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages)-1, ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages, ((EFI_MEMORY_DESCRIPTOR*)Walker)->Attribute);\r
-              TotalPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
-              AcpiReclaimPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
+              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiACPIReclaimMemoryShort:NameEfiACPIReclaimMemory, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute);\r
+              TotalPages += Walker->NumberOfPages;\r
+              AcpiReclaimPages += Walker->NumberOfPages;\r
               break;\r
             case EfiACPIMemoryNVS:\r
-              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiACPIMemoryNVSShort:NameEfiACPIMemoryNVS, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart+MultU64x64(SIZE_4KB,((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages)-1, ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages, ((EFI_MEMORY_DESCRIPTOR*)Walker)->Attribute);\r
-              TotalPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
-              AcpiNvsPages    += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
+              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiACPIMemoryNVSShort:NameEfiACPIMemoryNVS, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute);\r
+              TotalPages += Walker->NumberOfPages;\r
+              AcpiNvsPages    += Walker->NumberOfPages;\r
               break;\r
             case EfiMemoryMappedIO:\r
-              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiMemoryMappedIOShort:NameEfiMemoryMappedIO, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart+MultU64x64(SIZE_4KB,((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages)-1, ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages, ((EFI_MEMORY_DESCRIPTOR*)Walker)->Attribute);\r
-              MmioSpacePages  += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
+              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiMemoryMappedIOShort:NameEfiMemoryMappedIO, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute);\r
+              MmioSpacePages  += Walker->NumberOfPages;\r
               break;\r
             case EfiMemoryMappedIOPortSpace:\r
-              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiMemoryMappedIOPortSpaceShort:NameEfiMemoryMappedIOPortSpace, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart+MultU64x64(SIZE_4KB,((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages)-1, ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages, ((EFI_MEMORY_DESCRIPTOR*)Walker)->Attribute);\r
-              MmioPortPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
+              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiMemoryMappedIOPortSpaceShort:NameEfiMemoryMappedIOPortSpace, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute);\r
+              MmioPortPages += Walker->NumberOfPages;\r
               break;\r
             case EfiPalCode:\r
-              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiPalCode, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart, ((EFI_MEMORY_DESCRIPTOR*)Walker)->PhysicalStart+MultU64x64(SIZE_4KB,((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages)-1, ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages, ((EFI_MEMORY_DESCRIPTOR*)Walker)->Attribute);\r
-              TotalPages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
-              PalCodePages += ((EFI_MEMORY_DESCRIPTOR*)Walker)->NumberOfPages;\r
+              ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiPalCode, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute);\r
+              TotalPages += Walker->NumberOfPages;\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
@@ -261,6 +336,7 @@ ShellCommandRunMemMap (
         MmioSpacePagesSize      = MultU64x64(SIZE_4KB,MmioSpacePages);\r
         MmioPortPagesSize       = MultU64x64(SIZE_4KB,MmioPortPages);\r
         PalCodePagesSize        = MultU64x64(SIZE_4KB,PalCodePages);\r
+        PersistentPagesSize     = MultU64x64(SIZE_4KB,PersistentPages);\r
         UnusableMemoryPagesSize = MultU64x64(SIZE_4KB,UnusableMemoryPages);\r
         if (!Sfo) {\r
           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MEMMAP_LIST_SUMM), gShellDebug1HiiHandle,\r
@@ -277,6 +353,20 @@ ShellCommandRunMemMap (
             MmioPortPages, MmioPortPagesSize,\r
             PalCodePages, PalCodePagesSize,\r
             AvailPages, AvailPagesSize,\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
@@ -295,7 +385,8 @@ ShellCommandRunMemMap (
             UnusableMemoryPagesSize,\r
             AcpiReclaimPagesSize,\r
             AcpiNvsPagesSize,\r
-            PalCodePagesSize\r
+            PalCodePagesSize,\r
+            PersistentPagesSize\r
            );\r
         }\r
       }\r
@@ -303,8 +394,15 @@ ShellCommandRunMemMap (
     ShellCommandLineFreeVarList (Package);\r
   }\r
 \r
-  if (Buffer != NULL) {\r
-    FreePool(Buffer);\r
+  if (Descriptors != NULL) {\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