2 Entry point to the Standalone MM Foundation when initialized during the SEC
5 Copyright (c) 2017 - 2018, ARM Ltd. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include <Library/AArch64/StandaloneMmCoreEntryPoint.h>
22 #include <Guid/MmramMemoryReserve.h>
23 #include <Guid/MpInformation.h>
25 #include <Library/ArmMmuLib.h>
26 #include <Library/ArmSvcLib.h>
27 #include <Library/DebugLib.h>
28 #include <Library/HobLib.h>
29 #include <Library/BaseLib.h>
30 #include <Library/BaseMemoryLib.h>
31 #include <Library/SerialPortLib.h>
33 #include <IndustryStandard/ArmStdSmc.h>
34 #include <IndustryStandard/ArmMmSvc.h>
36 #define SPM_MAJOR_VER_MASK 0xFFFF0000
37 #define SPM_MINOR_VER_MASK 0x0000FFFF
38 #define SPM_MAJOR_VER_SHIFT 16
40 CONST UINT32 SPM_MAJOR_VER
= 0;
41 CONST UINT32 SPM_MINOR_VER
= 1;
43 CONST UINT8 BOOT_PAYLOAD_VERSION
= 1;
45 PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint
= NULL
;
48 Retrieve a pointer to and print the boot information passed by privileged
51 @param SharedBufAddress The pointer memory shared with privileged firmware
54 EFI_SECURE_PARTITION_BOOT_INFO
*
55 GetAndPrintBootinformation (
56 IN VOID
*SharedBufAddress
59 EFI_SECURE_PARTITION_BOOT_INFO
*PayloadBootInfo
;
60 EFI_SECURE_PARTITION_CPU_INFO
*PayloadCpuInfo
;
63 PayloadBootInfo
= (EFI_SECURE_PARTITION_BOOT_INFO
*) SharedBufAddress
;
65 if (PayloadBootInfo
== NULL
) {
66 DEBUG ((DEBUG_ERROR
, "PayloadBootInfo NULL\n"));
70 if (PayloadBootInfo
->Header
.Version
!= BOOT_PAYLOAD_VERSION
) {
71 DEBUG ((DEBUG_ERROR
, "Boot Information Version Mismatch. Current=0x%x, Expected=0x%x.\n",
72 PayloadBootInfo
->Header
.Version
, BOOT_PAYLOAD_VERSION
));
76 DEBUG ((DEBUG_INFO
, "NumSpMemRegions - 0x%x\n", PayloadBootInfo
->NumSpMemRegions
));
77 DEBUG ((DEBUG_INFO
, "SpMemBase - 0x%lx\n", PayloadBootInfo
->SpMemBase
));
78 DEBUG ((DEBUG_INFO
, "SpMemLimit - 0x%lx\n", PayloadBootInfo
->SpMemLimit
));
79 DEBUG ((DEBUG_INFO
, "SpImageBase - 0x%lx\n", PayloadBootInfo
->SpImageBase
));
80 DEBUG ((DEBUG_INFO
, "SpStackBase - 0x%lx\n", PayloadBootInfo
->SpStackBase
));
81 DEBUG ((DEBUG_INFO
, "SpHeapBase - 0x%lx\n", PayloadBootInfo
->SpHeapBase
));
82 DEBUG ((DEBUG_INFO
, "SpNsCommBufBase - 0x%lx\n", PayloadBootInfo
->SpNsCommBufBase
));
83 DEBUG ((DEBUG_INFO
, "SpSharedBufBase - 0x%lx\n", PayloadBootInfo
->SpSharedBufBase
));
85 DEBUG ((DEBUG_INFO
, "SpImageSize - 0x%x\n", PayloadBootInfo
->SpImageSize
));
86 DEBUG ((DEBUG_INFO
, "SpPcpuStackSize - 0x%x\n", PayloadBootInfo
->SpPcpuStackSize
));
87 DEBUG ((DEBUG_INFO
, "SpHeapSize - 0x%x\n", PayloadBootInfo
->SpHeapSize
));
88 DEBUG ((DEBUG_INFO
, "SpNsCommBufSize - 0x%x\n", PayloadBootInfo
->SpNsCommBufSize
));
89 DEBUG ((DEBUG_INFO
, "SpPcpuSharedBufSize - 0x%x\n", PayloadBootInfo
->SpPcpuSharedBufSize
));
91 DEBUG ((DEBUG_INFO
, "NumCpus - 0x%x\n", PayloadBootInfo
->NumCpus
));
92 DEBUG ((DEBUG_INFO
, "CpuInfo - 0x%p\n", PayloadBootInfo
->CpuInfo
));
94 PayloadCpuInfo
= (EFI_SECURE_PARTITION_CPU_INFO
*) PayloadBootInfo
->CpuInfo
;
96 if (PayloadCpuInfo
== NULL
) {
97 DEBUG ((DEBUG_ERROR
, "PayloadCpuInfo NULL\n"));
101 for (Index
= 0; Index
< PayloadBootInfo
->NumCpus
; Index
++) {
102 DEBUG ((DEBUG_INFO
, "Mpidr - 0x%lx\n", PayloadCpuInfo
[Index
].Mpidr
));
103 DEBUG ((DEBUG_INFO
, "LinearId - 0x%x\n", PayloadCpuInfo
[Index
].LinearId
));
104 DEBUG ((DEBUG_INFO
, "Flags - 0x%x\n", PayloadCpuInfo
[Index
].Flags
));
107 return PayloadBootInfo
;
113 IN ARM_SVC_ARGS
*EventCompleteSvcArgs
120 ArmCallSvc (EventCompleteSvcArgs
);
122 DEBUG ((DEBUG_INFO
, "Received delegated event\n"));
123 DEBUG ((DEBUG_INFO
, "X0 : 0x%x\n", (UINT32
) EventCompleteSvcArgs
->Arg0
));
124 DEBUG ((DEBUG_INFO
, "X1 : 0x%x\n", (UINT32
) EventCompleteSvcArgs
->Arg1
));
125 DEBUG ((DEBUG_INFO
, "X2 : 0x%x\n", (UINT32
) EventCompleteSvcArgs
->Arg2
));
126 DEBUG ((DEBUG_INFO
, "X3 : 0x%x\n", (UINT32
) EventCompleteSvcArgs
->Arg3
));
128 Status
= CpuDriverEntryPoint (
129 EventCompleteSvcArgs
->Arg0
,
130 EventCompleteSvcArgs
->Arg3
,
131 EventCompleteSvcArgs
->Arg1
134 if (EFI_ERROR (Status
)) {
135 DEBUG ((DEBUG_ERROR
, "Failed delegated event 0x%x, Status 0x%x\n",
136 EventCompleteSvcArgs
->Arg0
, Status
));
141 SvcStatus
= ARM_SVC_SPM_RET_SUCCESS
;
143 case EFI_INVALID_PARAMETER
:
144 SvcStatus
= ARM_SVC_SPM_RET_INVALID_PARAMS
;
146 case EFI_ACCESS_DENIED
:
147 SvcStatus
= ARM_SVC_SPM_RET_DENIED
;
149 case EFI_OUT_OF_RESOURCES
:
150 SvcStatus
= ARM_SVC_SPM_RET_NO_MEMORY
;
152 case EFI_UNSUPPORTED
:
153 SvcStatus
= ARM_SVC_SPM_RET_NOT_SUPPORTED
;
156 SvcStatus
= ARM_SVC_SPM_RET_NOT_SUPPORTED
;
160 EventCompleteSvcArgs
->Arg0
= ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH64
;
161 EventCompleteSvcArgs
->Arg1
= SvcStatus
;
170 UINT16 SpmMajorVersion
;
171 UINT16 SpmMinorVersion
;
173 ARM_SVC_ARGS SpmVersionArgs
;
175 SpmVersionArgs
.Arg0
= ARM_SVC_ID_SPM_VERSION_AARCH32
;
177 ArmCallSvc (&SpmVersionArgs
);
179 SpmVersion
= SpmVersionArgs
.Arg0
;
181 SpmMajorVersion
= ((SpmVersion
& SPM_MAJOR_VER_MASK
) >> SPM_MAJOR_VER_SHIFT
);
182 SpmMinorVersion
= ((SpmVersion
& SPM_MINOR_VER_MASK
) >> 0);
184 // Different major revision values indicate possibly incompatible functions.
185 // For two revisions, A and B, for which the major revision values are
186 // identical, if the minor revision value of revision B is greater than
187 // the minor revision value of revision A, then every function in
188 // revision A must work in a compatible way with revision B.
189 // However, it is possible for revision B to have a higher
190 // function count than revision A.
191 if ((SpmMajorVersion
== SPM_MAJOR_VER
) &&
192 (SpmMinorVersion
>= SPM_MINOR_VER
))
194 DEBUG ((DEBUG_INFO
, "SPM Version: Major=0x%x, Minor=0x%x\n",
195 SpmMajorVersion
, SpmMinorVersion
));
196 Status
= EFI_SUCCESS
;
200 DEBUG ((DEBUG_INFO
, "Incompatible SPM Versions.\n Current Version: Major=0x%x, Minor=0x%x.\n Expected: Major=0x%x, Minor>=0x%x.\n",
201 SpmMajorVersion
, SpmMinorVersion
, SPM_MAJOR_VER
, SPM_MINOR_VER
));
202 Status
= EFI_UNSUPPORTED
;
209 The entry point of Standalone MM Foundation.
211 @param SharedBufAddress Pointer to the Buffer between SPM and SP.
219 IN VOID
*SharedBufAddress
,
220 IN UINT64 SharedBufSize
,
225 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
226 EFI_SECURE_PARTITION_BOOT_INFO
*PayloadBootInfo
;
227 ARM_SVC_ARGS InitMmFoundationSvcArgs
;
229 UINT32 SectionHeaderOffset
;
230 UINT16 NumberOfSections
;
235 // Get Secure Partition Manager Version Information
236 Status
= GetSpmVersion ();
237 if (EFI_ERROR (Status
)) {
241 PayloadBootInfo
= GetAndPrintBootinformation (SharedBufAddress
);
242 if (PayloadBootInfo
== NULL
) {
243 Status
= EFI_UNSUPPORTED
;
247 // Locate PE/COFF File information for the Standalone MM core module
248 Status
= LocateStandaloneMmCorePeCoffData (
249 (EFI_FIRMWARE_VOLUME_HEADER
*) PayloadBootInfo
->SpImageBase
,
254 if (EFI_ERROR (Status
)) {
258 // Obtain the PE/COFF Section information for the Standalone MM core module
259 Status
= GetStandaloneMmCorePeCoffSections (
262 &SectionHeaderOffset
,
266 if (EFI_ERROR (Status
)) {
270 // Update the memory access permissions of individual sections in the
271 // Standalone MM core module
272 Status
= UpdateMmFoundationPeCoffPermissions (
276 ArmSetMemoryRegionNoExec
,
277 ArmSetMemoryRegionReadOnly
,
278 ArmClearMemoryRegionReadOnly
281 if (EFI_ERROR (Status
)) {
286 // Create Hoblist based upon boot information passed by privileged software
288 HobStart
= CreateHobListFromBootInfo (&CpuDriverEntryPoint
, PayloadBootInfo
);
291 // Call the MM Core entry point
293 ProcessModuleEntryPointList (HobStart
);
295 DEBUG ((DEBUG_INFO
, "Shared Cpu Driver EP 0x%lx\n", (UINT64
) CpuDriverEntryPoint
));
298 ZeroMem (&InitMmFoundationSvcArgs
, sizeof(InitMmFoundationSvcArgs
));
299 InitMmFoundationSvcArgs
.Arg0
= ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH64
;
300 InitMmFoundationSvcArgs
.Arg1
= Status
;
301 DelegatedEventLoop (&InitMmFoundationSvcArgs
);