1 /** @file
2 *
3 *  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
4 *  Copyright (c) 2014, Linaro 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 <PiPei.h>
17 
18 #include <Library/ArmPlatformLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/HobLib.h>
21 #include <Library/MemoryAllocationLib.h>
22 #include <Library/PcdLib.h>
23 #include <Library/CacheMaintenanceLib.h>
24 
25 VOID
26 BuildMemoryTypeInformationHob (
27   VOID
28   );
29 
30 VOID
InitMmu(VOID)31 InitMmu (
32   VOID
33   )
34 {
35   ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable;
36   VOID                          *TranslationTableBase;
37   UINTN                         TranslationTableSize;
38   RETURN_STATUS                 Status;
39 
40   // Get Virtual Memory Map from the Platform Library
41   ArmPlatformGetVirtualMemoryMap (&MemoryTable);
42 
43   //Note: Because we called PeiServicesInstallPeiMemory() before to call InitMmu() the MMU Page Table resides in
44   //      DRAM (even at the top of DRAM as it is the first permanent memory allocation)
45   Status = ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize);
46   if (EFI_ERROR (Status)) {
47     DEBUG ((EFI_D_ERROR, "Error: Failed to enable MMU\n"));
48   }
49 }
50 
51 EFI_STATUS
52 EFIAPI
MemoryPeim(IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,IN UINT64 UefiMemorySize)53 MemoryPeim (
54   IN EFI_PHYSICAL_ADDRESS               UefiMemoryBase,
55   IN UINT64                             UefiMemorySize
56   )
57 {
58   EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes;
59   UINT64                      SystemMemoryTop;
60 
61   // Ensure PcdSystemMemorySize has been set
62   ASSERT (PcdGet64 (PcdSystemMemorySize) != 0);
63 
64   //
65   // Now, the permanent memory has been installed, we can call AllocatePages()
66   //
67   ResourceAttributes = (
68       EFI_RESOURCE_ATTRIBUTE_PRESENT |
69       EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
70       EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
71       EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
72       EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
73       EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
74       EFI_RESOURCE_ATTRIBUTE_TESTED
75   );
76 
77   SystemMemoryTop = PcdGet64 (PcdSystemMemoryBase) +
78                     PcdGet64 (PcdSystemMemorySize);
79 
80   if (SystemMemoryTop - 1 > MAX_ADDRESS) {
81     BuildResourceDescriptorHob (
82         EFI_RESOURCE_SYSTEM_MEMORY,
83         ResourceAttributes,
84         PcdGet64 (PcdSystemMemoryBase),
85         (UINT64)MAX_ADDRESS - PcdGet64 (PcdSystemMemoryBase) + 1
86         );
87     BuildResourceDescriptorHob (
88         EFI_RESOURCE_SYSTEM_MEMORY,
89         ResourceAttributes,
90         (UINT64)MAX_ADDRESS + 1,
91         SystemMemoryTop - MAX_ADDRESS - 1
92         );
93   } else {
94     BuildResourceDescriptorHob (
95         EFI_RESOURCE_SYSTEM_MEMORY,
96         ResourceAttributes,
97         PcdGet64 (PcdSystemMemoryBase),
98         PcdGet64 (PcdSystemMemorySize)
99         );
100   }
101 
102   //
103   // When running under virtualization, the PI/UEFI memory region may be
104   // clean but not invalidated in system caches or in lower level caches
105   // on other CPUs. So invalidate the region by virtual address, to ensure
106   // that the contents we put there with the caches and MMU off will still
107   // be visible after turning them on.
108   //
109   InvalidateDataCacheRange ((VOID*)(UINTN)UefiMemoryBase, UefiMemorySize);
110 
111   // Build Memory Allocation Hob
112   InitMmu ();
113 
114   if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
115     // Optional feature that helps prevent EFI memory map fragmentation.
116     BuildMemoryTypeInformationHob ();
117   }
118 
119   return EFI_SUCCESS;
120 }
121