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