]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Library/ArmLib/AArch64/AArch64PeiLibConstructor.c
2de9c7c54ed98d4ab4052a07a407651681e661b8
[mirror_edk2.git] / ArmPkg / Library / ArmLib / AArch64 / AArch64PeiLibConstructor.c
1 #/* @file
2 #
3 # Copyright (c) 2016, Linaro Limited. All rights reserved.
4 #
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
9 #
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 #
13 #*/
14
15 #include <Base.h>
16
17 #include <Library/ArmLib.h>
18 #include <Library/CacheMaintenanceLib.h>
19 #include <Library/DebugLib.h>
20
21 //
22 // This is a hack. We define a weak symbol with external linkage, which may or
23 // may not be overridden by a non-weak alternative that is defined with a non
24 // zero value in the object that contains the MMU routines. Since static
25 // libraries are pulled in on a per-object basis, and since the MMU object will
26 // only be pulled in if any of its other symbols are referenced by the client
27 // module, we can use the value below to figure out whether the MMU routines are
28 // in use by this module, and decide whether cache maintenance of the function
29 // ArmReplaceLiveTranslationEntry () is required.
30 //
31 INT32 __attribute__((weak)) HaveMmuRoutines;
32
33 EFI_STATUS
34 EFIAPI
35 AArch64LibConstructor (
36 IN EFI_PEI_FILE_HANDLE FileHandle,
37 IN CONST EFI_PEI_SERVICES **PeiServices
38 )
39 {
40 extern UINT32 ArmReplaceLiveTranslationEntrySize;
41
42 EFI_FV_FILE_INFO FileInfo;
43 EFI_STATUS Status;
44
45 if (HaveMmuRoutines == 0) {
46 return RETURN_SUCCESS;
47 }
48
49 ASSERT (FileHandle != NULL);
50
51 Status = (*PeiServices)->FfsGetFileInfo (FileHandle, &FileInfo);
52 ASSERT_EFI_ERROR (Status);
53
54 //
55 // Some platforms do not cope very well with cache maintenance being
56 // performed on regions backed by NOR flash. Since the cache maintenance
57 // is unnecessary to begin with in that case, perform it only when not
58 // executing in place.
59 //
60 if ((UINTN)FileInfo.Buffer <= (UINTN)ArmReplaceLiveTranslationEntry &&
61 ((UINTN)FileInfo.Buffer + FileInfo.BufferSize >=
62 (UINTN)ArmReplaceLiveTranslationEntry + ArmReplaceLiveTranslationEntrySize)) {
63 DEBUG ((EFI_D_INFO, "ArmLib: skipping cache maintence on XIP PEIM\n"));
64 } else {
65 DEBUG ((EFI_D_INFO, "ArmLib: performing cache maintence on shadowed PEIM\n"));
66 //
67 // The ArmReplaceLiveTranslationEntry () helper function may be invoked
68 // with the MMU off so we have to ensure that it gets cleaned to the PoC
69 //
70 WriteBackDataCacheRange (ArmReplaceLiveTranslationEntry,
71 ArmReplaceLiveTranslationEntrySize);
72 }
73
74 return RETURN_SUCCESS;
75 }