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