]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/PlatformPei/ClearCache.c
7d15fd925c3cf5c8cc8a064d418bc835534f01ac
[mirror_edk2.git] / OvmfPkg / PlatformPei / ClearCache.c
1 /**@file
2 Install a callback to clear cache on all processors.
3 This is for conformance with the TCG "Platform Reset Attack Mitigation
4 Specification". Because clearing the CPU caches at boot doesn't impact
5 performance significantly, do it unconditionally, for simplicity's
6 sake.
7
8 Copyright (C) 2018, Red Hat, Inc.
9
10 This program and the accompanying materials are licensed and made available
11 under the terms and conditions of the BSD License which accompanies this
12 distribution. The full text of the license may be found at
13 http://opensource.org/licenses/bsd-license.php
14
15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
16 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 **/
18
19 #include <Library/CacheMaintenanceLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/PeiServicesLib.h>
22 #include <Ppi/MpServices.h>
23
24 #include "Platform.h"
25
26 /**
27 Invalidate data & instruction caches.
28 All APs execute this function in parallel. The BSP executes the function
29 separately.
30
31 @param[in,out] WorkSpace Pointer to the input/output argument workspace
32 shared by all processors.
33 **/
34 STATIC
35 VOID
36 EFIAPI
37 ClearCache (
38 IN OUT VOID *WorkSpace
39 )
40 {
41 WriteBackInvalidateDataCache ();
42 InvalidateInstructionCache ();
43 }
44
45 /**
46 Notification function called when EFI_PEI_MP_SERVICES_PPI becomes available.
47
48 @param[in] PeiServices Indirect reference to the PEI Services Table.
49 @param[in] NotifyDescriptor Address of the notification descriptor data
50 structure.
51 @param[in] Ppi Address of the PPI that was installed.
52
53 @return Status of the notification. The status code returned from this
54 function is ignored.
55 **/
56 STATIC
57 EFI_STATUS
58 EFIAPI
59 ClearCacheOnMpServicesAvailable (
60 IN EFI_PEI_SERVICES **PeiServices,
61 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
62 IN VOID *Ppi
63 )
64 {
65 EFI_PEI_MP_SERVICES_PPI *MpServices;
66 EFI_STATUS Status;
67
68 DEBUG ((DEBUG_INFO, "%a: %a\n", gEfiCallerBaseName, __FUNCTION__));
69
70 //
71 // Clear cache on all the APs in parallel.
72 //
73 MpServices = Ppi;
74 Status = MpServices->StartupAllAPs (
75 (CONST EFI_PEI_SERVICES **)PeiServices,
76 MpServices,
77 ClearCache, // Procedure
78 FALSE, // SingleThread
79 0, // TimeoutInMicroSeconds: inf.
80 NULL // ProcedureArgument
81 );
82 if (EFI_ERROR (Status) && Status != EFI_NOT_STARTED) {
83 DEBUG ((DEBUG_ERROR, "%a: StartupAllAps(): %r\n", __FUNCTION__, Status));
84 return Status;
85 }
86
87 //
88 // Now clear cache on the BSP too.
89 //
90 ClearCache (NULL);
91 return EFI_SUCCESS;
92 }
93
94 //
95 // Notification object for registering the callback, for when
96 // EFI_PEI_MP_SERVICES_PPI becomes available.
97 //
98 STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify = {
99 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | // Flags
100 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
101 &gEfiPeiMpServicesPpiGuid, // Guid
102 ClearCacheOnMpServicesAvailable // Notify
103 };
104
105 VOID
106 InstallClearCacheCallback (
107 VOID
108 )
109 {
110 EFI_STATUS Status;
111
112 Status = PeiServicesNotifyPpi (&mMpServicesNotify);
113 if (EFI_ERROR (Status)) {
114 DEBUG ((DEBUG_ERROR, "%a: failed to set up MP Services callback: %r\n",
115 __FUNCTION__, Status));
116 }
117 }