]>
Commit | Line | Data |
---|---|---|
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 | |
15 | extern CONST UINT8 mPostSmmPen[];\r | |
16 | extern 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 | |
39 | EFI_STATUS\r | |
40 | SmbaseAllocatePostSmmPen (\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 | |
83 | VOID\r | |
84 | SmbaseReinstallPostSmmPen (\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 | |
103 | VOID\r | |
104 | SmbaseReleasePostSmmPen (\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 |