Home | History | Annotate | Download | only in LinuxLoader
      1 /** @file
      2 *
      3 *  Copyright (c) 2011-2015, ARM Limited. All rights reserved.
      4 *
      5 *  This program and the accompanying materials
      6 *  are licensed and made available under the terms and conditions of the BSD License
      7 *  which accompanies this distribution.  The full text of the license may be found at
      8 *  http://opensource.org/licenses/bsd-license.php
      9 *
     10 *  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 *  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 *
     13 **/
     14 
     15 #include <PiDxe.h>
     16 #include <Library/HobLib.h>
     17 #include <Library/TimerLib.h>
     18 #include <Library/SerialPortLib.h>
     19 
     20 #include "LinuxLoader.h"
     21 
     22 STATIC CONST CHAR8 *mTokenList[] = {
     23   /*"SEC",*/
     24   "PEI",
     25   "DXE",
     26   "BDS",
     27   NULL
     28 };
     29 
     30 VOID
     31 PrintPerformance (
     32   VOID
     33   )
     34 {
     35   UINTN       Key;
     36   CONST VOID  *Handle;
     37   CONST CHAR8 *Token, *Module;
     38   UINT64      Start, Stop, TimeStamp;
     39   UINT64      Delta, TicksPerSecond, Milliseconds;
     40   UINTN       Index;
     41   CHAR8       Buffer[100];
     42   UINTN       CharCount;
     43   BOOLEAN     CountUp;
     44 
     45   TicksPerSecond = GetPerformanceCounterProperties (&Start, &Stop);
     46   if (Start < Stop) {
     47     CountUp = TRUE;
     48   } else {
     49     CountUp = FALSE;
     50   }
     51 
     52   TimeStamp = 0;
     53   Key       = 0;
     54   do {
     55     Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop);
     56     if (Key != 0) {
     57       for (Index = 0; mTokenList[Index] != NULL; Index++) {
     58         if (AsciiStriCmp (mTokenList[Index], Token) == 0) {
     59           Delta = CountUp ? (Stop - Start) : (Start - Stop);
     60           TimeStamp += Delta;
     61           Milliseconds = DivU64x64Remainder (MultU64x32 (Delta, 1000), TicksPerSecond, NULL);
     62           CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "%6a %6ld ms\n", Token, Milliseconds);
     63           SerialPortWrite ((UINT8 *) Buffer, CharCount);
     64           break;
     65         }
     66       }
     67     }
     68   } while (Key != 0);
     69 
     70   CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "Total Time = %ld ms\n\n",
     71       DivU64x64Remainder (MultU64x32 (TimeStamp, 1000), TicksPerSecond, NULL));
     72   SerialPortWrite ((UINT8 *) Buffer, CharCount);
     73 }
     74 
     75 STATIC
     76 EFI_STATUS
     77 InsertSystemMemoryResources (
     78   LIST_ENTRY *ResourceList,
     79   EFI_HOB_RESOURCE_DESCRIPTOR *ResHob
     80   )
     81 {
     82   SYSTEM_MEMORY_RESOURCE  *NewResource;
     83   LIST_ENTRY              *Link;
     84   LIST_ENTRY              *NextLink;
     85   LIST_ENTRY              AttachedResources;
     86   SYSTEM_MEMORY_RESOURCE  *Resource;
     87   EFI_PHYSICAL_ADDRESS    NewResourceEnd;
     88 
     89   if (IsListEmpty (ResourceList)) {
     90     NewResource = AllocateZeroPool (sizeof (SYSTEM_MEMORY_RESOURCE));
     91     NewResource->PhysicalStart = ResHob->PhysicalStart;
     92     NewResource->ResourceLength = ResHob->ResourceLength;
     93     InsertTailList (ResourceList, &NewResource->Link);
     94     return EFI_SUCCESS;
     95   }
     96 
     97   InitializeListHead (&AttachedResources);
     98 
     99   Link = ResourceList->ForwardLink;
    100   ASSERT (Link != NULL);
    101   while (Link != ResourceList) {
    102     Resource = (SYSTEM_MEMORY_RESOURCE*)Link;
    103 
    104     // Sanity Check. The resources should not overlapped.
    105     ASSERT (!((ResHob->PhysicalStart >= Resource->PhysicalStart) && (ResHob->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))));
    106     ASSERT (!((ResHob->PhysicalStart + ResHob->ResourceLength - 1 >= Resource->PhysicalStart) &&
    107         ((ResHob->PhysicalStart + ResHob->ResourceLength - 1) < (Resource->PhysicalStart + Resource->ResourceLength))));
    108 
    109     // The new resource is attached after this resource descriptor
    110     if (ResHob->PhysicalStart == Resource->PhysicalStart + Resource->ResourceLength) {
    111       Resource->ResourceLength =  Resource->ResourceLength + ResHob->ResourceLength;
    112 
    113       NextLink = RemoveEntryList (&Resource->Link);
    114       InsertTailList (&AttachedResources, &Resource->Link);
    115       Link = NextLink;
    116     }
    117     // The new resource is attached before this resource descriptor
    118     else if (ResHob->PhysicalStart + ResHob->ResourceLength == Resource->PhysicalStart) {
    119       Resource->PhysicalStart = ResHob->PhysicalStart;
    120       Resource->ResourceLength =  Resource->ResourceLength + ResHob->ResourceLength;
    121 
    122       NextLink = RemoveEntryList (&Resource->Link);
    123       InsertTailList (&AttachedResources, &Resource->Link);
    124       Link = NextLink;
    125     } else {
    126       Link = Link->ForwardLink;
    127     }
    128   }
    129 
    130   if (!IsListEmpty (&AttachedResources)) {
    131     // See if we can merge the attached resource with other resources
    132 
    133     NewResource = (SYSTEM_MEMORY_RESOURCE*)GetFirstNode (&AttachedResources);
    134     Link = RemoveEntryList (&NewResource->Link);
    135     while (!IsListEmpty (&AttachedResources)) {
    136       // Merge resources
    137       Resource = (SYSTEM_MEMORY_RESOURCE*)Link;
    138 
    139       // Ensure they overlap each other
    140       ASSERT (
    141           ((NewResource->PhysicalStart >= Resource->PhysicalStart) && (NewResource->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))) ||
    142           (((NewResource->PhysicalStart + NewResource->ResourceLength) >= Resource->PhysicalStart) && ((NewResource->PhysicalStart + NewResource->ResourceLength) < (Resource->PhysicalStart + Resource->ResourceLength)))
    143       );
    144 
    145       NewResourceEnd = MAX (NewResource->PhysicalStart + NewResource->ResourceLength, Resource->PhysicalStart + Resource->ResourceLength);
    146       NewResource->PhysicalStart = MIN (NewResource->PhysicalStart, Resource->PhysicalStart);
    147       NewResource->ResourceLength = NewResourceEnd - NewResource->PhysicalStart;
    148 
    149       Link = RemoveEntryList (Link);
    150     }
    151   } else {
    152     // None of the Resource of the list is attached to this ResHob. Create a new entry for it
    153     NewResource = AllocateZeroPool (sizeof (SYSTEM_MEMORY_RESOURCE));
    154     NewResource->PhysicalStart = ResHob->PhysicalStart;
    155     NewResource->ResourceLength = ResHob->ResourceLength;
    156   }
    157   InsertTailList (ResourceList, &NewResource->Link);
    158   return EFI_SUCCESS;
    159 }
    160 
    161 EFI_STATUS
    162 GetSystemMemoryResources (
    163   IN  LIST_ENTRY *ResourceList
    164   )
    165 {
    166   EFI_HOB_RESOURCE_DESCRIPTOR *ResHob;
    167 
    168   InitializeListHead (ResourceList);
    169 
    170   // Find the first System Memory Resource Descriptor
    171   ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
    172   while ((ResHob != NULL) && (ResHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY)) {
    173     ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, (VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
    174   }
    175 
    176   // Did not find any
    177   if (ResHob == NULL) {
    178     return EFI_NOT_FOUND;
    179   } else {
    180     InsertSystemMemoryResources (ResourceList, ResHob);
    181   }
    182 
    183   ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, (VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
    184   while (ResHob != NULL) {
    185     if (ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
    186       InsertSystemMemoryResources (ResourceList, ResHob);
    187     }
    188     ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, (VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
    189   }
    190 
    191   return EFI_SUCCESS;
    192 }
    193