TianoCore EDK2 master
Loading...
Searching...
No Matches
CpuDxe.c
Go to the documentation of this file.
1
10#include "CpuDxe.h"
11
12#include <Guid/IdleLoopEvent.h>
13
15
16BOOLEAN mIsFlushingGCD;
17
46EFIAPI
50 IN UINT64 Length,
51 IN EFI_CPU_FLUSH_TYPE FlushType
52 )
53{
54 switch (FlushType) {
55 case EfiCpuFlushTypeWriteBack:
56 WriteBackDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length);
57 break;
58 case EfiCpuFlushTypeInvalidate:
59 InvalidateDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length);
60 break;
61 case EfiCpuFlushTypeWriteBackInvalidate:
62 WriteBackInvalidateDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length);
63 break;
64 default:
65 return EFI_INVALID_PARAMETER;
66 }
67
68 return EFI_SUCCESS;
69}
70
81EFIAPI
84 )
85{
86 ArmEnableInterrupts ();
87
88 return EFI_SUCCESS;
89}
90
101EFIAPI
104 )
105{
106 ArmDisableInterrupts ();
107
108 return EFI_SUCCESS;
109}
110
125EFIAPI
128 OUT BOOLEAN *State
129 )
130{
131 if (State == NULL) {
132 return EFI_INVALID_PARAMETER;
133 }
134
135 *State = ArmGetInterruptState ();
136 return EFI_SUCCESS;
137}
138
156EFIAPI
159 IN EFI_CPU_INIT_TYPE InitType
160 )
161{
162 return EFI_UNSUPPORTED;
163}
164
166EFIAPI
169 IN EFI_EXCEPTION_TYPE InterruptType,
170 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
171 )
172{
173 return RegisterInterruptHandler (InterruptType, InterruptHandler);
174}
175
177EFIAPI
180 IN UINT32 TimerIndex,
181 OUT UINT64 *TimerValue,
182 OUT UINT64 *TimerPeriod OPTIONAL
183 )
184{
185 return EFI_UNSUPPORTED;
186}
187
196VOID
197EFIAPI
199 IN EFI_EVENT Event,
200 IN VOID *Context
201 )
202{
203 CpuSleep ();
204}
205
206//
207// Globals used to initialize the protocol
208//
209EFI_HANDLE mCpuHandle = NULL;
215 CpuInit,
219 0, // NumberOfTimers
220 2048, // DmaBufferAlignment
221};
222
223STATIC
224VOID
225InitializeDma (
226 IN OUT EFI_CPU_ARCH_PROTOCOL *CpuArchProtocol
227 )
228{
229 CpuArchProtocol->DmaBufferAlignment = ArmCacheWritebackGranule ();
230}
231
238STATIC
239VOID
241 VOID
242 )
243{
244 UINT64 TestBit;
245 UINTN MemoryMapSize;
246 UINTN MapKey;
247 UINTN DescriptorSize;
248 UINT32 DescriptorVersion;
249 EFI_MEMORY_DESCRIPTOR *MemoryMap;
250 EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
251 EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
252 EFI_STATUS Status;
253
254 TestBit = LShiftU64 (1, EfiBootServicesData);
255 if ((PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & TestBit) == 0) {
256 return;
257 }
258
259 MemoryMapSize = 0;
260 MemoryMap = NULL;
261
262 Status = gBS->GetMemoryMap (
263 &MemoryMapSize,
264 MemoryMap,
265 &MapKey,
266 &DescriptorSize,
267 &DescriptorVersion
268 );
269 ASSERT (Status == EFI_BUFFER_TOO_SMALL);
270 do {
271 MemoryMap = (EFI_MEMORY_DESCRIPTOR *)AllocatePool (MemoryMapSize);
272 ASSERT (MemoryMap != NULL);
273 Status = gBS->GetMemoryMap (
274 &MemoryMapSize,
275 MemoryMap,
276 &MapKey,
277 &DescriptorSize,
278 &DescriptorVersion
279 );
280 if (EFI_ERROR (Status)) {
281 FreePool (MemoryMap);
282 }
283 } while (Status == EFI_BUFFER_TOO_SMALL);
284
285 ASSERT_EFI_ERROR (Status);
286
287 MemoryMapEntry = MemoryMap;
288 MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
289 while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
290 if (MemoryMapEntry->Type == EfiConventionalMemory) {
292 MemoryMapEntry->PhysicalStart,
293 EFI_PAGES_TO_SIZE (MemoryMapEntry->NumberOfPages),
294 EFI_MEMORY_XP,
295 EFI_MEMORY_XP
296 );
297 }
298
299 MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
300 }
301}
302
304CpuDxeInitialize (
305 IN EFI_HANDLE ImageHandle,
306 IN EFI_SYSTEM_TABLE *SystemTable
307 )
308{
309 EFI_STATUS Status;
310 EFI_EVENT IdleLoopEvent;
311
312 InitializeExceptions (&mCpu);
313
314 InitializeDma (&mCpu);
315
316 //
317 // Once we install the CPU arch protocol, the DXE core's memory
318 // protection routines will invoke them to manage the permissions of page
319 // allocations as they are created. Given that this includes pages
320 // allocated for page tables by this driver, we must ensure that unused
321 // memory is mapped with the same permissions as boot services data
322 // regions. Otherwise, we may end up with unbounded recursion, due to the
323 // fact that updating permissions on a newly allocated page table may trigger
324 // a block entry split, which triggers a page table allocation, etc etc
325 //
326 if (FeaturePcdGet (PcdRemapUnusedMemoryNx)) {
328 }
329
330 Status = gBS->InstallMultipleProtocolInterfaces (
331 &mCpuHandle,
332 &gEfiCpuArchProtocolGuid,
333 &mCpu,
334 &gEfiMemoryAttributeProtocolGuid,
335 &mMemoryAttribute,
336 NULL
337 );
338
339 //
340 // Make sure GCD and MMU settings match. This API calls gDS->SetMemorySpaceAttributes ()
341 // and that calls EFI_CPU_ARCH_PROTOCOL.SetMemoryAttributes, so this code needs to go
342 // after the protocol is installed
343 //
344 mIsFlushingGCD = TRUE;
345 SyncCacheConfig (&mCpu);
346 mIsFlushingGCD = FALSE;
347
348 //
349 // Setup a callback for idle events
350 //
351 Status = gBS->CreateEventEx (
352 EVT_NOTIFY_SIGNAL,
353 TPL_NOTIFY,
355 NULL,
356 &gIdleLoopEventGuid,
357 &IdleLoopEvent
358 );
359 ASSERT_EFI_ERROR (Status);
360
361 return Status;
362}
UINT64 UINTN
VOID *EFIAPI WriteBackDataCacheRange(IN VOID *Address, IN UINTN Length)
VOID *EFIAPI InvalidateDataCacheRange(IN VOID *Address, IN UINTN Length)
VOID *EFIAPI WriteBackInvalidateDataCacheRange(IN VOID *Address, IN UINTN Length)
EFI_STATUS ArmSetMemoryAttributes(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes, IN UINT64 AttributeMask)
EFI_STATUS EFIAPI CpuGetInterruptState(IN EFI_CPU_ARCH_PROTOCOL *This, OUT BOOLEAN *State)
Definition: CpuDxe.c:126
VOID EFIAPI IdleLoopEventCallback(IN EFI_EVENT Event, IN VOID *Context)
Definition: CpuDxe.c:198
EFI_STATUS EFIAPI CpuRegisterInterruptHandler(IN EFI_CPU_ARCH_PROTOCOL *This, IN EFI_EXCEPTION_TYPE InterruptType, IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler)
Definition: CpuDxe.c:167
EFI_STATUS EFIAPI CpuGetTimerValue(IN EFI_CPU_ARCH_PROTOCOL *This, IN UINT32 TimerIndex, OUT UINT64 *TimerValue, OUT UINT64 *TimerPeriod OPTIONAL)
Definition: CpuDxe.c:178
STATIC VOID RemapUnusedMemoryNx(VOID)
Definition: CpuDxe.c:240
EFI_STATUS EFIAPI CpuDisableInterrupt(IN EFI_CPU_ARCH_PROTOCOL *This)
Definition: CpuDxe.c:102
EFI_STATUS EFIAPI CpuInit(IN EFI_CPU_ARCH_PROTOCOL *This, IN EFI_CPU_INIT_TYPE InitType)
Definition: CpuDxe.c:157
EFI_STATUS EFIAPI CpuFlushCpuDataCache(IN EFI_CPU_ARCH_PROTOCOL *This, IN EFI_PHYSICAL_ADDRESS Start, IN UINT64 Length, IN EFI_CPU_FLUSH_TYPE FlushType)
Definition: CpuDxe.c:47
EFI_STATUS EFIAPI CpuEnableInterrupt(IN EFI_CPU_ARCH_PROTOCOL *This)
Definition: CpuDxe.c:82
EFI_STATUS EFIAPI CpuSetMemoryAttributes(IN EFI_CPU_ARCH_PROTOCOL *This, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
Definition: CpuMmuCommon.c:185
EFI_STATUS RegisterInterruptHandler(IN EFI_EXCEPTION_TYPE InterruptType, IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler)
Definition: Exception.c:93
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
EFI_CPU_FLUSH_TYPE
Definition: Cpu.h:24
EFI_CPU_INIT_TYPE
Definition: Cpu.h:34
VOID(EFIAPI * EFI_CPU_INTERRUPT_HANDLER)(IN CONST EFI_EXCEPTION_TYPE InterruptType, IN CONST EFI_SYSTEM_CONTEXT SystemContext)
Definition: Cpu.h:52
VOID EFIAPI CpuSleep(VOID)
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:445
VOID EFIAPI FreePool(IN VOID *Buffer)
INTN EFI_EXCEPTION_TYPE
Definition: DebugSupport.h:35
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
#define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size)
Definition: UefiLib.h:111
@ EfiBootServicesData
@ EfiConventionalMemory
EFI_PHYSICAL_ADDRESS PhysicalStart
Definition: UefiSpec.h:140