60 THUNK_CONTEXT *ThunkContext
64 UINT32 RealModeBufferSize;
65 UINT32 ExtraStackSize;
66 EFI_PHYSICAL_ADDRESS LegacyRegionBase;
67 UINT32 LegacyRegionSize;
72 AsmGetThunk16Properties (&RealModeBufferSize, &ExtraStackSize);
73 LegacyRegionSize = (((RealModeBufferSize + ExtraStackSize) / EFI_PAGE_SIZE) + 1) * EFI_PAGE_SIZE;
75 Status =
gBS->AllocatePages (
78 EFI_SIZE_TO_PAGES (LegacyRegionSize),
81 if (EFI_ERROR (Status)) {
85 ZeroMem ((VOID *)(UINTN)LegacyRegionBase, LegacyRegionSize);
87 ThunkContext->RealModeBuffer = (VOID *)(UINTN)LegacyRegionBase;
88 ThunkContext->RealModeBufferSize = LegacyRegionSize;
89 ThunkContext->ThunkAttributes = THUNK_ATTRIBUTE_BIG_REAL_MODE|THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15;
90 AsmPrepareThunk16 (ThunkContext);
110 EFI_PHYSICAL_ADDRESS LegacyRegionBase;
111 UINTN LegacyRegionLength;
112 volatile UINT32 *IdtArray;
114 UINT8 ProtectedModeBaseVector;
116 STATIC CONST UINT32 InterruptRedirectionCode[] = {
130 LegacyRegionLength =
sizeof (InterruptRedirectionCode);
132 Status =
gBS->AllocatePages (
135 EFI_SIZE_TO_PAGES (LegacyRegionLength),
138 if (EFI_ERROR (Status)) {
145 CopyMem ((VOID *)(UINTN)LegacyRegionBase, InterruptRedirectionCode,
sizeof (InterruptRedirectionCode));
150 Status = Legacy8259->GetVector (Legacy8259,
Efi8259Irq0, &ProtectedModeBaseVector);
151 ASSERT_EFI_ERROR (Status);
156 IdtArray = (UINT32 *)0;
157 for (Index = 0; Index < 8; Index++) {
158 IdtArray[ProtectedModeBaseVector + Index] = ((
EFI_SEGMENT (LegacyRegionBase + Index * 4)) << 16) | (
EFI_OFFSET (LegacyRegionBase + Index * 4));
242 IN THUNK_CONTEXT *ThunkContext,
245 IN IA32_REGISTER_SET *Regs
249 IA32_REGISTER_SET ThunkRegSet;
254 ZeroMem (&ThunkRegSet,
sizeof (ThunkRegSet));
255 ThunkRegSet.E.EFLAGS.Bits.Reserved_0 = 1;
256 ThunkRegSet.E.EFLAGS.Bits.Reserved_1 = 0;
257 ThunkRegSet.E.EFLAGS.Bits.Reserved_2 = 0;
258 ThunkRegSet.E.EFLAGS.Bits.Reserved_3 = 0;
259 ThunkRegSet.E.EFLAGS.Bits.IOPL = 3;
260 ThunkRegSet.E.EFLAGS.Bits.NT = 0;
261 ThunkRegSet.E.EFLAGS.Bits.IF = 1;
262 ThunkRegSet.E.EFLAGS.Bits.TF = 0;
263 ThunkRegSet.E.EFLAGS.Bits.CF = 0;
265 ThunkRegSet.E.EDI = Regs->E.EDI;
266 ThunkRegSet.E.ESI = Regs->E.ESI;
267 ThunkRegSet.E.EBP = Regs->E.EBP;
268 ThunkRegSet.E.EBX = Regs->E.EBX;
269 ThunkRegSet.E.EDX = Regs->E.EDX;
270 ThunkRegSet.E.ECX = Regs->E.ECX;
271 ThunkRegSet.E.EAX = Regs->E.EAX;
272 ThunkRegSet.E.DS = Regs->E.DS;
273 ThunkRegSet.E.ES = Regs->E.ES;
278 Enabled = SaveAndDisableInterrupts ();
284 ASSERT_EFI_ERROR (Status);
286 Stack16 = (UINT16 *)((UINT8 *)ThunkContext->RealModeBuffer + ThunkContext->RealModeBufferSize - sizeof (UINT16));
288 ThunkRegSet.E.SS = (UINT16)(((UINTN)Stack16 >> 16) << 12);
289 ThunkRegSet.E.ESP = (UINT16)(UINTN)Stack16;
291 ThunkRegSet.E.Eip = (UINT16)((
volatile UINT32 *)NULL)[BiosInt];
292 ThunkRegSet.E.CS = (UINT16)(((
volatile UINT32 *)NULL)[BiosInt] >> 16);
293 ThunkContext->RealModeState = &ThunkRegSet;
294 AsmThunk16 (ThunkContext);
300 ASSERT_EFI_ERROR (Status);
305 SetInterruptState (Enabled);
307 Regs->E.EDI = ThunkRegSet.E.EDI;
308 Regs->E.ESI = ThunkRegSet.E.ESI;
309 Regs->E.EBP = ThunkRegSet.E.EBP;
310 Regs->E.EBX = ThunkRegSet.E.EBX;
311 Regs->E.EDX = ThunkRegSet.E.EDX;
312 Regs->E.ECX = ThunkRegSet.E.ECX;
313 Regs->E.EAX = ThunkRegSet.E.EAX;
314 Regs->E.SS = ThunkRegSet.E.SS;
315 Regs->E.CS = ThunkRegSet.E.CS;
316 Regs->E.DS = ThunkRegSet.E.DS;
317 Regs->E.ES = ThunkRegSet.E.ES;
319 CopyMem (&(Regs->E.EFLAGS), &(ThunkRegSet.E.EFLAGS), sizeof (UINT32));
321 Ret = (BOOLEAN)(Regs->E.EFLAGS.Bits.CF == 1);
329 IN THUNK_CONTEXT *ThunkContext,
333 IN IA32_REGISTER_SET *Regs,
340 IA32_REGISTER_SET ThunkRegSet;
345 EFI_TIMER_ARCH_PROTOCOL *TimerProtocol;
347 ZeroMem (&ThunkRegSet,
sizeof (ThunkRegSet));
348 ThunkRegSet.E.EFLAGS.Bits.Reserved_0 = 1;
349 ThunkRegSet.E.EFLAGS.Bits.Reserved_1 = 0;
350 ThunkRegSet.E.EFLAGS.Bits.Reserved_2 = 0;
351 ThunkRegSet.E.EFLAGS.Bits.Reserved_3 = 0;
352 ThunkRegSet.E.EFLAGS.Bits.IOPL = 3;
353 ThunkRegSet.E.EFLAGS.Bits.NT = 0;
354 ThunkRegSet.E.EFLAGS.Bits.IF = 1;
355 ThunkRegSet.E.EFLAGS.Bits.TF = 0;
356 ThunkRegSet.E.EFLAGS.Bits.CF = 0;
358 ThunkRegSet.E.EDI = Regs->E.EDI;
359 ThunkRegSet.E.ESI = Regs->E.ESI;
360 ThunkRegSet.E.EBP = Regs->E.EBP;
361 ThunkRegSet.E.EBX = Regs->E.EBX;
362 ThunkRegSet.E.EDX = Regs->E.EDX;
363 ThunkRegSet.E.ECX = Regs->E.ECX;
364 ThunkRegSet.E.EAX = Regs->E.EAX;
365 ThunkRegSet.E.DS = Regs->E.DS;
366 ThunkRegSet.E.ES = Regs->E.ES;
371 Enabled = SaveAndDisableInterrupts ();
377 Status =
gBS->LocateProtocol (
378 &gEfiTimerArchProtocolGuid,
380 (VOID **)&TimerProtocol
382 if (!EFI_ERROR (Status)) {
383 TimerProtocol->GetTimerPeriod (TimerProtocol, &TimerPeriod);
384 TimerProtocol->SetTimerPeriod (TimerProtocol, 0);
386 TimerProtocol = NULL;
400 ASSERT_EFI_ERROR (Status);
406 ASSERT_EFI_ERROR (Status);
412 Stack16 = (UINT16 *)((UINT8 *)ThunkContext->RealModeBuffer + ThunkContext->RealModeBufferSize - sizeof (UINT16));
414 if ((Stack != NULL) && (StackSize != 0)) {
418 Stack16 -= StackSize /
sizeof (UINT16);
419 CopyMem (Stack16, Stack, StackSize);
422 ThunkRegSet.E.SS = (UINT16)(((UINTN)Stack16 >> 16) << 12);
423 ThunkRegSet.E.ESP = (UINT16)(UINTN)Stack16;
424 ThunkRegSet.E.CS = Segment;
425 ThunkRegSet.E.Eip = Offset;
427 ThunkContext->RealModeState = &ThunkRegSet;
428 AsmThunk16 (ThunkContext);
433 if ((Stack != NULL) && (StackSize != 0)) {
437 CopyMem (Stack, Stack16, StackSize);
444 ASSERT_EFI_ERROR (Status);
446 ThunkContext->RealModeState = NULL;
451 if (TimerProtocol != NULL) {
452 TimerProtocol->SetTimerPeriod (TimerProtocol, TimerPeriod);
458 SetInterruptState (Enabled);
460 Regs->E.EDI = ThunkRegSet.E.EDI;
461 Regs->E.ESI = ThunkRegSet.E.ESI;
462 Regs->E.EBP = ThunkRegSet.E.EBP;
463 Regs->E.EBX = ThunkRegSet.E.EBX;
464 Regs->E.EDX = ThunkRegSet.E.EDX;
465 Regs->E.ECX = ThunkRegSet.E.ECX;
466 Regs->E.EAX = ThunkRegSet.E.EAX;
467 Regs->E.SS = ThunkRegSet.E.SS;
468 Regs->E.CS = ThunkRegSet.E.CS;
469 Regs->E.DS = ThunkRegSet.E.DS;
470 Regs->E.ES = ThunkRegSet.E.ES;
472 CopyMem (&(Regs->E.EFLAGS), &(ThunkRegSet.E.EFLAGS), sizeof (UINT32));
474 Ret = (BOOLEAN)(Regs->E.EFLAGS.Bits.CF == 1);