2 SMBASE relocation for hot-plugged CPUs.
4 Copyright (c) 2020, Red Hat, Inc.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include <Base.h> // BASE_1MB
10 #include <Library/BaseMemoryLib.h> // CopyMem()
11 #include <Library/DebugLib.h> // DEBUG()
15 extern CONST UINT8 mPostSmmPen
[];
16 extern CONST UINT16 mPostSmmPenSize
;
19 Allocate a non-SMRAM reserved memory page for the Post-SMM Pen for hot-added
22 This function may only be called from the entry point function of the driver.
24 @param[out] PenAddress The address of the allocated (normal RAM) reserved
27 @param[in] BootServices Pointer to the UEFI boot services table. Used for
28 allocating the normal RAM (not SMRAM) reserved page.
30 @retval EFI_SUCCESS Allocation successful.
32 @retval EFI_BAD_BUFFER_SIZE The Post-SMM Pen template is not smaller than
35 @return Error codes propagated from underlying services.
36 DEBUG_ERROR messages have been logged. No
37 resources have been allocated.
40 SmbaseAllocatePostSmmPen (
41 OUT UINT32
*PenAddress
,
42 IN CONST EFI_BOOT_SERVICES
*BootServices
46 EFI_PHYSICAL_ADDRESS Address
;
49 // The pen code must fit in one page, and the last byte must remain free for
50 // signaling the SMM Monarch.
52 if (mPostSmmPenSize
>= EFI_PAGE_SIZE
) {
53 Status
= EFI_BAD_BUFFER_SIZE
;
54 DEBUG ((DEBUG_ERROR
, "%a: mPostSmmPenSize=%u: %r\n", __FUNCTION__
,
55 mPostSmmPenSize
, Status
));
59 Address
= BASE_1MB
- 1;
60 Status
= BootServices
->AllocatePages (AllocateMaxAddress
,
61 EfiReservedMemoryType
, 1, &Address
);
62 if (EFI_ERROR (Status
)) {
63 DEBUG ((DEBUG_ERROR
, "%a: AllocatePages(): %r\n", __FUNCTION__
, Status
));
67 DEBUG ((DEBUG_INFO
, "%a: Post-SMM Pen at 0x%Lx\n", __FUNCTION__
, Address
));
68 *PenAddress
= (UINT32
)Address
;
73 Copy the Post-SMM Pen template code into the reserved page allocated with
74 SmbaseAllocatePostSmmPen().
76 Note that this effects an "SMRAM to normal RAM" copy.
78 The SMM Monarch is supposed to call this function from the root MMI handler.
80 @param[in] PenAddress The allocation address returned by
81 SmbaseAllocatePostSmmPen().
84 SmbaseReinstallPostSmmPen (
88 CopyMem ((VOID
*)(UINTN
)PenAddress
, mPostSmmPen
, mPostSmmPenSize
);
92 Release the reserved page allocated with SmbaseAllocatePostSmmPen().
94 This function may only be called from the entry point function of the driver,
97 @param[in] PenAddress The allocation address returned by
98 SmbaseAllocatePostSmmPen().
100 @param[in] BootServices Pointer to the UEFI boot services table. Used for
101 releasing the normal RAM (not SMRAM) reserved page.
104 SmbaseReleasePostSmmPen (
105 IN UINT32 PenAddress
,
106 IN CONST EFI_BOOT_SERVICES
*BootServices
109 BootServices
->FreePages (PenAddress
, 1);