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
25VOID
26BuildMemoryTypeInformationHob (
27  VOID
28  );
29
30VOID
31InitMmu (
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
51EFI_STATUS
52EFIAPI
53MemoryPeim (
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