]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/CpuHotplugSmm/Smbase.c
OvmfPkg/CpuHotplugSmm: introduce Post-SMM Pen for hot-added CPUs
[mirror_edk2.git] / OvmfPkg / CpuHotplugSmm / Smbase.c
CommitLineData
63c89da2
LE
1/** @file\r
2 SMBASE relocation for hot-plugged CPUs.\r
3\r
4 Copyright (c) 2020, Red Hat, Inc.\r
5\r
6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
7**/\r
8\r
9#include <Base.h> // BASE_1MB\r
10#include <Library/BaseMemoryLib.h> // CopyMem()\r
11#include <Library/DebugLib.h> // DEBUG()\r
12\r
13#include "Smbase.h"\r
14\r
15extern CONST UINT8 mPostSmmPen[];\r
16extern CONST UINT16 mPostSmmPenSize;\r
17\r
18/**\r
19 Allocate a non-SMRAM reserved memory page for the Post-SMM Pen for hot-added\r
20 CPUs.\r
21\r
22 This function may only be called from the entry point function of the driver.\r
23\r
24 @param[out] PenAddress The address of the allocated (normal RAM) reserved\r
25 page.\r
26\r
27 @param[in] BootServices Pointer to the UEFI boot services table. Used for\r
28 allocating the normal RAM (not SMRAM) reserved page.\r
29\r
30 @retval EFI_SUCCESS Allocation successful.\r
31\r
32 @retval EFI_BAD_BUFFER_SIZE The Post-SMM Pen template is not smaller than\r
33 EFI_PAGE_SIZE.\r
34\r
35 @return Error codes propagated from underlying services.\r
36 DEBUG_ERROR messages have been logged. No\r
37 resources have been allocated.\r
38**/\r
39EFI_STATUS\r
40SmbaseAllocatePostSmmPen (\r
41 OUT UINT32 *PenAddress,\r
42 IN CONST EFI_BOOT_SERVICES *BootServices\r
43 )\r
44{\r
45 EFI_STATUS Status;\r
46 EFI_PHYSICAL_ADDRESS Address;\r
47\r
48 //\r
49 // The pen code must fit in one page, and the last byte must remain free for\r
50 // signaling the SMM Monarch.\r
51 //\r
52 if (mPostSmmPenSize >= EFI_PAGE_SIZE) {\r
53 Status = EFI_BAD_BUFFER_SIZE;\r
54 DEBUG ((DEBUG_ERROR, "%a: mPostSmmPenSize=%u: %r\n", __FUNCTION__,\r
55 mPostSmmPenSize, Status));\r
56 return Status;\r
57 }\r
58\r
59 Address = BASE_1MB - 1;\r
60 Status = BootServices->AllocatePages (AllocateMaxAddress,\r
61 EfiReservedMemoryType, 1, &Address);\r
62 if (EFI_ERROR (Status)) {\r
63 DEBUG ((DEBUG_ERROR, "%a: AllocatePages(): %r\n", __FUNCTION__, Status));\r
64 return Status;\r
65 }\r
66\r
67 DEBUG ((DEBUG_INFO, "%a: Post-SMM Pen at 0x%Lx\n", __FUNCTION__, Address));\r
68 *PenAddress = (UINT32)Address;\r
69 return EFI_SUCCESS;\r
70}\r
71\r
72/**\r
73 Copy the Post-SMM Pen template code into the reserved page allocated with\r
74 SmbaseAllocatePostSmmPen().\r
75\r
76 Note that this effects an "SMRAM to normal RAM" copy.\r
77\r
78 The SMM Monarch is supposed to call this function from the root MMI handler.\r
79\r
80 @param[in] PenAddress The allocation address returned by\r
81 SmbaseAllocatePostSmmPen().\r
82**/\r
83VOID\r
84SmbaseReinstallPostSmmPen (\r
85 IN UINT32 PenAddress\r
86 )\r
87{\r
88 CopyMem ((VOID *)(UINTN)PenAddress, mPostSmmPen, mPostSmmPenSize);\r
89}\r
90\r
91/**\r
92 Release the reserved page allocated with SmbaseAllocatePostSmmPen().\r
93\r
94 This function may only be called from the entry point function of the driver,\r
95 on the error path.\r
96\r
97 @param[in] PenAddress The allocation address returned by\r
98 SmbaseAllocatePostSmmPen().\r
99\r
100 @param[in] BootServices Pointer to the UEFI boot services table. Used for\r
101 releasing the normal RAM (not SMRAM) reserved page.\r
102**/\r
103VOID\r
104SmbaseReleasePostSmmPen (\r
105 IN UINT32 PenAddress,\r
106 IN CONST EFI_BOOT_SERVICES *BootServices\r
107 )\r
108{\r
109 BootServices->FreePages (PenAddress, 1);\r
110}\r