Home | History | Annotate | Download | only in HiKeyLib
      1 /** @file
      2 *
      3 *  Copyright (c) 2014-2015, Linaro Limited. All rights reserved.
      4 *  Copyright (c) 2014-2015, Hisilicon Limited. 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 #include <Library/ArmPlatformLib.h>
     17 #include <Library/DebugLib.h>
     18 #include <Library/HobLib.h>
     19 #include <Library/PcdLib.h>
     20 #include <Library/IoLib.h>
     21 #include <Library/MemoryAllocationLib.h>
     22 
     23 #include <Hi6220.h>
     24 
     25 // The total number of descriptors, including the final "end-of-table" descriptor.
     26 #define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 12
     27 
     28 // DDR attributes
     29 #define DDR_ATTRIBUTES_CACHED           ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
     30 #define DDR_ATTRIBUTES_UNCACHED         ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
     31 
     32 #define HIKEY_EXTRA_SYSTEM_MEMORY_BASE  0x40000000
     33 #define HIKEY_EXTRA_SYSTEM_MEMORY_SIZE  0x40000000
     34 
     35 STATIC struct HiKeyReservedMemory {
     36   EFI_PHYSICAL_ADDRESS         Offset;
     37   EFI_PHYSICAL_ADDRESS         Size;
     38 } HiKeyReservedMemoryBuffer [] = {
     39   { 0x05E00000, 0x00100000 },    // MCU
     40   { 0x05F01000, 0x00001000 },    // ADB REBOOT "REASON"
     41   { 0x06DFF000, 0x00001000 },    // MAILBOX
     42   { 0x0740F000, 0x00001000 },    // MAILBOX
     43   { 0x21F00000, 0x00100000 },    // PSTORE/RAMOOPS
     44   { 0x3E000000, 0x02000000 }     // TEE OS
     45 };
     46 
     47 STATIC
     48 UINT64
     49 EFIAPI
     50 HiKeyInitMemorySize (
     51   IN VOID
     52   )
     53 {
     54   UINT32               Count, Data, MemorySize;
     55 
     56   Count = 0;
     57   while (MmioRead32 (MDDRC_AXI_BASE + AXI_REGION_MAP_OFFSET (Count)) != 0) {
     58     Count++;
     59   }
     60   Data = MmioRead32 (MDDRC_AXI_BASE + AXI_REGION_MAP_OFFSET (Count - 1));
     61   MemorySize = 16 << ((Data >> 8) & 0x7);
     62   MemorySize += Data << 24;
     63   return (UINT64) (MemorySize << 20);
     64 }
     65 
     66 /**
     67   Return the Virtual Memory Map of your platform
     68 
     69   This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform.
     70 
     71   @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-
     72                                     Virtual Memory mapping. This array must be ended by a zero-filled
     73                                     entry
     74 
     75 **/
     76 VOID
     77 ArmPlatformGetVirtualMemoryMap (
     78   IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap
     79   )
     80 {
     81   ARM_MEMORY_REGION_ATTRIBUTES  CacheAttributes;
     82   UINTN                         Index = 0, Count, ReservedTop;
     83   ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
     84   EFI_PEI_HOB_POINTERS          NextHob;
     85   EFI_RESOURCE_ATTRIBUTE_TYPE   ResourceAttributes;
     86   UINT64                        ResourceLength;
     87   EFI_PHYSICAL_ADDRESS          ResourceTop;
     88   UINT64                        MemorySize, AdditionalMemorySize;
     89 
     90   MemorySize = HiKeyInitMemorySize ();
     91 
     92   ResourceAttributes = (
     93       EFI_RESOURCE_ATTRIBUTE_PRESENT |
     94       EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
     95       EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
     96       EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
     97       EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
     98       EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
     99       EFI_RESOURCE_ATTRIBUTE_TESTED
    100   );
    101 
    102   // Create initial Base Hob for system memory.
    103   BuildResourceDescriptorHob (
    104       EFI_RESOURCE_SYSTEM_MEMORY,
    105       ResourceAttributes,
    106       PcdGet64 (PcdSystemMemoryBase),
    107       PcdGet64 (PcdSystemMemorySize)
    108   );
    109 
    110   NextHob.Raw = GetHobList ();
    111   Count = sizeof (HiKeyReservedMemoryBuffer) / sizeof (struct HiKeyReservedMemory);
    112   while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL)
    113   {
    114     if (Index >= Count)
    115       break;
    116     if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
    117         (HiKeyReservedMemoryBuffer[Index].Offset >= NextHob.ResourceDescriptor->PhysicalStart) &&
    118         ((HiKeyReservedMemoryBuffer[Index].Offset + HiKeyReservedMemoryBuffer[Index].Size) <=
    119          NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength))
    120     {
    121       ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute;
    122       ResourceLength = NextHob.ResourceDescriptor->ResourceLength;
    123       ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength;
    124       ReservedTop = HiKeyReservedMemoryBuffer[Index].Offset + HiKeyReservedMemoryBuffer[Index].Size;
    125 
    126       // Create the System Memory HOB for the reserved buffer
    127       BuildResourceDescriptorHob (EFI_RESOURCE_MEMORY_RESERVED,
    128                                   EFI_RESOURCE_ATTRIBUTE_PRESENT,
    129                                   HiKeyReservedMemoryBuffer[Index].Offset,
    130                                   HiKeyReservedMemoryBuffer[Index].Size);
    131       // Update the HOB
    132       NextHob.ResourceDescriptor->ResourceLength = HiKeyReservedMemoryBuffer[Index].Offset - NextHob.ResourceDescriptor->PhysicalStart;
    133 
    134       // If there is some memory available on the top of the reserved memory then create a HOB
    135       if (ReservedTop < ResourceTop)
    136       {
    137         BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
    138                                     ResourceAttributes,
    139                                     ReservedTop,
    140                                     ResourceTop - ReservedTop);
    141       }
    142       Index++;
    143     }
    144     NextHob.Raw = GET_NEXT_HOB (NextHob);
    145   }
    146 
    147   AdditionalMemorySize = MemorySize - PcdGet64 (PcdSystemMemorySize);
    148   if (AdditionalMemorySize >= SIZE_1GB) {
    149     // Declared the additional memory
    150     ResourceAttributes =
    151         EFI_RESOURCE_ATTRIBUTE_PRESENT |
    152         EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
    153         EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
    154         EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
    155         EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
    156         EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
    157         EFI_RESOURCE_ATTRIBUTE_TESTED;
    158 
    159     BuildResourceDescriptorHob (
    160       EFI_RESOURCE_SYSTEM_MEMORY,
    161       ResourceAttributes,
    162       HIKEY_EXTRA_SYSTEM_MEMORY_BASE,
    163       HIKEY_EXTRA_SYSTEM_MEMORY_SIZE);
    164   }
    165 
    166   ASSERT (VirtualMemoryMap != NULL);
    167 
    168   VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS));
    169   if (VirtualMemoryTable == NULL) {
    170       return;
    171   }
    172 
    173   if (FeaturePcdGet(PcdCacheEnable) == TRUE) {
    174       CacheAttributes = DDR_ATTRIBUTES_CACHED;
    175   } else {
    176       CacheAttributes = DDR_ATTRIBUTES_UNCACHED;
    177   }
    178 
    179   Index = 0;
    180 
    181   // Hi6220 SOC peripherals
    182   VirtualMemoryTable[Index].PhysicalBase    = HI6220_PERIPH_BASE;
    183   VirtualMemoryTable[Index].VirtualBase     = HI6220_PERIPH_BASE;
    184   VirtualMemoryTable[Index].Length          = HI6220_PERIPH_SZ;
    185   VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
    186 
    187   // DDR - predefined 1GB size
    188   VirtualMemoryTable[++Index].PhysicalBase  = PcdGet64 (PcdSystemMemoryBase);
    189   VirtualMemoryTable[Index].VirtualBase     = PcdGet64 (PcdSystemMemoryBase);
    190   VirtualMemoryTable[Index].Length          = PcdGet64 (PcdSystemMemorySize);
    191   VirtualMemoryTable[Index].Attributes      = CacheAttributes;
    192 
    193   // If DDR capacity is 2GB size, append a new entry to fill the gap.
    194   if (AdditionalMemorySize >= SIZE_1GB) {
    195     VirtualMemoryTable[++Index].PhysicalBase = HIKEY_EXTRA_SYSTEM_MEMORY_BASE;
    196     VirtualMemoryTable[Index].VirtualBase    = HIKEY_EXTRA_SYSTEM_MEMORY_BASE;
    197     VirtualMemoryTable[Index].Length         = HIKEY_EXTRA_SYSTEM_MEMORY_SIZE;
    198     VirtualMemoryTable[Index].Attributes     = CacheAttributes;
    199   }
    200 
    201   // End of Table
    202   VirtualMemoryTable[++Index].PhysicalBase  = 0;
    203   VirtualMemoryTable[Index].VirtualBase     = 0;
    204   VirtualMemoryTable[Index].Length          = 0;
    205   VirtualMemoryTable[Index].Attributes      = (ARM_MEMORY_REGION_ATTRIBUTES)0;
    206 
    207   ASSERT((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
    208 
    209   *VirtualMemoryMap = VirtualMemoryTable;
    210 }
    211