Changeset 58459 in vbox for trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg
- Timestamp:
- Oct 28, 2015 8:17:18 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 103761
- Location:
- trunk/src/VBox/Devices/EFI/Firmware
- Files:
-
- 3 deleted
- 36 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/EFI/Firmware
-
Property svn:mergeinfo
set to (toggle deleted branches)
/vendor/edk2/current 103735-103757
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/CpuDxe/CpuDxe.c
r48674 r58459 2 2 CPU DXE Module. 3 3 4 Copyright (c) 2008 - 201 1, Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 18 18 // Global Variables 19 19 // 20 IA32_IDT_GATE_DESCRIPTOR gIdtTable[INTERRUPT_VECTOR_NUMBER] = { 0 };21 22 EFI_CPU_INTERRUPT_HANDLER ExternalVectorTable[0x100];23 20 BOOLEAN InterruptState = FALSE; 24 21 EFI_HANDLE mCpuHandle = NULL; … … 26 23 UINT64 mValidMtrrAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS; 27 24 UINT64 mValidMtrrBitsMask = MTRR_LIB_MSR_VALID_MASK; 28 IA32_IDT_GATE_DESCRIPTOR *mOrigIdtEntry = NULL;29 UINT16 mOrigIdtEntryCount = 0;30 25 31 26 FIXED_MTRR mFixedMtrrTable[] = { … … 102 97 103 98 // 104 // Error code flag indicating whether or not an error code will be105 // pushed on the stack if an exception occurs.106 //107 // 1 means an error code will be pushed, otherwise 0108 //109 // bit 0 - exception 0110 // bit 1 - exception 1111 // etc.112 //113 UINT32 mErrorCodeFlag = 0x00027d00;114 115 //116 // Local function prototypes117 //118 119 /**120 Set Interrupt Descriptor Table Handler Address.121 122 @param Index The Index of the interrupt descriptor table handle.123 @param Handler Handler address.124 125 **/126 VOID127 SetInterruptDescriptorTableHandlerAddress (128 IN UINTN Index,129 IN VOID *Handler OPTIONAL130 );131 132 //133 99 // CPU Arch Protocol Functions 134 100 // 135 136 137 /**138 Common exception handler.139 140 @param InterruptType Exception type141 @param SystemContext EFI_SYSTEM_CONTEXT142 143 **/144 VOID145 EFIAPI146 CommonExceptionHandler (147 IN EFI_EXCEPTION_TYPE InterruptType,148 IN EFI_SYSTEM_CONTEXT SystemContext149 )150 {151 #if defined (MDE_CPU_IA32)152 DEBUG ((153 EFI_D_ERROR,154 "!!!! IA32 Exception Type - %08x !!!!\n",155 InterruptType156 ));157 if ((mErrorCodeFlag & (1 << InterruptType)) != 0) {158 DEBUG ((159 EFI_D_ERROR,160 "ExceptionData - %08x\n",161 SystemContext.SystemContextIa32->ExceptionData162 ));163 }164 DEBUG ((165 EFI_D_ERROR,166 "CS - %04x, EIP - %08x, EFL - %08x, SS - %04x\n",167 SystemContext.SystemContextIa32->Cs,168 SystemContext.SystemContextIa32->Eip,169 SystemContext.SystemContextIa32->Eflags,170 SystemContext.SystemContextIa32->Ss171 ));172 DEBUG ((173 EFI_D_ERROR,174 "DS - %04x, ES - %04x, FS - %04x, GS - %04x\n",175 SystemContext.SystemContextIa32->Ds,176 SystemContext.SystemContextIa32->Es,177 SystemContext.SystemContextIa32->Fs,178 SystemContext.SystemContextIa32->Gs179 ));180 DEBUG ((181 EFI_D_ERROR,182 "EAX - %08x, EBX - %08x, ECX - %08x, EDX - %08x\n",183 SystemContext.SystemContextIa32->Eax,184 SystemContext.SystemContextIa32->Ebx,185 SystemContext.SystemContextIa32->Ecx,186 SystemContext.SystemContextIa32->Edx187 ));188 DEBUG ((189 EFI_D_ERROR,190 "ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n",191 SystemContext.SystemContextIa32->Esp,192 SystemContext.SystemContextIa32->Ebp,193 SystemContext.SystemContextIa32->Esi,194 SystemContext.SystemContextIa32->Edi195 ));196 DEBUG ((197 EFI_D_ERROR,198 "GDT - %08x LIM - %04x, IDT - %08x LIM - %04x\n",199 SystemContext.SystemContextIa32->Gdtr[0],200 SystemContext.SystemContextIa32->Gdtr[1],201 SystemContext.SystemContextIa32->Idtr[0],202 SystemContext.SystemContextIa32->Idtr[1]203 ));204 DEBUG ((205 EFI_D_ERROR,206 "LDT - %08x, TR - %08x\n",207 SystemContext.SystemContextIa32->Ldtr,208 SystemContext.SystemContextIa32->Tr209 ));210 DEBUG ((211 EFI_D_ERROR,212 "CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n",213 SystemContext.SystemContextIa32->Cr0,214 SystemContext.SystemContextIa32->Cr2,215 SystemContext.SystemContextIa32->Cr3,216 SystemContext.SystemContextIa32->Cr4217 ));218 DEBUG ((219 EFI_D_ERROR,220 "DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n",221 SystemContext.SystemContextIa32->Dr0,222 SystemContext.SystemContextIa32->Dr1,223 SystemContext.SystemContextIa32->Dr2,224 SystemContext.SystemContextIa32->Dr3225 ));226 DEBUG ((227 EFI_D_ERROR,228 "DR6 - %08x, DR7 - %08x\n",229 SystemContext.SystemContextIa32->Dr6,230 SystemContext.SystemContextIa32->Dr7231 ));232 #elif defined (MDE_CPU_X64)233 DEBUG ((234 EFI_D_ERROR,235 "!!!! X64 Exception Type - %016lx !!!!\n",236 (UINT64)InterruptType237 ));238 if ((mErrorCodeFlag & (1 << InterruptType)) != 0) {239 DEBUG ((240 EFI_D_ERROR,241 "ExceptionData - %016lx\n",242 SystemContext.SystemContextX64->ExceptionData243 ));244 }245 DEBUG ((246 EFI_D_ERROR,247 "RIP - %016lx, RFL - %016lx\n",248 SystemContext.SystemContextX64->Rip,249 SystemContext.SystemContextX64->Rflags250 ));251 DEBUG ((252 EFI_D_ERROR,253 "RAX - %016lx, RCX - %016lx, RDX - %016lx\n",254 SystemContext.SystemContextX64->Rax,255 SystemContext.SystemContextX64->Rcx,256 SystemContext.SystemContextX64->Rdx257 ));258 DEBUG ((259 EFI_D_ERROR,260 "RBX - %016lx, RSP - %016lx, RBP - %016lx\n",261 SystemContext.SystemContextX64->Rbx,262 SystemContext.SystemContextX64->Rsp,263 SystemContext.SystemContextX64->Rbp264 ));265 DEBUG ((266 EFI_D_ERROR,267 "RSI - %016lx, RDI - %016lx\n",268 SystemContext.SystemContextX64->Rsi,269 SystemContext.SystemContextX64->Rdi270 ));271 DEBUG ((272 EFI_D_ERROR,273 "R8 - %016lx, R9 - %016lx, R10 - %016lx\n",274 SystemContext.SystemContextX64->R8,275 SystemContext.SystemContextX64->R9,276 SystemContext.SystemContextX64->R10277 ));278 DEBUG ((279 EFI_D_ERROR,280 "R11 - %016lx, R12 - %016lx, R13 - %016lx\n",281 SystemContext.SystemContextX64->R11,282 SystemContext.SystemContextX64->R12,283 SystemContext.SystemContextX64->R13284 ));285 DEBUG ((286 EFI_D_ERROR,287 "R14 - %016lx, R15 - %016lx\n",288 SystemContext.SystemContextX64->R14,289 SystemContext.SystemContextX64->R15290 ));291 DEBUG ((292 EFI_D_ERROR,293 "CS - %04lx, DS - %04lx, ES - %04lx, FS - %04lx, GS - %04lx, SS - %04lx\n",294 SystemContext.SystemContextX64->Cs,295 SystemContext.SystemContextX64->Ds,296 SystemContext.SystemContextX64->Es,297 SystemContext.SystemContextX64->Fs,298 SystemContext.SystemContextX64->Gs,299 SystemContext.SystemContextX64->Ss300 ));301 DEBUG ((302 EFI_D_ERROR,303 "GDT - %016lx; %04lx, IDT - %016lx; %04lx\n",304 SystemContext.SystemContextX64->Gdtr[0],305 SystemContext.SystemContextX64->Gdtr[1],306 SystemContext.SystemContextX64->Idtr[0],307 SystemContext.SystemContextX64->Idtr[1]308 ));309 DEBUG ((310 EFI_D_ERROR,311 "LDT - %016lx, TR - %016lx\n",312 SystemContext.SystemContextX64->Ldtr,313 SystemContext.SystemContextX64->Tr314 ));315 DEBUG ((316 EFI_D_ERROR,317 "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n",318 SystemContext.SystemContextX64->Cr0,319 SystemContext.SystemContextX64->Cr2,320 SystemContext.SystemContextX64->Cr3321 ));322 DEBUG ((323 EFI_D_ERROR,324 "CR4 - %016lx, CR8 - %016lx\n",325 SystemContext.SystemContextX64->Cr4,326 SystemContext.SystemContextX64->Cr8327 ));328 DEBUG ((329 EFI_D_ERROR,330 "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n",331 SystemContext.SystemContextX64->Dr0,332 SystemContext.SystemContextX64->Dr1,333 SystemContext.SystemContextX64->Dr2334 ));335 DEBUG ((336 EFI_D_ERROR,337 "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n",338 SystemContext.SystemContextX64->Dr3,339 SystemContext.SystemContextX64->Dr6,340 SystemContext.SystemContextX64->Dr7341 ));342 #else343 #error CPU type not supported for exception information dump!344 #endif345 346 //347 // Hang the system with CpuSleep so the processor will enter a lower power348 // state.349 //350 while (TRUE) {351 CpuSleep ();352 };353 }354 355 101 356 102 /** … … 511 257 ) 512 258 { 513 if (InterruptType < 0 || InterruptType > 0xff) { 514 return EFI_UNSUPPORTED; 515 } 516 517 if (InterruptHandler == NULL && ExternalVectorTable[InterruptType] == NULL) { 518 return EFI_INVALID_PARAMETER; 519 } 520 521 if (InterruptHandler != NULL && ExternalVectorTable[InterruptType] != NULL) { 522 return EFI_ALREADY_STARTED; 523 } 524 525 if (InterruptHandler != NULL) { 526 SetInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType, NULL); 527 } else { 528 // 529 // Restore the original IDT handler address if InterruptHandler is NULL. 530 // 531 RestoreInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType); 532 } 533 534 ExternalVectorTable[InterruptType] = InterruptHandler; 535 return EFI_SUCCESS; 259 return RegisterCpuInterruptHandler (InterruptType, InterruptHandler); 536 260 } 537 261 … … 638 362 // 639 363 if (mIsFlushingGCD) { 640 DEBUG((EFI_D_ ERROR, " Flushing GCD\n"));641 642 364 DEBUG((EFI_D_INFO, " Flushing GCD\n")); 365 return EFI_SUCCESS; 366 } 643 367 644 368 switch (Attributes) { … … 970 694 // 971 695 for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) { 972 if (VariableMtrr[Index].Valid && 696 if (VariableMtrr[Index].Valid && 973 697 VariableMtrr[Index].Type != MTRR_CACHE_WRITE_BACK && 974 698 VariableMtrr[Index].Type != MTRR_CACHE_UNCACHEABLE) { … … 1062 786 1063 787 /** 1064 Set Interrupt Descriptor Table Handler Address.1065 1066 @param Index The Index of the interrupt descriptor table handle.1067 @param Handler Handler address.1068 1069 **/1070 VOID1071 SetInterruptDescriptorTableHandlerAddress (1072 IN UINTN Index,1073 IN VOID *Handler OPTIONAL1074 )1075 {1076 UINTN UintnHandler;1077 1078 if (Handler != NULL) {1079 UintnHandler = (UINTN) Handler;1080 } else {1081 UintnHandler = ((UINTN) AsmIdtVector00) + (8 * Index);1082 }1083 1084 gIdtTable[Index].Bits.OffsetLow = (UINT16)UintnHandler;1085 gIdtTable[Index].Bits.Reserved_0 = 0;1086 gIdtTable[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;1087 gIdtTable[Index].Bits.OffsetHigh = (UINT16)(UintnHandler >> 16);1088 #if defined (MDE_CPU_X64)1089 gIdtTable[Index].Bits.OffsetUpper = (UINT32)(UintnHandler >> 32);1090 gIdtTable[Index].Bits.Reserved_1 = 0;1091 #endif1092 }1093 1094 /**1095 Restore original Interrupt Descriptor Table Handler Address.1096 1097 @param Index The Index of the interrupt descriptor table handle.1098 1099 **/1100 VOID1101 RestoreInterruptDescriptorTableHandlerAddress (1102 IN UINTN Index1103 )1104 {1105 if (Index < mOrigIdtEntryCount) {1106 gIdtTable[Index].Bits.OffsetLow = mOrigIdtEntry[Index].Bits.OffsetLow;1107 gIdtTable[Index].Bits.OffsetHigh = mOrigIdtEntry[Index].Bits.OffsetHigh;1108 #if defined (MDE_CPU_X64)1109 gIdtTable[Index].Bits.OffsetUpper = mOrigIdtEntry[Index].Bits.OffsetUpper;1110 #endif1111 }1112 }1113 1114 /**1115 788 Initialize Interrupt Descriptor Table for interrupt handling. 1116 789 … … 1121 794 ) 1122 795 { 1123 EFI_STATUS Status; 1124 IA32_DESCRIPTOR OldIdtPtr; 1125 IA32_IDT_GATE_DESCRIPTOR *OldIdt; 1126 UINTN OldIdtSize; 1127 VOID *IdtPtrAlignmentBuffer; 1128 IA32_DESCRIPTOR *IdtPtr; 1129 UINTN Index; 1130 UINT16 CurrentCs; 1131 VOID *IntHandler; 1132 1133 SetMem (ExternalVectorTable, sizeof(ExternalVectorTable), 0); 1134 1135 // 1136 // Get original IDT address and size. 1137 // 1138 AsmReadIdtr ((IA32_DESCRIPTOR *) &OldIdtPtr); 1139 1140 if ((OldIdtPtr.Base != 0) && ((OldIdtPtr.Limit & 7) == 7)) { 1141 OldIdt = (IA32_IDT_GATE_DESCRIPTOR*) OldIdtPtr.Base; 1142 OldIdtSize = (OldIdtPtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR); 1143 // 1144 // Save original IDT entry and IDT entry count. 1145 // 1146 mOrigIdtEntry = AllocateCopyPool (OldIdtPtr.Limit + 1, (VOID *) OldIdtPtr.Base); 1147 ASSERT (mOrigIdtEntry != NULL); 1148 mOrigIdtEntryCount = (UINT16) OldIdtSize; 1149 } else { 1150 OldIdt = NULL; 1151 OldIdtSize = 0; 1152 } 1153 1154 // 1155 // Intialize IDT 1156 // 1157 CurrentCs = AsmReadCs(); 1158 for (Index = 0; Index < INTERRUPT_VECTOR_NUMBER; Index ++) { 1159 // 1160 // If the old IDT had a handler for this interrupt, then 1161 // preserve it. 1162 // 1163 if (Index < OldIdtSize) { 1164 IntHandler = 1165 (VOID*) ( 1166 OldIdt[Index].Bits.OffsetLow + 1167 (OldIdt[Index].Bits.OffsetHigh << 16) 1168 #if defined (MDE_CPU_X64) 1169 + (((UINTN) OldIdt[Index].Bits.OffsetUpper) << 32) 1170 #endif 1171 ); 1172 } else { 1173 IntHandler = NULL; 1174 } 1175 1176 gIdtTable[Index].Bits.Selector = CurrentCs; 1177 gIdtTable[Index].Bits.Reserved_0 = 0; 1178 gIdtTable[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; 1179 SetInterruptDescriptorTableHandlerAddress (Index, IntHandler); 1180 } 1181 1182 // 1183 // Load IDT Pointer 1184 // 1185 IdtPtrAlignmentBuffer = AllocatePool (sizeof (*IdtPtr) + 16); 1186 IdtPtr = ALIGN_POINTER (IdtPtrAlignmentBuffer, 16); 1187 IdtPtr->Base = (UINT32)(((UINTN)(VOID*) gIdtTable) & (BASE_4GB-1)); 1188 IdtPtr->Limit = (UINT16) (sizeof (gIdtTable) - 1); 1189 1190 AsmWriteIdtr (IdtPtr); 1191 1192 FreePool (IdtPtrAlignmentBuffer); 1193 1194 // 1195 // Initialize Exception Handlers 1196 // 1197 for (Index = OldIdtSize; Index < 32; Index++) { 1198 Status = CpuRegisterInterruptHandler (&gCpu, Index, CommonExceptionHandler); 1199 ASSERT_EFI_ERROR (Status); 1200 } 1201 1202 // 1203 // Set the pointer to the array of C based exception handling routines. 1204 // 1205 InitializeExternalVectorTablePtr (ExternalVectorTable); 1206 796 EFI_STATUS Status; 797 EFI_VECTOR_HANDOFF_INFO *VectorInfoList; 798 EFI_VECTOR_HANDOFF_INFO *VectorInfo; 799 800 VectorInfo = NULL; 801 Status = EfiGetSystemConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID **) &VectorInfoList); 802 if (Status == EFI_SUCCESS && VectorInfoList != NULL) { 803 VectorInfo = VectorInfoList; 804 } 805 Status = InitializeCpuInterruptHandlers (VectorInfo); 806 ASSERT_EFI_ERROR (Status); 1207 807 } 1208 808 … … 1210 810 /** 1211 811 Callback function for idle events. 1212 812 1213 813 @param Event Event whose notification function is being invoked. 1214 814 @param Context The pointer to the notification function's context, … … 1248 848 EFI_EVENT IdleLoopEvent; 1249 849 850 InitializeFloatingPointUnits (); 851 1250 852 // 1251 853 // Make sure interrupts are disabled … … 1262 864 // 1263 865 InitInterruptDescriptorTable (); 866 867 // 868 // Enable the local APIC for Virtual Wire Mode. 869 // 870 ProgramVirtualWireMode (); 1264 871 1265 872 // -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/CpuDxe/CpuDxe.h
r48674 r58459 2 2 CPU DXE Module. 3 3 4 Copyright (c) 2008 - 201 1, Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 29 29 #include <Library/DebugLib.h> 30 30 #include <Library/MtrrLib.h> 31 #include <Library/LocalApicLib.h> 32 #include <Library/UefiCpuLib.h> 33 #include <Library/UefiLib.h> 34 #include <Library/CpuExceptionHandlerLib.h> 31 35 #include <Guid/IdleLoopEvent.h> 32 33 // 34 // 35 // 36 #define INTERRUPT_VECTOR_NUMBER 256 36 #include <Guid/VectorHandoffTable.h> 37 37 38 38 #define EFI_MEMORY_CACHETYPE_MASK (EFI_MEMORY_UC | \ … … 220 220 221 221 /** 222 Label of base address of IDT vector 0.223 224 This is just a label of base address of IDT vector 0.225 226 **/227 VOID228 EFIAPI229 AsmIdtVector00 (230 VOID231 );232 233 /**234 Initializes the pointer to the external interrupt vector table.235 236 @param VectorTable Address of the external interrupt vector table.237 238 **/239 VOID240 EFIAPI241 InitializeExternalVectorTablePtr (242 EFI_CPU_INTERRUPT_HANDLER *VectorTable243 );244 245 /**246 222 Initialize Global Descriptor Table. 247 223 … … 276 252 ); 277 253 278 /**279 Restore original Interrupt Descriptor Table Handler Address.280 281 @param Index The Index of the interrupt descriptor table handle.282 283 **/284 VOID285 RestoreInterruptDescriptorTableHandlerAddress (286 IN UINTN Index287 );288 289 254 #endif 290 255 -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/CpuDxe/CpuDxe.inf
r48674 r58459 1 1 ## @file 2 # Simple CPU driver installs CPU Architecture Protocol. 2 3 # 3 # Component description file for simple CPU driver 4 # 5 # Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR> 4 # Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> 6 5 # This program and the accompanying materials 7 6 # are licensed and made available under the terms and conditions of the BSD License … … 17 16 INF_VERSION = 0x00010005 18 17 BASE_NAME = CpuDxe 18 MODULE_UNI_FILE = CpuDxe.uni 19 19 FILE_GUID = 1A1E4886-9517-440e-9FDE-3BE44CEE2136 20 20 MODULE_TYPE = DXE_DRIVER … … 38 38 UefiBootServicesTableLib 39 39 UefiDriverEntryPoint 40 LocalApicLib 41 UefiCpuLib 42 UefiLib 43 CpuExceptionHandlerLib 40 44 41 45 [Sources] … … 43 47 CpuDxe.h 44 48 CpuGdt.c 45 46 Ia32/IvtAsm.asm | MSFT47 Ia32/IvtAsm.asm | INTEL48 Ia32/IvtAsm.S | GCC49 49 50 50 [Sources.IA32] … … 59 59 60 60 [Protocols] 61 gEfiCpuArchProtocolGuid 61 gEfiCpuArchProtocolGuid ## PRODUCES 62 62 63 63 [Guids] 64 gIdleLoopEventGuid ## CONSUMES ## GUID 64 gIdleLoopEventGuid ## CONSUMES ## Event 65 gEfiVectorHandoffTableGuid ## SOMETIMES_CONSUMES ## SystemTable 65 66 66 67 [Depex] 67 68 TRUE 68 69 70 [UserExtensions.TianoCore."ExtraFiles"] 71 CpuDxeExtra.uni -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S
r48674 r58459 1 1 #------------------------------------------------------------------------------ 2 2 #* 3 #* Copyright (c) 2006 - 201 1, Intel Corporation. All rights reserved.<BR>3 #* Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR> 4 4 #* This program and the accompanying materials 5 5 #* are licensed and made available under the terms and conditions of the BSD License … … 19 19 #.MMX 20 20 #.XMM 21 22 #EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions23 24 25 #26 # point to the external interrupt vector table27 #28 ExternalVectorTablePtr:29 .byte 0, 0, 0, 030 31 ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)32 ASM_PFX(InitializeExternalVectorTablePtr):33 movl 4(%esp), %eax34 movl %eax, ExternalVectorTablePtr35 ret36 21 37 22 #------------------------------------------------------------------------------ … … 69 54 ret 70 55 71 #---------------------------------------;72 # CommonInterruptEntry ;73 #---------------------------------------;74 # The follow algorithm is used for the common interrupt routine.75 76 ASM_GLOBAL ASM_PFX(CommonInterruptEntry)77 ASM_PFX(CommonInterruptEntry):78 cli79 #80 # All interrupt handlers are invoked through interrupt gates, so81 # IF flag automatically cleared at the entry point82 #83 84 #85 # Calculate vector number86 #87 # Get the return address of call, actually, it is the88 # address of vector number.89 #90 xchgl (%esp), %ecx91 movw (%ecx), %cx92 andl $0x0FFFF, %ecx93 cmpl $32, %ecx # Intel reserved vector for exceptions?94 jae NoErrorCode95 bt %ecx, ASM_PFX(mErrorCodeFlag)96 jc HasErrorCode97 98 NoErrorCode:99 100 #101 # Stack:102 # +---------------------+103 # + EFlags +104 # +---------------------+105 # + CS +106 # +---------------------+107 # + EIP +108 # +---------------------+109 # + ECX +110 # +---------------------+ <-- ESP111 #112 # Registers:113 # ECX - Vector Number114 #115 116 #117 # Put Vector Number on stack118 #119 pushl %ecx120 121 #122 # Put 0 (dummy) error code on stack, and restore ECX123 #124 xorl %ecx, %ecx # ECX = 0125 xchgl 4(%esp), %ecx126 127 jmp ErrorCodeAndVectorOnStack128 129 HasErrorCode:130 131 #132 # Stack:133 # +---------------------+134 # + EFlags +135 # +---------------------+136 # + CS +137 # +---------------------+138 # + EIP +139 # +---------------------+140 # + Error Code +141 # +---------------------+142 # + ECX +143 # +---------------------+ <-- ESP144 #145 # Registers:146 # ECX - Vector Number147 #148 149 #150 # Put Vector Number on stack and restore ECX151 #152 xchgl (%esp), %ecx153 154 #155 # Fall through to join main routine code156 # at ErrorCodeAndVectorOnStack157 #158 CommonInterruptEntry_al_0000:159 jmp CommonInterruptEntry_al_0000160 161 ErrorCodeAndVectorOnStack:162 pushl %ebp163 movl %esp, %ebp164 165 #166 # Stack:167 # +---------------------+168 # + EFlags +169 # +---------------------+170 # + CS +171 # +---------------------+172 # + EIP +173 # +---------------------+174 # + Error Code +175 # +---------------------+176 # + Vector Number +177 # +---------------------+178 # + EBP +179 # +---------------------+ <-- EBP180 #181 182 #183 # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32184 # is 16-byte aligned185 #186 andl $0x0fffffff0, %esp187 subl $12, %esp188 189 #; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;190 pushl %eax191 pushl %ecx192 pushl %edx193 pushl %ebx194 leal 24(%ebp), %ecx195 pushl %ecx # ESP196 pushl (%ebp) # EBP197 pushl %esi198 pushl %edi199 200 #; UINT32 Gs, Fs, Es, Ds, Cs, Ss;201 movl %ss, %eax202 pushl %eax203 movzwl 16(%ebp), %eax204 pushl %eax205 movl %ds, %eax206 pushl %eax207 movl %es, %eax208 pushl %eax209 movl %fs, %eax210 pushl %eax211 movl %gs, %eax212 pushl %eax213 214 #; UINT32 Eip;215 movl 12(%ebp), %eax216 pushl %eax217 218 #; UINT32 Gdtr[2], Idtr[2];219 subl $8, %esp220 sidt (%esp)221 movl 2(%esp), %eax222 xchgl (%esp), %eax223 andl $0x0FFFF, %eax224 movl %eax, 4(%esp)225 226 subl $8, %esp227 sgdt (%esp)228 movl 2(%esp), %eax229 xchgl (%esp), %eax230 andl $0x0FFFF, %eax231 movl %eax, 4(%esp)232 233 #; UINT32 Ldtr, Tr;234 xorl %eax, %eax235 str %ax236 pushl %eax237 sldt %ax238 pushl %eax239 240 #; UINT32 EFlags;241 movl 20(%ebp), %eax242 pushl %eax243 244 #; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;245 movl %cr4, %eax246 orl $0x208, %eax247 movl %eax, %cr4248 pushl %eax249 movl %cr3, %eax250 pushl %eax251 movl %cr2, %eax252 pushl %eax253 xorl %eax, %eax254 pushl %eax255 movl %cr0, %eax256 pushl %eax257 258 #; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;259 movl %dr7, %eax260 pushl %eax261 movl %dr6, %eax262 pushl %eax263 movl %dr3, %eax264 pushl %eax265 movl %dr2, %eax266 pushl %eax267 movl %dr1, %eax268 pushl %eax269 movl %dr0, %eax270 pushl %eax271 272 #; FX_SAVE_STATE_IA32 FxSaveState;273 subl $512, %esp274 movl %esp, %edi275 .byte 0x0f, 0x0ae, 0x07 #fxsave [edi]276 277 #; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear278 cld279 280 #; UINT32 ExceptionData;281 pushl 8(%ebp)282 283 #; call into exception handler284 movl ExternalVectorTablePtr, %eax # get the interrupt vectors base285 orl %eax, %eax # NULL?286 jz nullExternalExceptionHandler287 288 mov 4(%ebp), %ecx289 movl (%eax,%ecx,4), %eax290 orl %eax, %eax # NULL?291 jz nullExternalExceptionHandler292 293 #; Prepare parameter and call294 movl %esp, %edx295 pushl %edx296 movl 4(%ebp), %edx297 pushl %edx298 299 #300 # Call External Exception Handler301 #302 call *%eax303 addl $8, %esp304 305 nullExternalExceptionHandler:306 307 cli308 #; UINT32 ExceptionData;309 addl $4, %esp310 311 #; FX_SAVE_STATE_IA32 FxSaveState;312 movl %esp, %esi313 .byte 0x0f, 0x0ae, 0x0e # fxrstor [esi]314 addl $512, %esp315 316 #; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;317 #; Skip restoration of DRx registers to support in-circuit emualators318 #; or debuggers set breakpoint in interrupt/exception context319 addl $24, %esp320 321 #; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;322 popl %eax323 movl %eax, %cr0324 addl $4, %esp # not for Cr1325 popl %eax326 movl %eax, %cr2327 popl %eax328 movl %eax, %cr3329 popl %eax330 movl %eax, %cr4331 332 #; UINT32 EFlags;333 popl 20(%ebp)334 335 #; UINT32 Ldtr, Tr;336 #; UINT32 Gdtr[2], Idtr[2];337 #; Best not let anyone mess with these particular registers...338 addl $24, %esp339 340 #; UINT32 Eip;341 popl 12(%ebp)342 343 #; UINT32 Gs, Fs, Es, Ds, Cs, Ss;344 #; NOTE - modified segment registers could hang the debugger... We345 #; could attempt to insulate ourselves against this possibility,346 #; but that poses risks as well.347 #;348 popl %gs349 popl %fs350 popl %es351 popl %ds352 popl 16(%ebp)353 popl %ss354 355 #; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;356 popl %edi357 popl %esi358 addl $4, %esp # not for ebp359 addl $4, %esp # not for esp360 popl %ebx361 popl %edx362 popl %ecx363 popl %eax364 365 movl %ebp, %esp366 popl %ebp367 addl $8, %esp368 iretl369 370 371 56 #END 372 57 -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm
r48674 r58459 2 2 ;------------------------------------------------------------------------------ 3 3 ;* 4 ;* Copyright (c) 2006 - 201 1, Intel Corporation. All rights reserved.<BR>4 ;* Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR> 5 5 ;* This program and the accompanying materials 6 6 ;* are licensed and made available under the terms and conditions of the BSD License … … 20 20 .model flat,C 21 21 .code 22 23 EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions24 25 ;26 ; point to the external interrupt vector table27 ;28 ExternalVectorTablePtr DWORD 029 30 InitializeExternalVectorTablePtr PROC PUBLIC31 mov eax, [esp+4]32 mov ExternalVectorTablePtr, eax33 ret34 InitializeExternalVectorTablePtr ENDP35 22 36 23 ;------------------------------------------------------------------------------ … … 68 55 SetDataSelectors ENDP 69 56 70 ;---------------------------------------;71 ; CommonInterruptEntry ;72 ;---------------------------------------;73 ; The follow algorithm is used for the common interrupt routine.74 75 CommonInterruptEntry PROC PUBLIC76 cli77 ;78 ; All interrupt handlers are invoked through interrupt gates, so79 ; IF flag automatically cleared at the entry point80 ;81 82 ;83 ; Calculate vector number84 ;85 ; Get the return address of call, actually, it is the86 ; address of vector number.87 ;88 xchg ecx, [esp]89 mov cx, [ecx]90 and ecx, 0FFFFh91 cmp ecx, 32 ; Intel reserved vector for exceptions?92 jae NoErrorCode93 bt mErrorCodeFlag, ecx94 jc HasErrorCode95 96 NoErrorCode:97 98 ;99 ; Stack:100 ; +---------------------+101 ; + EFlags +102 ; +---------------------+103 ; + CS +104 ; +---------------------+105 ; + EIP +106 ; +---------------------+107 ; + ECX +108 ; +---------------------+ <-- ESP109 ;110 ; Registers:111 ; ECX - Vector Number112 ;113 114 ;115 ; Put Vector Number on stack116 ;117 push ecx118 119 ;120 ; Put 0 (dummy) error code on stack, and restore ECX121 ;122 xor ecx, ecx ; ECX = 0123 xchg ecx, [esp+4]124 125 jmp ErrorCodeAndVectorOnStack126 127 HasErrorCode:128 129 ;130 ; Stack:131 ; +---------------------+132 ; + EFlags +133 ; +---------------------+134 ; + CS +135 ; +---------------------+136 ; + EIP +137 ; +---------------------+138 ; + Error Code +139 ; +---------------------+140 ; + ECX +141 ; +---------------------+ <-- ESP142 ;143 ; Registers:144 ; ECX - Vector Number145 ;146 147 ;148 ; Put Vector Number on stack and restore ECX149 ;150 xchg ecx, [esp]151 152 ;153 ; Fall through to join main routine code154 ; at ErrorCodeAndVectorOnStack155 ;156 @@:157 jmp @B158 159 ErrorCodeAndVectorOnStack:160 push ebp161 mov ebp, esp162 163 ;164 ; Stack:165 ; +---------------------+166 ; + EFlags +167 ; +---------------------+168 ; + CS +169 ; +---------------------+170 ; + EIP +171 ; +---------------------+172 ; + Error Code +173 ; +---------------------+174 ; + Vector Number +175 ; +---------------------+176 ; + EBP +177 ; +---------------------+ <-- EBP178 ;179 180 ;181 ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32182 ; is 16-byte aligned183 ;184 and esp, 0fffffff0h185 sub esp, 12186 187 ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;188 push eax189 push ecx190 push edx191 push ebx192 lea ecx, [ebp + 6 * 4]193 push ecx ; ESP194 push dword ptr [ebp] ; EBP195 push esi196 push edi197 198 ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;199 mov eax, ss200 push eax201 movzx eax, word ptr [ebp + 4 * 4]202 push eax203 mov eax, ds204 push eax205 mov eax, es206 push eax207 mov eax, fs208 push eax209 mov eax, gs210 push eax211 212 ;; UINT32 Eip;213 mov eax, [ebp + 3 * 4]214 push eax215 216 ;; UINT32 Gdtr[2], Idtr[2];217 sub esp, 8218 sidt [esp]219 mov eax, [esp + 2]220 xchg eax, [esp]221 and eax, 0FFFFh222 mov [esp+4], eax223 224 sub esp, 8225 sgdt [esp]226 mov eax, [esp + 2]227 xchg eax, [esp]228 and eax, 0FFFFh229 mov [esp+4], eax230 231 ;; UINT32 Ldtr, Tr;232 xor eax, eax233 str ax234 push eax235 sldt ax236 push eax237 238 ;; UINT32 EFlags;239 mov eax, [ebp + 5 * 4]240 push eax241 242 ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;243 mov eax, cr4244 or eax, 208h245 mov cr4, eax246 push eax247 mov eax, cr3248 push eax249 mov eax, cr2250 push eax251 xor eax, eax252 push eax253 mov eax, cr0254 push eax255 256 ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;257 mov eax, dr7258 push eax259 mov eax, dr6260 push eax261 mov eax, dr3262 push eax263 mov eax, dr2264 push eax265 mov eax, dr1266 push eax267 mov eax, dr0268 push eax269 270 ;; FX_SAVE_STATE_IA32 FxSaveState;271 sub esp, 512272 mov edi, esp273 db 0fh, 0aeh, 07h ;fxsave [edi]274 275 ;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear276 cld277 278 ;; UINT32 ExceptionData;279 push dword ptr [ebp + 2 * 4]280 281 ;; call into exception handler282 mov eax, ExternalVectorTablePtr ; get the interrupt vectors base283 or eax, eax ; NULL?284 jz nullExternalExceptionHandler285 286 mov ecx, [ebp + 4]287 mov eax, [eax + ecx * 4]288 or eax, eax ; NULL?289 jz nullExternalExceptionHandler290 291 ;; Prepare parameter and call292 mov edx, esp293 push edx294 mov edx, dword ptr [ebp + 1 * 4]295 push edx296 297 ;298 ; Call External Exception Handler299 ;300 call eax301 add esp, 8302 303 nullExternalExceptionHandler:304 305 cli306 ;; UINT32 ExceptionData;307 add esp, 4308 309 ;; FX_SAVE_STATE_IA32 FxSaveState;310 mov esi, esp311 db 0fh, 0aeh, 0eh ; fxrstor [esi]312 add esp, 512313 314 ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;315 ;; Skip restoration of DRx registers to support in-circuit emualators316 ;; or debuggers set breakpoint in interrupt/exception context317 add esp, 4 * 6318 319 ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;320 pop eax321 mov cr0, eax322 add esp, 4 ; not for Cr1323 pop eax324 mov cr2, eax325 pop eax326 mov cr3, eax327 pop eax328 mov cr4, eax329 330 ;; UINT32 EFlags;331 pop dword ptr [ebp + 5 * 4]332 333 ;; UINT32 Ldtr, Tr;334 ;; UINT32 Gdtr[2], Idtr[2];335 ;; Best not let anyone mess with these particular registers...336 add esp, 24337 338 ;; UINT32 Eip;339 pop dword ptr [ebp + 3 * 4]340 341 ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;342 ;; NOTE - modified segment registers could hang the debugger... We343 ;; could attempt to insulate ourselves against this possibility,344 ;; but that poses risks as well.345 ;;346 pop gs347 pop fs348 pop es349 pop ds350 pop dword ptr [ebp + 4 * 4]351 pop ss352 353 ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;354 pop edi355 pop esi356 add esp, 4 ; not for ebp357 add esp, 4 ; not for esp358 pop ebx359 pop edx360 pop ecx361 pop eax362 363 mov esp, ebp364 pop ebp365 add esp, 8366 iretd367 368 CommonInterruptEntry ENDP369 57 370 58 END -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/CpuDxe/X64/CpuAsm.S
r48674 r58459 3 3 #------------------------------------------------------------------------------ 4 4 #* 5 #* Copyright (c) 2008 - 201 1, Intel Corporation. All rights reserved.<BR>5 #* Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR> 6 6 #* This program and the accompanying materials 7 7 #* are licensed and made available under the terms and conditions of the BSD License … … 20 20 21 21 #text SEGMENT 22 23 24 #EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions25 26 27 #28 # point to the external interrupt vector table29 #30 ExternalVectorTablePtr:31 .byte 0, 0, 0, 0, 0, 0, 0, 032 33 ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)34 ASM_PFX(InitializeExternalVectorTablePtr):35 lea ExternalVectorTablePtr(%rip), %rax # save vector number36 mov %rcx, (%rax)37 ret38 22 39 23 … … 70 54 ret 71 55 72 #---------------------------------------;73 # CommonInterruptEntry ;74 #---------------------------------------;75 # The follow algorithm is used for the common interrupt routine.76 77 ASM_GLOBAL ASM_PFX(CommonInterruptEntry)78 ASM_PFX(CommonInterruptEntry):79 cli80 #81 # All interrupt handlers are invoked through interrupt gates, so82 # IF flag automatically cleared at the entry point83 #84 #85 # Calculate vector number86 #87 xchgq (%rsp), %rcx # get the return address of call, actually, it is the address of vector number.88 movzwl (%rcx), %ecx89 cmp $32, %ecx # Intel reserved vector for exceptions?90 jae NoErrorCode91 pushq %rax92 leaq ASM_PFX(mErrorCodeFlag)(%rip), %rax93 bt %ecx, (%rax)94 popq %rax95 jc CommonInterruptEntry_al_000096 97 NoErrorCode:98 99 #100 # Push a dummy error code on the stack101 # to maintain coherent stack map102 #103 pushq (%rsp)104 movq $0, 8(%rsp)105 CommonInterruptEntry_al_0000:106 pushq %rbp107 movq %rsp, %rbp108 109 #110 # Stack:111 # +---------------------+ <-- 16-byte aligned ensured by processor112 # + Old SS +113 # +---------------------+114 # + Old RSP +115 # +---------------------+116 # + RFlags +117 # +---------------------+118 # + CS +119 # +---------------------+120 # + RIP +121 # +---------------------+122 # + Error Code +123 # +---------------------+124 # + RCX / Vector Number +125 # +---------------------+126 # + RBP +127 # +---------------------+ <-- RBP, 16-byte aligned128 #129 130 131 #132 # Since here the stack pointer is 16-byte aligned, so133 # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64134 # is 16-byte aligned135 #136 137 #; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;138 #; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;139 pushq %r15140 pushq %r14141 pushq %r13142 pushq %r12143 pushq %r11144 pushq %r10145 pushq %r9146 pushq %r8147 pushq %rax148 pushq 8(%rbp) # RCX149 pushq %rdx150 pushq %rbx151 pushq 48(%rbp) # RSP152 pushq (%rbp) # RBP153 pushq %rsi154 pushq %rdi155 156 #; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero157 movzwq 56(%rbp), %rax158 pushq %rax # for ss159 movzwq 32(%rbp), %rax160 pushq %rax # for cs161 movl %ds, %eax162 pushq %rax163 movl %es, %eax164 pushq %rax165 movl %fs, %eax166 pushq %rax167 movl %gs, %eax168 pushq %rax169 170 movq %rcx, 8(%rbp) # save vector number171 172 #; UINT64 Rip;173 pushq 24(%rbp)174 175 #; UINT64 Gdtr[2], Idtr[2];176 xorq %rax, %rax177 pushq %rax178 pushq %rax179 sidt (%rsp)180 xchgq 2(%rsp), %rax181 xchgq (%rsp), %rax182 xchgq 8(%rsp), %rax183 184 xorq %rax, %rax185 pushq %rax186 pushq %rax187 sgdt (%rsp)188 xchgq 2(%rsp), %rax189 xchgq (%rsp), %rax190 xchgq 8(%rsp), %rax191 192 #; UINT64 Ldtr, Tr;193 xorq %rax, %rax194 str %ax195 pushq %rax196 sldt %ax197 pushq %rax198 199 #; UINT64 RFlags;200 pushq 40(%rbp)201 202 #; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;203 movq %cr8, %rax204 pushq %rax205 movq %cr4, %rax206 orq $0x208, %rax207 movq %rax, %cr4208 pushq %rax209 mov %cr3, %rax210 pushq %rax211 mov %cr2, %rax212 pushq %rax213 xorq %rax, %rax214 pushq %rax215 mov %cr0, %rax216 pushq %rax217 218 #; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;219 movq %dr7, %rax220 pushq %rax221 movq %dr6, %rax222 pushq %rax223 movq %dr3, %rax224 pushq %rax225 movq %dr2, %rax226 pushq %rax227 movq %dr1, %rax228 pushq %rax229 movq %dr0, %rax230 pushq %rax231 232 #; FX_SAVE_STATE_X64 FxSaveState;233 subq $512, %rsp234 movq %rsp, %rdi235 .byte 0x0f, 0x0ae, 0x07 #fxsave [rdi]236 237 #; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear238 cld239 240 #; UINT32 ExceptionData;241 pushq 16(%rbp)242 243 #; call into exception handler244 movq 8(%rbp), %rcx245 leaq ExternalVectorTablePtr(%rip), %rax246 movl (%eax), %eax247 movq (%rax,%rcx,8), %rax248 orq %rax, %rax # NULL?249 250 je nonNullValue#251 252 #; Prepare parameter and call253 # mov rcx, [rbp + 8]254 mov %rsp, %rdx255 #256 # Per X64 calling convention, allocate maximum parameter stack space257 # and make sure RSP is 16-byte aligned258 #259 subq $40, %rsp260 call *%rax261 addq $40, %rsp262 263 nonNullValue:264 cli265 #; UINT64 ExceptionData;266 addq $8, %rsp267 268 #; FX_SAVE_STATE_X64 FxSaveState;269 270 movq %rsp, %rsi271 .byte 0x0f, 0x0ae, 0x0E # fxrstor [rsi]272 addq $512, %rsp273 274 #; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;275 #; Skip restoration of DRx registers to support in-circuit emualators276 #; or debuggers set breakpoint in interrupt/exception context277 addq $48, %rsp278 279 #; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;280 popq %rax281 movq %rax, %cr0282 addq $8, %rsp # not for Cr1283 popq %rax284 movq %rax, %cr2285 popq %rax286 movq %rax, %cr3287 popq %rax288 movq %rax, %cr4289 popq %rax290 movq %rax, %cr8291 292 #; UINT64 RFlags;293 popq 40(%rbp)294 295 #; UINT64 Ldtr, Tr;296 #; UINT64 Gdtr[2], Idtr[2];297 #; Best not let anyone mess with these particular registers...298 addq $48, %rsp299 300 #; UINT64 Rip;301 popq 24(%rbp)302 303 #; UINT64 Gs, Fs, Es, Ds, Cs, Ss;304 popq %rax305 # mov %rax, %gs ; not for gs306 popq %rax307 # mov %rax, %fs ; not for fs308 # (X64 will not use fs and gs, so we do not restore it)309 popq %rax310 movl %eax, %es311 popq %rax312 movl %eax, %ds313 popq 32(%rbp) # for cs314 popq 56(%rbp) # for ss315 316 #; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;317 #; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;318 popq %rdi319 popq %rsi320 addq $8, %rsp # not for rbp321 popq 48(%rbp) # for rsp322 popq %rbx323 popq %rdx324 popq %rcx325 popq %rax326 popq %r8327 popq %r9328 popq %r10329 popq %r11330 popq %r12331 popq %r13332 popq %r14333 popq %r15334 335 movq %rbp, %rsp336 popq %rbp337 addq $16, %rsp338 iretq339 340 341 56 #text ENDS 342 57 -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/CpuDxe/X64/CpuAsm.asm
r48674 r58459 2 2 ;------------------------------------------------------------------------------ 3 3 ;* 4 ;* Copyright (c) 2008 - 201 1, Intel Corporation. All rights reserved.<BR>4 ;* Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR> 5 5 ;* This program and the accompanying materials 6 6 ;* are licensed and made available under the terms and conditions of the BSD License … … 18 18 19 19 .code 20 21 EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions22 23 ;24 ; point to the external interrupt vector table25 ;26 ExternalVectorTablePtr QWORD 027 28 InitializeExternalVectorTablePtr PROC PUBLIC29 mov ExternalVectorTablePtr, rcx30 ret31 InitializeExternalVectorTablePtr ENDP32 20 33 21 ;------------------------------------------------------------------------------ … … 63 51 SetDataSelectors ENDP 64 52 65 ;---------------------------------------;66 ; CommonInterruptEntry ;67 ;---------------------------------------;68 ; The follow algorithm is used for the common interrupt routine.69 70 CommonInterruptEntry PROC PUBLIC71 cli72 ;73 ; All interrupt handlers are invoked through interrupt gates, so74 ; IF flag automatically cleared at the entry point75 ;76 ;77 ; Calculate vector number78 ;79 xchg rcx, [rsp] ; get the return address of call, actually, it is the address of vector number.80 movzx ecx, word ptr [rcx]81 cmp ecx, 32 ; Intel reserved vector for exceptions?82 jae NoErrorCode83 bt mErrorCodeFlag, ecx84 jc @F85 86 NoErrorCode:87 88 ;89 ; Push a dummy error code on the stack90 ; to maintain coherent stack map91 ;92 push [rsp]93 mov qword ptr [rsp + 8], 094 @@:95 push rbp96 mov rbp, rsp97 98 ;99 ; Stack:100 ; +---------------------+ <-- 16-byte aligned ensured by processor101 ; + Old SS +102 ; +---------------------+103 ; + Old RSP +104 ; +---------------------+105 ; + RFlags +106 ; +---------------------+107 ; + CS +108 ; +---------------------+109 ; + RIP +110 ; +---------------------+111 ; + Error Code +112 ; +---------------------+113 ; + RCX / Vector Number +114 ; +---------------------+115 ; + RBP +116 ; +---------------------+ <-- RBP, 16-byte aligned117 ;118 119 120 ;121 ; Since here the stack pointer is 16-byte aligned, so122 ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64123 ; is 16-byte aligned124 ;125 126 ;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;127 ;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;128 push r15129 push r14130 push r13131 push r12132 push r11133 push r10134 push r9135 push r8136 push rax137 push qword ptr [rbp + 8] ; RCX138 push rdx139 push rbx140 push qword ptr [rbp + 48] ; RSP141 push qword ptr [rbp] ; RBP142 push rsi143 push rdi144 145 ;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero146 movzx rax, word ptr [rbp + 56]147 push rax ; for ss148 movzx rax, word ptr [rbp + 32]149 push rax ; for cs150 mov rax, ds151 push rax152 mov rax, es153 push rax154 mov rax, fs155 push rax156 mov rax, gs157 push rax158 159 mov [rbp + 8], rcx ; save vector number160 161 ;; UINT64 Rip;162 push qword ptr [rbp + 24]163 164 ;; UINT64 Gdtr[2], Idtr[2];165 xor rax, rax166 push rax167 push rax168 sidt [rsp]169 xchg rax, [rsp + 2]170 xchg rax, [rsp]171 xchg rax, [rsp + 8]172 173 xor rax, rax174 push rax175 push rax176 sgdt [rsp]177 xchg rax, [rsp + 2]178 xchg rax, [rsp]179 xchg rax, [rsp + 8]180 181 ;; UINT64 Ldtr, Tr;182 xor rax, rax183 str ax184 push rax185 sldt ax186 push rax187 188 ;; UINT64 RFlags;189 push qword ptr [rbp + 40]190 191 ;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;192 mov rax, cr8193 push rax194 mov rax, cr4195 or rax, 208h196 mov cr4, rax197 push rax198 mov rax, cr3199 push rax200 mov rax, cr2201 push rax202 xor rax, rax203 push rax204 mov rax, cr0205 push rax206 207 ;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;208 mov rax, dr7209 push rax210 mov rax, dr6211 push rax212 mov rax, dr3213 push rax214 mov rax, dr2215 push rax216 mov rax, dr1217 push rax218 mov rax, dr0219 push rax220 221 ;; FX_SAVE_STATE_X64 FxSaveState;222 sub rsp, 512223 mov rdi, rsp224 db 0fh, 0aeh, 07h ;fxsave [rdi]225 226 ;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear227 cld228 229 ;; UINT32 ExceptionData;230 push qword ptr [rbp + 16]231 232 ;; call into exception handler233 mov rcx, [rbp + 8]234 mov rax, ExternalVectorTablePtr ; get the interrupt vectors base235 mov rax, [rax + rcx * 8]236 or rax, rax ; NULL?237 238 je nonNullValue;239 240 ;; Prepare parameter and call241 ; mov rcx, [rbp + 8]242 mov rdx, rsp243 ;244 ; Per X64 calling convention, allocate maximum parameter stack space245 ; and make sure RSP is 16-byte aligned246 ;247 sub rsp, 4 * 8 + 8248 call rax249 add rsp, 4 * 8 + 8250 251 nonNullValue:252 cli253 ;; UINT64 ExceptionData;254 add rsp, 8255 256 ;; FX_SAVE_STATE_X64 FxSaveState;257 258 mov rsi, rsp259 db 0fh, 0aeh, 0Eh ; fxrstor [rsi]260 add rsp, 512261 262 ;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;263 ;; Skip restoration of DRx registers to support in-circuit emualators264 ;; or debuggers set breakpoint in interrupt/exception context265 add rsp, 8 * 6266 267 ;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;268 pop rax269 mov cr0, rax270 add rsp, 8 ; not for Cr1271 pop rax272 mov cr2, rax273 pop rax274 mov cr3, rax275 pop rax276 mov cr4, rax277 pop rax278 mov cr8, rax279 280 ;; UINT64 RFlags;281 pop qword ptr [rbp + 40]282 283 ;; UINT64 Ldtr, Tr;284 ;; UINT64 Gdtr[2], Idtr[2];285 ;; Best not let anyone mess with these particular registers...286 add rsp, 48287 288 ;; UINT64 Rip;289 pop qword ptr [rbp + 24]290 291 ;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;292 pop rax293 ; mov gs, rax ; not for gs294 pop rax295 ; mov fs, rax ; not for fs296 ; (X64 will not use fs and gs, so we do not restore it)297 pop rax298 mov es, rax299 pop rax300 mov ds, rax301 pop qword ptr [rbp + 32] ; for cs302 pop qword ptr [rbp + 56] ; for ss303 304 ;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;305 ;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;306 pop rdi307 pop rsi308 add rsp, 8 ; not for rbp309 pop qword ptr [rbp + 48] ; for rsp310 pop rbx311 pop rdx312 pop rcx313 pop rax314 pop r8315 pop r9316 pop r10317 pop r11318 pop r12319 pop r13320 pop r14321 pop r15322 323 mov rsp, rbp324 pop rbp325 add rsp, 16326 iretq327 328 CommonInterruptEntry ENDP329 330 53 END 331 54 -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.c
r48674 r58459 2 2 Produces the CPU I/O 2 Protocol. 3 3 4 Copyright (c) 2009 - 201 1, Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 117 117 // Check to see if Width is in the valid range 118 118 // 119 if ( Width < 0 ||Width >= EfiCpuIoWidthMaximum) {119 if ((UINT32)Width >= EfiCpuIoWidthMaximum) { 120 120 return EFI_INVALID_PARAMETER; 121 121 } -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
r48674 r58459 1 1 ## @file 2 # Produces the CPU I/O 2 Protocol .2 # Produces the CPU I/O 2 Protocol by using the services of the I/O Library. 3 3 # 4 # This DXE driver produces of the CPU I/O 2 Protocol, as introduced by PI 1.2. 5 # 6 # Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR> 4 # Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 7 5 # This program and the accompanying materials 8 6 # are licensed and made available under the terms and conditions of the BSD License … … 18 16 INF_VERSION = 0x00010005 19 17 BASE_NAME = CpuIo2Dxe 18 MODULE_UNI_FILE = CpuIo2Dxe.uni 20 19 FILE_GUID = A19B1FE7-C1BC-49F8-875F-54A5D542443F 21 20 MODULE_TYPE = DXE_DRIVER … … 48 47 [Depex] 49 48 TRUE 49 50 [UserExtensions.TianoCore."ExtraFiles"] 51 CpuIo2DxeExtra.uni -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.c
r48674 r58459 2 2 Produces the SMM CPU I/O Protocol. 3 3 4 Copyright (c) 2009 - 201 0, Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 83 83 // Check to see if Width is in the valid range 84 84 // 85 if ( Width < 0 ||Width > SMM_IO_UINT64) {85 if ((UINT32)Width > SMM_IO_UINT64) { 86 86 return EFI_INVALID_PARAMETER; 87 87 } -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
r48674 r58459 1 1 ## @file 2 # Module that produces the SMM CPU I/O 2 Protocol using the services of the I/O Library2 # Produces the SMM CPU I/O 2 Protocol by using the services of the I/O Library. 3 3 # 4 # Copyright (c) 2009 - 201 0, Intel Corporation. All rights reserved.<BR>4 # Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 5 5 # This program and the accompanying materials 6 6 # are licensed and made available under the terms and conditions of the BSD License … … 15 15 INF_VERSION = 0x00010005 16 16 BASE_NAME = CpuIo2Smm 17 MODULE_UNI_FILE = CpuIo2Smm.uni 17 18 FILE_GUID = A47EE2D8-F60E-42fd-8E58-7BD65EE4C29B 18 19 MODULE_TYPE = DXE_SMM_DRIVER … … 43 44 44 45 [Protocols] 45 gEfiSmmCpuIo2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED46 gEfiSmmCpuIo2ProtocolGuid ## PRODUCES 46 47 47 48 [Depex] 48 49 TRUE 50 51 [UserExtensions.TianoCore."ExtraFiles"] 52 CpuIo2SmmExtra.uni -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/CpuIoPei/CpuIoPei.c
r48674 r58459 2 2 Produces the CPU I/O PPI. 3 3 4 Copyright (c) 2009 - 201 0, Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 128 128 // Check to see if Width is in the valid range 129 129 // 130 if ( Width < 0 ||Width >= EfiPeiCpuIoWidthMaximum) {130 if ((UINT32)Width >= EfiPeiCpuIoWidthMaximum) { 131 131 return EFI_INVALID_PARAMETER; 132 132 } -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/CpuIoPei/CpuIoPei.inf
r48674 r58459 1 1 ## @file 2 # Produces the CPU I/O PPI .2 # Produces the CPU I/O PPI by using the services of the I/O Library. 3 3 # 4 # This PEIM produces of the CPU I/O PPI. 5 # 6 # Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR> 4 # Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 7 5 # This program and the accompanying materials 8 6 # are licensed and made available under the terms and conditions of the BSD License … … 18 16 INF_VERSION = 0x00010005 19 17 BASE_NAME = CpuIoPei 18 MODULE_UNI_FILE = CpuIoPei.uni 20 19 FILE_GUID = AE265864-CF5D-41a8-913D-71C155E76442 21 20 MODULE_TYPE = PEIM … … 44 43 45 44 [Ppis] 46 gEfiPeiCpuIoPpiInstalledGuid # PPI ALWAYS_PRODUCED45 gEfiPeiCpuIoPpiInstalledGuid ## PRODUCES 47 46 48 47 [Depex] 49 48 TRUE 49 50 [UserExtensions.TianoCore."ExtraFiles"] 51 CpuIoPeiExtra.uni -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/LocalApicLib.h
r48674 r58459 5 5 handles cases where local APIC is disabled. 6 6 7 Copyright (c) 2010 - 201 1, Intel Corporation. All rights reserved.<BR>7 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 8 8 This program and the accompanying materials 9 9 are licensed and made available under the terms and conditions of the BSD License … … 23 23 24 24 /** 25 Retrieve the base address of local APIC. 26 27 @return The base address of local APIC. 28 29 **/ 30 UINTN 31 EFIAPI 32 GetLocalApicBaseAddress ( 33 VOID 34 ); 35 36 /** 37 Set the base address of local APIC. 38 39 If BaseAddress is not aligned on a 4KB boundary, then ASSERT(). 40 41 @param[in] BaseAddress Local APIC base address to be set. 42 43 **/ 44 VOID 45 EFIAPI 46 SetLocalApicBaseAddress ( 47 IN UINTN BaseAddress 48 ); 49 50 /** 25 51 Get the current local APIC mode. 26 52 … … 43 69 44 70 @param ApicMode APIC mode to be set. 71 72 @note This API must not be called from an interrupt handler or SMI handler. 73 It may result in unpredictable behavior. 45 74 **/ 46 75 VOID … … 53 82 Get the initial local APIC ID of the executing processor assigned by hardware upon power on or reset. 54 83 55 In xAPIC mode, the initial local APIC ID is 8-bit, andmay be different from current APIC ID.84 In xAPIC mode, the initial local APIC ID may be different from current APIC ID. 56 85 In x2APIC mode, the local APIC ID can't be changed and there is no concept of initial APIC ID. In this case, 57 86 the 32-bit local APIC ID is returned as initial APIC ID. -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Register/LocalApic.h
r48674 r58459 2 2 IA32 Local APIC Definitions. 3 3 4 Copyright (c) 2010 - 201 1, Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 24 24 // Definitions for CPUID instruction 25 25 // 26 #define CPUID_SIGNATURE 0x0 26 27 #define CPUID_VERSION_INFO 0x1 28 #define CPUID_EXTENDED_TOPOLOGY 0xB 27 29 #define CPUID_EXTENDED_FUNCTION 0x80000000 28 30 #define CPUID_VIR_PHY_ADDRESS_SIZE 0x80000008 -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
r48674 r58459 1 1 ## @file 2 # This library defines some routines that are generic for IA32 family CPU 3 # to be UEFI specification compliant. 2 # This library defines some routines that are generic for IA32 family CPU. 4 3 # 5 # Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR> 4 # The library routines are UEFI specification compliant. 5 # 6 # Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 6 7 # This program and the accompanying materials 7 8 # are licensed and made available under the terms and conditions of the BSD License … … 17 18 INF_VERSION = 0x00010005 18 19 BASE_NAME = BaseUefiCpuLib 20 MODULE_UNI_FILE = BaseUefiCpuLib.uni 19 21 FILE_GUID = 34C24FD7-7A90-45c2-89FD-946473D9CE98 20 22 MODULE_TYPE = BASE -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.S
r48674 r58459 1 1 #------------------------------------------------------------------------------ 2 2 #* 3 #* Copyright (c) 2009 - 201 0, Intel Corporation. All rights reserved.<BR>3 #* Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> 4 4 #* This program and the accompanying materials 5 5 #* are licensed and made available under the terms and conditions of the BSD License … … 16 16 # Initializes floating point units for requirement of UEFI specification. 17 17 # 18 # This function initializes floating-point control word to 0x0 27F (all exceptions19 # masked,double- precision, round-to-nearest) and multimedia-extensions control word18 # This function initializes floating-point control word to 0x037F (all exceptions 19 # masked,double-extended-precision, round-to-nearest) and multimedia-extensions control word 20 20 # (if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero 21 21 # for masked underflow). … … 33 33 # all exceptions masked, double-precision, round-to-nearest 34 34 # 35 pushq $0x0 27F35 pushq $0x037F 36 36 lea (%rsp), %rax 37 37 fldcw (%rax) -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.asm
r48674 r58459 1 1 ;------------------------------------------------------------------------------ 2 2 ;* 3 ;* Copyright (c) 2009 , Intel Corporation. All rights reserved.<BR>3 ;* Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> 4 4 ;* This program and the accompanying materials 5 5 ;* are licensed and made available under the terms and conditions of the BSD License … … 17 17 ; 18 18 ; Float control word initial value: 19 ; all exceptions masked, double- precision, round-to-nearest19 ; all exceptions masked, double-extended-precision, round-to-nearest 20 20 ; 21 mFpuControlWord DW 0 27Fh21 mFpuControlWord DW 037Fh 22 22 ; 23 23 ; Multimedia-extensions control word: -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c
r48674 r58459 4 4 This local APIC library instance supports xAPIC mode only. 5 5 6 Copyright (c) 2010 - 201 1, Intel Corporation. All rights reserved.<BR>6 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 7 7 This program and the accompanying materials 8 8 are licensed and made available under the terms and conditions of the BSD License … … 22 22 #include <Library/IoLib.h> 23 23 #include <Library/TimerLib.h> 24 #include <Library/PcdLib.h>25 24 26 25 // 27 26 // Library internal functions 28 27 // 28 29 /** 30 Retrieve the base address of local APIC. 31 32 @return The base address of local APIC. 33 34 **/ 35 UINTN 36 EFIAPI 37 GetLocalApicBaseAddress ( 38 VOID 39 ) 40 { 41 MSR_IA32_APIC_BASE ApicBaseMsr; 42 43 ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS); 44 45 return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHigh, 32)) + 46 (((UINTN)ApicBaseMsr.Bits.ApicBaseLow) << 12); 47 } 48 49 /** 50 Set the base address of local APIC. 51 52 If BaseAddress is not aligned on a 4KB boundary, then ASSERT(). 53 54 @param[in] BaseAddress Local APIC base address to be set. 55 56 **/ 57 VOID 58 EFIAPI 59 SetLocalApicBaseAddress ( 60 IN UINTN BaseAddress 61 ) 62 { 63 MSR_IA32_APIC_BASE ApicBaseMsr; 64 65 ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0); 66 67 ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS); 68 69 ApicBaseMsr.Bits.ApicBaseLow = (UINT32) (BaseAddress >> 12); 70 ApicBaseMsr.Bits.ApicBaseHigh = (UINT32) (RShiftU64((UINT64) BaseAddress, 32)); 71 72 AsmWriteMsr64 (MSR_IA32_APIC_BASE_ADDRESS, ApicBaseMsr.Uint64); 73 } 29 74 30 75 /** … … 50 95 ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); 51 96 52 return MmioRead32 ( PcdGet32 (PcdCpuLocalApicBaseAddress) + MmioOffset);97 return MmioRead32 (GetLocalApicBaseAddress() + MmioOffset); 53 98 } 54 99 … … 77 122 ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); 78 123 79 MmioWrite32 ( PcdGet32 (PcdCpuLocalApicBaseAddress) + MmioOffset, Value);124 MmioWrite32 (GetLocalApicBaseAddress() + MmioOffset, Value); 80 125 } 81 126 … … 95 140 { 96 141 LOCAL_APIC_ICR_LOW IcrLowReg; 142 UINT32 IcrHigh; 143 BOOLEAN InterruptState; 97 144 98 145 ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); 99 146 ASSERT (ApicId <= 0xff); 100 147 101 // 102 // For xAPIC, the act of writing to the low doubleword of the ICR causes the IPI to be sent. 103 // 104 WriteLocalApicReg (XAPIC_ICR_HIGH_OFFSET, ApicId << 24); 105 WriteLocalApicReg (XAPIC_ICR_LOW_OFFSET, IcrLow); 148 InterruptState = SaveAndDisableInterrupts (); 149 150 // 151 // Save existing contents of ICR high 32 bits 152 // 153 IcrHigh = ReadLocalApicReg (XAPIC_ICR_HIGH_OFFSET); 154 155 // 156 // Wait for DeliveryStatus clear in case a previous IPI 157 // is still being sent 158 // 106 159 do { 107 160 IcrLowReg.Uint32 = ReadLocalApicReg (XAPIC_ICR_LOW_OFFSET); 108 161 } while (IcrLowReg.Bits.DeliveryStatus != 0); 162 163 // 164 // For xAPIC, the act of writing to the low doubleword of the ICR causes the IPI to be sent. 165 // 166 WriteLocalApicReg (XAPIC_ICR_HIGH_OFFSET, ApicId << 24); 167 WriteLocalApicReg (XAPIC_ICR_LOW_OFFSET, IcrLow); 168 169 // 170 // Wait for DeliveryStatus clear again 171 // 172 do { 173 IcrLowReg.Uint32 = ReadLocalApicReg (XAPIC_ICR_LOW_OFFSET); 174 } while (IcrLowReg.Bits.DeliveryStatus != 0); 175 176 // 177 // And restore old contents of ICR high 178 // 179 WriteLocalApicReg (XAPIC_ICR_HIGH_OFFSET, IcrHigh); 180 181 SetInterruptState (InterruptState); 182 109 183 } 110 184 … … 149 223 150 224 @param ApicMode APIC mode to be set. 225 226 @note This API must not be called from an interrupt handler or SMI handler. 227 It may result in unpredictable behavior. 151 228 **/ 152 229 VOID … … 163 240 Get the initial local APIC ID of the executing processor assigned by hardware upon power on or reset. 164 241 165 In xAPIC mode, the initial local APIC ID is 8-bit, andmay be different from current APIC ID.242 In xAPIC mode, the initial local APIC ID may be different from current APIC ID. 166 243 In x2APIC mode, the local APIC ID can't be changed and there is no concept of initial APIC ID. In this case, 167 244 the 32-bit local APIC ID is returned as initial APIC ID. … … 175 252 ) 176 253 { 254 UINT32 ApicId; 255 UINT32 MaxCpuIdIndex; 177 256 UINT32 RegEbx; 178 257 179 258 ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); 259 260 // 261 // Get the max index of basic CPUID 262 // 263 AsmCpuid (CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL); 264 265 // 266 // If CPUID Leaf B is supported, 267 // Then the initial 32-bit APIC ID = CPUID.0BH:EDX 268 // Else the initial 8-bit APIC ID = CPUID.1:EBX[31:24] 269 // 270 if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) { 271 AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 0, NULL, NULL, NULL, &ApicId); 272 return ApicId; 273 } 180 274 181 275 AsmCpuid (CPUID_VERSION_INFO, NULL, &RegEbx, NULL, NULL); … … 197 291 198 292 ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); 199 200 ApicId = ReadLocalApicReg (XAPIC_ID_OFFSET); 201 ApicId >>= 24; 293 294 if ((ApicId = GetInitialApicId ()) < 0x100) { 295 // 296 // If the initial local APIC ID is less 0x100, read APIC ID from 297 // XAPIC_ID_OFFSET, otherwise return the initial local APIC ID. 298 // 299 ApicId = ReadLocalApicReg (XAPIC_ID_OFFSET); 300 ApicId >>= 24; 301 } 202 302 return ApicId; 203 303 } … … 371 471 372 472 SendInitIpi (ApicId); 373 MicroSecondDelay ( 10);473 MicroSecondDelay (PcdGet32(PcdCpuInitIpiDelayInMicroSeconds)); 374 474 IcrLow.Uint32 = 0; 375 475 IcrLow.Bits.Vector = (StartupRoutine >> 12); … … 404 504 405 505 SendInitIpiAllExcludingSelf (); 406 MicroSecondDelay ( 10);506 MicroSecondDelay (PcdGet32(PcdCpuInitIpiDelayInMicroSeconds)); 407 507 IcrLow.Uint32 = 0; 408 508 IcrLow.Bits.Vector = (StartupRoutine >> 12); -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
r48674 r58459 1 1 ## @file 2 # Component description file for CPU Local APIC Library.2 # The Local Apic library supports xAPIC mode only. 3 3 # 4 # This library instance supports xAPIC mode only. 4 # Note: Local APIC library assumes local APIC is enabled. It does not handle cases 5 # where local APIC is disabled. 5 6 # 6 # Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>7 # Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR> 7 8 # This program and the accompanying materials 8 9 # are licensed and made available under the terms and conditions of the BSD License … … 18 19 INF_VERSION = 0x00010005 19 20 BASE_NAME = BaseXApicLib 21 MODULE_UNI_FILE = BaseXApicLib.uni 20 22 FILE_GUID = D87CA0A8-1AC2-439b-90F8-EF4A2AC88DAF 21 23 MODULE_TYPE = BASE … … 43 45 44 46 [Pcd] 45 gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress 46 47 gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds ## SOMETIMES_CONSUMES -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
r48674 r58459 5 5 which have xAPIC and x2APIC modes. 6 6 7 Copyright (c) 2010 - 201 1, Intel Corporation. All rights reserved.<BR>7 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 8 8 This program and the accompanying materials 9 9 are licensed and made available under the terms and conditions of the BSD License … … 23 23 #include <Library/IoLib.h> 24 24 #include <Library/TimerLib.h> 25 #include <Library/PcdLib.h>26 25 27 26 // 28 27 // Library internal functions 29 28 // 29 30 /** 31 Retrieve the base address of local APIC. 32 33 @return The base address of local APIC. 34 35 **/ 36 UINTN 37 EFIAPI 38 GetLocalApicBaseAddress ( 39 VOID 40 ) 41 { 42 MSR_IA32_APIC_BASE ApicBaseMsr; 43 44 ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS); 45 46 return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHigh, 32)) + 47 (((UINTN)ApicBaseMsr.Bits.ApicBaseLow) << 12); 48 } 49 50 /** 51 Set the base address of local APIC. 52 53 If BaseAddress is not aligned on a 4KB boundary, then ASSERT(). 54 55 @param[in] BaseAddress Local APIC base address to be set. 56 57 **/ 58 VOID 59 EFIAPI 60 SetLocalApicBaseAddress ( 61 IN UINTN BaseAddress 62 ) 63 { 64 MSR_IA32_APIC_BASE ApicBaseMsr; 65 66 ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0); 67 68 ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS); 69 70 ApicBaseMsr.Bits.ApicBaseLow = (UINT32) (BaseAddress >> 12); 71 ApicBaseMsr.Bits.ApicBaseHigh = (UINT32) (RShiftU64((UINT64) BaseAddress, 32)); 72 73 AsmWriteMsr64 (MSR_IA32_APIC_BASE_ADDRESS, ApicBaseMsr.Uint64); 74 } 30 75 31 76 /** … … 53 98 54 99 if (GetApicMode () == LOCAL_APIC_MODE_XAPIC) { 55 return MmioRead32 ( PcdGet32 (PcdCpuLocalApicBaseAddress) + MmioOffset);100 return MmioRead32 (GetLocalApicBaseAddress() + MmioOffset); 56 101 } else { 57 102 // … … 96 141 97 142 if (GetApicMode () == LOCAL_APIC_MODE_XAPIC) { 98 MmioWrite32 ( PcdGet32 (PcdCpuLocalApicBaseAddress) + MmioOffset, Value);143 MmioWrite32 (GetLocalApicBaseAddress() + MmioOffset, Value); 99 144 } else { 100 145 // … … 135 180 UINT64 MsrValue; 136 181 LOCAL_APIC_ICR_LOW IcrLowReg; 137 182 UINTN LocalApciBaseAddress; 183 UINT32 IcrHigh; 184 BOOLEAN InterruptState; 185 186 // 187 // Legacy APIC or X2APIC? 188 // 138 189 if (GetApicMode () == LOCAL_APIC_MODE_XAPIC) { 139 190 ASSERT (ApicId <= 0xff); 140 191 192 InterruptState = SaveAndDisableInterrupts (); 193 194 // 195 // Get base address of this LAPIC 196 // 197 LocalApciBaseAddress = GetLocalApicBaseAddress(); 198 199 // 200 // Save existing contents of ICR high 32 bits 201 // 202 IcrHigh = MmioRead32 (LocalApciBaseAddress + XAPIC_ICR_HIGH_OFFSET); 203 204 // 205 // Wait for DeliveryStatus clear in case a previous IPI 206 // is still being sent 207 // 208 do { 209 IcrLowReg.Uint32 = MmioRead32 (LocalApciBaseAddress + XAPIC_ICR_LOW_OFFSET); 210 } while (IcrLowReg.Bits.DeliveryStatus != 0); 211 141 212 // 142 213 // For xAPIC, the act of writing to the low doubleword of the ICR causes the IPI to be sent. 143 214 // 144 MmioWrite32 (PcdGet32 (PcdCpuLocalApicBaseAddress) + XAPIC_ICR_HIGH_OFFSET, ApicId << 24); 145 MmioWrite32 (PcdGet32 (PcdCpuLocalApicBaseAddress) + XAPIC_ICR_LOW_OFFSET, IcrLow); 215 MmioWrite32 (LocalApciBaseAddress + XAPIC_ICR_HIGH_OFFSET, ApicId << 24); 216 MmioWrite32 (LocalApciBaseAddress + XAPIC_ICR_LOW_OFFSET, IcrLow); 217 218 // 219 // Wait for DeliveryStatus clear again 220 // 146 221 do { 147 IcrLowReg.Uint32 = MmioRead32 ( PcdGet32 (PcdCpuLocalApicBaseAddress)+ XAPIC_ICR_LOW_OFFSET);222 IcrLowReg.Uint32 = MmioRead32 (LocalApciBaseAddress + XAPIC_ICR_LOW_OFFSET); 148 223 } while (IcrLowReg.Bits.DeliveryStatus != 0); 224 225 // 226 // And restore old contents of ICR high 227 // 228 MmioWrite32 (LocalApciBaseAddress + XAPIC_ICR_HIGH_OFFSET, IcrHigh); 229 230 SetInterruptState (InterruptState); 231 149 232 } else { 150 233 // … … 196 279 197 280 @param ApicMode APIC mode to be set. 281 282 @note This API must not be called from an interrupt handler or SMI handler. 283 It may result in unpredictable behavior. 198 284 **/ 199 285 VOID … … 244 330 Get the initial local APIC ID of the executing processor assigned by hardware upon power on or reset. 245 331 246 In xAPIC mode, the initial local APIC ID is 8-bit, andmay be different from current APIC ID.332 In xAPIC mode, the initial local APIC ID may be different from current APIC ID. 247 333 In x2APIC mode, the local APIC ID can't be changed and there is no concept of initial APIC ID. In this case, 248 334 the 32-bit local APIC ID is returned as initial APIC ID. … … 256 342 ) 257 343 { 344 UINT32 ApicId; 345 UINT32 MaxCpuIdIndex; 258 346 UINT32 RegEbx; 259 347 260 348 if (GetApicMode () == LOCAL_APIC_MODE_XAPIC) { 349 // 350 // Get the max index of basic CPUID 351 // 352 AsmCpuid (CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL); 353 // 354 // If CPUID Leaf B is supported, 355 // Then the initial 32-bit APIC ID = CPUID.0BH:EDX 356 // Else the initial 8-bit APIC ID = CPUID.1:EBX[31:24] 357 // 358 if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) { 359 AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 0, NULL, NULL, NULL, &ApicId); 360 return ApicId; 361 } 261 362 AsmCpuid (CPUID_VERSION_INFO, NULL, &RegEbx, NULL, NULL); 262 363 return RegEbx >> 24; … … 278 379 { 279 380 UINT32 ApicId; 381 UINT32 InitApicId; 280 382 281 383 ApicId = ReadLocalApicReg (XAPIC_ID_OFFSET); 282 384 if (GetApicMode () == LOCAL_APIC_MODE_XAPIC) { 283 ApicId >>= 24; 284 } 385 ApicId = ((InitApicId = GetInitialApicId ()) < 0x100) ? (ApicId >> 24) : InitApicId; 386 } 387 285 388 return ApicId; 286 389 } … … 454 557 455 558 SendInitIpi (ApicId); 456 MicroSecondDelay ( 10);559 MicroSecondDelay (PcdGet32(PcdCpuInitIpiDelayInMicroSeconds)); 457 560 IcrLow.Uint32 = 0; 458 561 IcrLow.Bits.Vector = (StartupRoutine >> 12); … … 487 590 488 591 SendInitIpiAllExcludingSelf (); 489 MicroSecondDelay ( 10);592 MicroSecondDelay (PcdGet32(PcdCpuInitIpiDelayInMicroSeconds)); 490 593 IcrLow.Uint32 = 0; 491 594 IcrLow.Bits.Vector = (StartupRoutine >> 12); -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
r48674 r58459 1 1 ## @file 2 # Component description file for CPU Local APIC Library.2 # The Local Apic library supports x2APIC capable processors which have xAPIC and x2APIC modes. 3 3 # 4 # This library instance supports x2APIC capable processors5 # wh ich have xAPIC and x2APIC modes.4 # Note: Local APIC library assumes local APIC is enabled. It does not handle cases 5 # where local APIC is disabled. 6 6 # 7 # Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>7 # Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR> 8 8 # This program and the accompanying materials 9 9 # are licensed and made available under the terms and conditions of the BSD License … … 19 19 INF_VERSION = 0x00010005 20 20 BASE_NAME = BaseXApicX2ApicLib 21 MODULE_UNI_FILE = BaseXApicX2ApicLib.uni 21 22 FILE_GUID = 967B6E05-F10D-4c10-8BF7-365291CA143F 22 23 MODULE_TYPE = BASE … … 44 45 45 46 [Pcd] 46 gUefiCpuPkgTokenSpaceGuid.PcdCpu LocalApicBaseAddress47 gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds ## SOMETIMES_CONSUMES 47 48 -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
r48674 r58459 2 2 MTRR setting library 3 3 4 Copyright (c) 2008 - 201 2, Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 20 20 #include <Library/BaseMemoryLib.h> 21 21 #include <Library/DebugLib.h> 22 23 // 24 // Context to save and restore when MTRRs are programmed 25 // 26 typedef struct { 27 UINTN Cr4; 28 BOOLEAN InterruptState; 29 } MTRR_CONTEXT; 22 30 23 31 // … … 167 175 disable cache, invalid cache and disable MTRR caching functionality 168 176 169 @ return CR4 value before changing.170 171 **/ 172 UINTN 177 @param[out] MtrrContext Pointer to context to save 178 179 **/ 180 VOID 173 181 PreMtrrChange ( 174 VOID 175 ) 176 { 177 UINTN Value; 178 182 OUT MTRR_CONTEXT *MtrrContext 183 ) 184 { 185 // 186 // Disable interrupts and save current interrupt state 187 // 188 MtrrContext->InterruptState = SaveAndDisableInterrupts(); 189 179 190 // 180 191 // Enter no fill cache mode, CD=1(Bit30), NW=0 (Bit29) … … 185 196 // Save original CR4 value and clear PGE flag (Bit 7) 186 197 // 187 Value= AsmReadCr4 ();188 AsmWriteCr4 ( Value& (~BIT7));198 MtrrContext->Cr4 = AsmReadCr4 (); 199 AsmWriteCr4 (MtrrContext->Cr4 & (~BIT7)); 189 200 190 201 // … … 197 208 // 198 209 AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 0); 199 200 //201 // Return original CR4 value202 //203 return Value;204 210 } 205 211 … … 210 216 Flush all TLBs, re-enable caching, restore CR4. 211 217 212 @param Cr4 CR4 valueto restore218 @param[in] MtrrContext Pointer to context to restore 213 219 214 220 **/ 215 221 VOID 216 222 PostMtrrChangeEnableCache ( 217 IN UINTN Cr4223 IN MTRR_CONTEXT *MtrrContext 218 224 ) 219 225 { … … 231 237 // Restore original CR4 value 232 238 // 233 AsmWriteCr4 (Cr4); 239 AsmWriteCr4 (MtrrContext->Cr4); 240 241 // 242 // Restore original interrupt state 243 // 244 SetInterruptState (MtrrContext->InterruptState); 234 245 } 235 246 … … 240 251 enable MTRR caching functionality, and enable cache 241 252 242 @param Cr4 CR4 valueto restore253 @param[in] MtrrContext Pointer to context to restore 243 254 244 255 **/ 245 256 VOID 246 257 PostMtrrChange ( 247 IN UINTN Cr4258 IN MTRR_CONTEXT *MtrrContext 248 259 ) 249 260 { … … 253 264 AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 3); 254 265 255 PostMtrrChangeEnableCache ( Cr4);266 PostMtrrChangeEnableCache (MtrrContext); 256 267 } 257 268 … … 705 716 ) 706 717 { 707 UINTN Index;708 UINTN Cr4;709 UINTN VariableMtrrCount;710 711 Cr4 = PreMtrrChange ();718 UINTN Index; 719 UINTN VariableMtrrCount; 720 MTRR_CONTEXT MtrrContext; 721 722 PreMtrrChange (&MtrrContext); 712 723 Index = 0; 713 724 VariableMtrrCount = GetVariableMtrrCount (); … … 720 731 Index ++; 721 732 } 722 PostMtrrChange ( Cr4);733 PostMtrrChange (&MtrrContext); 723 734 } 724 735 … … 745 756 ) 746 757 { 747 UINT64 TempQword;748 UINTN Cr4;749 750 Cr4 = PreMtrrChange ();758 UINT64 TempQword; 759 MTRR_CONTEXT MtrrContext; 760 761 PreMtrrChange (&MtrrContext); 751 762 752 763 // … … 765 776 ); 766 777 767 PostMtrrChange ( Cr4);778 PostMtrrChange (&MtrrContext); 768 779 } 769 780 … … 798 809 // no mtrr covers the range 799 810 // 800 return CacheUncacheable;811 return MtrrGetDefaultMemoryType (); 801 812 } 802 813 } … … 954 965 UINT64 MtrrValidBitsMask; 955 966 UINT64 MtrrValidAddressMask; 956 UINTN Cr4;957 967 BOOLEAN OverwriteExistingMtrr; 958 968 UINT32 FirmwareVariableMtrrCount; 959 969 UINT32 VariableMtrrEnd; 970 MTRR_CONTEXT MtrrContext; 960 971 961 972 DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length)); … … 996 1007 Status = RETURN_SUCCESS; 997 1008 while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) { 998 Cr4 = PreMtrrChange ();1009 PreMtrrChange (&MtrrContext); 999 1010 Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length); 1000 PostMtrrChange ( Cr4);1011 PostMtrrChange (&MtrrContext); 1001 1012 if (RETURN_ERROR (Status)) { 1002 1013 goto Done; … … 1354 1365 ) 1355 1366 { 1356 UINTN Cr4;1367 MTRR_CONTEXT MtrrContext; 1357 1368 1358 1369 if (!IsMtrrSupported ()) { … … 1360 1371 } 1361 1372 1362 Cr4 = PreMtrrChange ();1373 PreMtrrChange (&MtrrContext); 1363 1374 MtrrSetVariableMtrrWorker (VariableSettings); 1364 PostMtrrChange ( Cr4);1375 PostMtrrChange (&MtrrContext); 1365 1376 return VariableSettings; 1366 1377 } … … 1431 1442 ) 1432 1443 { 1433 UINTN Cr4;1444 MTRR_CONTEXT MtrrContext; 1434 1445 1435 1446 if (!IsMtrrSupported ()) { … … 1437 1448 } 1438 1449 1439 Cr4 = PreMtrrChange ();1450 PreMtrrChange (&MtrrContext); 1440 1451 MtrrSetFixedMtrrWorker (FixedSettings); 1441 PostMtrrChange ( Cr4);1452 PostMtrrChange (&MtrrContext); 1442 1453 1443 1454 return FixedSettings; … … 1496 1507 ) 1497 1508 { 1498 UINTN Cr4;1509 MTRR_CONTEXT MtrrContext; 1499 1510 1500 1511 if (!IsMtrrSupported ()) { … … 1502 1513 } 1503 1514 1504 Cr4 = PreMtrrChange ();1515 PreMtrrChange (&MtrrContext); 1505 1516 1506 1517 // … … 1519 1530 AsmWriteMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, MtrrSetting->MtrrDefType); 1520 1531 1521 PostMtrrChangeEnableCache ( Cr4);1532 PostMtrrChangeEnableCache (&MtrrContext); 1522 1533 1523 1534 return MtrrSetting; … … 1599 1610 VariableMtrrCount = GetVariableMtrrCount (); 1600 1611 1612 Limit = BIT36 - 1; 1613 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); 1614 if (RegEax >= 0x80000008) { 1615 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); 1616 Limit = LShiftU64 (1, RegEax & 0xff) - 1; 1617 } 1601 1618 Base = BASE_1MB; 1602 1619 PreviousMemoryType = MTRR_CACHE_INVALID_TYPE; … … 1617 1634 RangeBase = BASE_1MB; 1618 1635 NoRangeBase = BASE_1MB; 1619 Limit = BIT36 - 1;1620 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);1621 if (RegEax >= 0x80000008) {1622 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);1623 Limit = LShiftU64 (1, RegEax & 0xff) - 1;1624 }1625 1636 RangeLimit = Limit; 1626 1637 NoRangeLimit = Limit; … … 1666 1677 Base = NoRangeLimit + 1; 1667 1678 } 1668 } while ( Found);1679 } while (Base < Limit); 1669 1680 DEBUG((DEBUG_CACHE, "%016lx\n\n", Base - 1)); 1670 1681 ); -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
r48674 r58459 1 1 ## @file 2 # MTRR library provides API for MTRR operation2 # MTRR library provides APIs for MTRR operation. 3 3 # 4 # Copyright (c) 2006 - 201 0, Intel Corporation. All rights reserved.<BR>4 # Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR> 5 5 # This program and the accompanying materials 6 6 # are licensed and made available under the terms and conditions of the BSD License … … 16 16 INF_VERSION = 0x00010005 17 17 BASE_NAME = MtrrLib 18 MODULE_UNI_FILE = MtrrLib.uni 18 19 FILE_GUID = 6826b408-f4f3-47ee-917f-af7047f9d937 19 20 MODULE_TYPE = BASE … … 39 40 BaseLib 40 41 CpuLib 42 DebugLib 41 43 -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf
r48674 r58459 14 14 # that it uses the local APIC library so that it supports x2APIC mode. 15 15 # 16 # Copyright (c) 2010 - 201 1, Intel Corporation. All rights reserved.<BR>16 # Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR> 17 17 # 18 18 # This program and the accompanying materials … … 29 29 INF_VERSION = 0x00010005 30 30 BASE_NAME = SecPeiDxeTimerLibUefiCpu 31 MODULE_UNI_FILE = SecPeiDxeTimerLibUefiCpu.uni 31 32 FILE_GUID = 4FFF2014-2086-4ee6-9B58-886D1967861C 32 33 MODULE_TYPE = BASE … … 63 64 64 65 [Pcd.IA32, Pcd.X64] 65 gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## CONSUMES66 gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## SOMETIMES_CONSUMES 66 67 -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c
r48674 r58459 4 4 This library uses the local APIC library so that it supports x2APIC mode. 5 5 6 Copyright (c) 2010 - 201 1, Intel Corporation. All rights reserved.<BR>6 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR> 7 7 This program and the accompanying materials 8 8 are licensed and made available under the terms and conditions of the BSD License … … 56 56 { 57 57 INT32 Ticks; 58 UINT32 PowerOfTwoCounter; 59 60 // 61 // The target timer count is calculated here 62 // 63 Ticks = GetApicTimerCurrentCount () - Delay; 64 65 // 66 // Wait until time out 67 // Delay > 2^31 could not be handled by this function 68 // Timer wrap-arounds are handled correctly by this function 69 // 70 PowerOfTwoCounter = GetPowerOfTwo32 (GetApicTimerInitCount ()); 71 while (((UINT32)(GetApicTimerCurrentCount () - Ticks) & PowerOfTwoCounter) == 0) { 72 CpuPause (); 73 } 58 UINT32 Times; 59 UINT32 InitCount; 60 UINT32 StartTick; 61 62 // 63 // In case Delay is too larger, separate it into several small delay slot. 64 // Devided Delay by half value of Init Count is to avoid Delay close to 65 // the Init Count, timeout maybe missing if the time consuming between 2 66 // GetApicTimerCurrentCount() invoking is larger than the time gap between 67 // Delay and the Init Count. 68 // 69 InitCount = GetApicTimerInitCount (); 70 Times = Delay / (InitCount / 2); 71 Delay = Delay % (InitCount / 2); 72 73 // 74 // Get Start Tick and do delay 75 // 76 StartTick = GetApicTimerCurrentCount (); 77 do { 78 // 79 // Wait until time out by Delay value 80 // 81 do { 82 CpuPause (); 83 // 84 // Get Ticks from Start to Current. 85 // 86 Ticks = StartTick - GetApicTimerCurrentCount (); 87 // 88 // Ticks < 0 means Timer wrap-arounds happens. 89 // 90 if (Ticks < 0) { 91 Ticks += InitCount; 92 } 93 } while ((UINT32)Ticks < Delay); 94 95 // 96 // Update StartTick and Delay for next delay slot 97 // 98 StartTick -= (StartTick > Delay) ? Delay : (Delay - InitCount); 99 Delay = InitCount / 2; 100 } while (Times-- > 0); 74 101 } 75 102 … … 182 209 if (StartValue != NULL) { 183 210 *StartValue = (UINT64)GetApicTimerInitCount (); 184 //185 // make sure StartValue is all 1s from High Bit186 //187 ASSERT ((*StartValue & (*StartValue + 1)) == 0);188 211 } 189 212 -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
r48674 r58459 2 2 # Reset Vector binary 3 3 # 4 # Copyright (c) 2006 - 201 0, Intel Corporation. All rights reserved.<BR>4 # Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR> 5 5 # 6 6 # This program and the accompanying materials … … 16 16 INF_VERSION = 0x00010005 17 17 BASE_NAME = ResetVector 18 MODULE_UNI_FILE = ResetVector.uni 18 19 FILE_GUID = 1BA0062E-C779-4582-8566-336AE8F78F09 19 20 MODULE_TYPE = SEC … … 40 41 #!endif 41 42 43 [UserExtensions.TianoCore."ExtraFiles"] 44 ResetVectorExtra.uni -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/ResetVector/Vtf0/Build.py
r48674 r58459 42 42 '-D', 'DEBUG_%s' % str(debugType).upper(), 43 43 '-o', output, 44 ' ResetVectorCode.asm',44 'Vtf0.nasmb', 45 45 ) 46 46 ret = RunCommand(commandLine) -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm
r48674 r58459 1 1 ;------------------------------------------------------------------------------ 2 2 ; @file 3 ; First code exec tuted by processor after resetting.3 ; First code executed by processor after resetting. 4 4 ; 5 ; Copyright (c) 2008 - 201 1, Intel Corporation. All rights reserved.<BR>5 ; Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> 6 6 ; This program and the accompanying materials 7 7 ; are licensed and made available under the terms and conditions of the BSD License … … 18 18 ALIGN 16 19 19 20 ; 21 ; Pad the image size to 4k when page tables are in VTF0 22 ; 23 ; If the VTF0 image has page tables built in, then we need to make 24 ; sure the end of VTF0 is 4k above where the page tables end. 25 ; 26 ; This is required so the page tables will be 4k aligned when VTF0 is 27 ; located just below 0x100000000 (4GB) in the firmware device. 28 ; 29 %ifdef ALIGN_TOP_TO_4K_FOR_PAGING 30 TIMES (0x1000 - ($ - EndOfPageTables) - 0x20) DB 0 31 %endif 32 20 33 applicationProcessorEntryPoint: 21 34 ; … … 26 39 ; used to wake up the application processors. 27 40 ; 28 jmp shortEarlyApInitReal1641 jmp EarlyApInitReal16 29 42 30 43 ALIGN 8 … … 51 64 nop 52 65 nop 53 jmp shortEarlyBspInitReal1666 jmp EarlyBspInitReal16 54 67 55 68 ALIGN 16 -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/ResetVector/Vtf0/Ia32/Flat32ToFlat64.asm
r48674 r58459 3 3 ; Transition from 32 bit flat protected mode into 64 bit flat protected mode 4 4 ; 5 ; Copyright (c) 2008 - 20 09, Intel Corporation. All rights reserved.<BR>5 ; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR> 6 6 ; This program and the accompanying materials 7 7 ; are licensed and made available under the terms and conditions of the BSD License … … 100 100 mov eax, VBOX_PML4_ADDR 101 101 %endif 102 mov cr3, eax102 OneTimeCall SetCr3ForPageTables64 103 103 104 104 mov eax, cr4 -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/ResetVector/Vtf0/Tools/FixupForRawSection.py
r48674 r58459 16 16 17 17 18 # VBox - begin 19 #filename = sys.argv[1] - VBox changed it to: 20 OnlyPaddImage = (sys.argv[1] == '--only-padd-image'); 21 SrcFilename = sys.argv[1 + OnlyPaddImage] 22 DstFilename = sys.argv[2 + OnlyPaddImage] 23 if len(sys.argv) > 3 + OnlyPaddImage: 24 raise Exception("Too many arguments"); 25 # VBox - end 26 27 #if filename.lower().find('ia32') >= 0: - VBox changed it to: 28 if OnlyPaddImage: 29 #d = open(sys.argv[1], 'rb').read() - VBox changed it to: 30 d = open(SrcFilename, 'rb').read() 31 c = ((len(d) + 4 + 7) & ~7) - 4 32 if c > len(d): 33 c -= len(d) 34 #f = open(sys.argv[1], 'wb') - VBox changed it to: 35 f = open(DstFilename, 'wb') 36 f.write('\x90' * c) 37 f.write(d) 38 f.close() 39 else: 40 from struct import pack 41 42 PAGE_PRESENT = 0x01 43 PAGE_READ_WRITE = 0x02 44 PAGE_USER_SUPERVISOR = 0x04 45 PAGE_WRITE_THROUGH = 0x08 46 PAGE_CACHE_DISABLE = 0x010 47 PAGE_ACCESSED = 0x020 48 PAGE_DIRTY = 0x040 49 PAGE_PAT = 0x080 50 PAGE_GLOBAL = 0x0100 51 PAGE_2M_MBO = 0x080 52 PAGE_2M_PAT = 0x01000 53 54 def NopAlign4k(s): 55 c = ((len(s) + 0xfff) & ~0xfff) - len(s) 56 return ('\x90' * c) + s 57 58 def PageDirectoryEntries4GbOf2MbPages(baseAddress): 59 60 s = '' 61 for i in range(0x800): 62 i = ( 63 baseAddress + long(i << 21) + 64 PAGE_2M_MBO + 65 PAGE_CACHE_DISABLE + 66 PAGE_ACCESSED + 67 PAGE_DIRTY + 68 PAGE_READ_WRITE + 69 PAGE_PRESENT 70 ) 71 s += pack('Q', i) 72 return s 73 74 def PageDirectoryPointerTable4GbOf2MbPages(pdeBase): 75 s = '' 76 for i in range(0x200): 77 i = ( 78 pdeBase + 79 (min(i, 3) << 12) + 80 PAGE_CACHE_DISABLE + 81 PAGE_ACCESSED + 82 PAGE_READ_WRITE + 83 PAGE_PRESENT 84 ) 85 s += pack('Q', i) 86 return s 87 88 def PageMapLevel4Table4GbOf2MbPages(pdptBase): 89 s = '' 90 for i in range(0x200): 91 i = ( 92 pdptBase + 93 (min(i, 0) << 12) + 94 PAGE_CACHE_DISABLE + 95 PAGE_ACCESSED + 96 PAGE_READ_WRITE + 97 PAGE_PRESENT 98 ) 99 s += pack('Q', i) 100 return s 101 102 def First4GbPageEntries(topAddress): 103 PDE = PageDirectoryEntries4GbOf2MbPages(0L) 104 pml4tBase = topAddress - 0x1000 105 pdptBase = pml4tBase - 0x1000 106 pdeBase = pdptBase - len(PDE) 107 PDPT = PageDirectoryPointerTable4GbOf2MbPages(pdeBase) 108 PML4T = PageMapLevel4Table4GbOf2MbPages(pdptBase) 109 return PDE + PDPT + PML4T 110 111 def AlignAndAddPageTables(): 112 #d = open(sys.argv[1], 'rb').read() - VBox changed it to: 113 d = open(SrcFilename, 'rb').read() 114 code = NopAlign4k(d) 115 topAddress = 0x100000000 - len(code) 116 d = ('\x90' * 4) + First4GbPageEntries(topAddress) + code 117 #f = open(sys.argv[1], 'wb') - VBox changed it to: 118 f = open(DstFilename, 'wb') 119 f.write(d) 120 f.close() 121 122 AlignAndAddPageTables() 123 18 d = open(sys.argv[1], 'rb').read() 19 c = ((len(d) + 4 + 7) & ~7) - 4 20 if c > len(d): 21 c -= len(d) 22 # VBox begin 23 # Original: f = open(sys.argv[1], 'wb'), changed to: 24 f = open(sys.argv[2], 'wb') 25 # VBox end 26 f.write('\x90' * c) 27 f.write(d) 28 f.close() -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/UefiCpuPkg.dec
r48674 r58459 1 1 ## @file UefiCpuPkg.dec 2 #3 2 # This Package provides UEFI compatible CPU modules and libraries. 4 3 # 5 # Copyright (c) 2007 - 201 1, Intel Corporation. All rights reserved.<BR>4 # Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> 6 5 # 7 6 # This program and the accompanying materials are licensed and made available under … … 18 17 DEC_SPECIFICATION = 0x00010005 19 18 PACKAGE_NAME = UefiCpuPkg 19 PACKAGE_UNI_FILE = UefiCpuPkg.uni 20 20 PACKAGE_GUID = 2171df9b-0d39-45aa-ac37-2de190010d23 21 PACKAGE_VERSION = 0. 221 PACKAGE_VERSION = 0.3 22 22 23 23 [Includes] … … 42 42 gUefiCpuPkgTokenSpaceGuid = { 0xac05bf33, 0x995a, 0x4ed4, { 0xaa, 0xb8, 0xef, 0x7a, 0xe8, 0xf, 0x5c, 0xb0 }} 43 43 44 # 45 # [Error.gUefiCpuPkgTokenSpaceGuid] 46 # 0x80000001 | Invalid value provided. 47 # 48 44 49 [PcdsFixedAtBuild, PcdsPatchableInModule] 50 ## This value is the CPU Local Apic base address, which aligns the address on a 4-KByte boundary. 51 # @Prompt Configure base address of CPU Local Apic 52 # @Expression 0x80000001 | (gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress & 0xfff) == 0 45 53 gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress|0xfee00000|UINT32|0x00000001 54 ## Specifies delay value in microseconds after sending out an INIT IPI. 55 # @Prompt Configure delay value after send an INIT IPI 56 gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds|10000|UINT32|0x30000002 46 57 58 [UserExtensions.TianoCore."ExtraFiles"] 59 UefiCpuPkgExtra.uni -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/UefiCpuPkg.dsc
r48674 r58459 2 2 # UefiCpuPkg Package 3 3 # 4 # Copyright (c) 2007 - 201 1, Intel Corporation. All rights reserved.<BR>4 # Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> 5 5 # 6 6 # This program and the accompanying materials … … 17 17 PLATFORM_NAME = UefiCpu 18 18 PLATFORM_GUID = a1b7be22-78b3-4260-9569-8649e8c17d49 19 PLATFORM_VERSION = 0. 219 PLATFORM_VERSION = 0.3 20 20 DSC_SPECIFICATION = 0x00010005 21 21 OUTPUT_DIRECTORY = Build/UefiCpu … … 35 35 DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf 36 36 DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf 37 UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf 37 38 IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf 38 39 MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf … … 50 51 DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf 51 52 LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf 52 ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf 53 ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf 54 CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf 53 55 54 56 [LibraryClasses.common.PEIM] … … 86 88 UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf 87 89 UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf 90 UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf 91 UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf 92 UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf 88 93 UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf 89 94 -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c
r48674 r58459 1 1 /** @file 2 This module produces the EFI_PEI_S3_RESUME _PPI.2 This module produces the EFI_PEI_S3_RESUME2_PPI. 3 3 This module works with StandAloneBootScriptExecutor to S3 resume to OS. 4 4 This module will excute the boot script saved during last boot and after that, 5 5 control is passed to OS waking up handler. 6 6 7 Copyright (c) 2006 - 201 1, Intel Corporation. All rights reserved.<BR>7 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR> 8 8 9 9 This program and the accompanying materials … … 48 48 #include <Library/LockBoxLib.h> 49 49 #include <IndustryStandard/Acpi.h> 50 51 /** 52 This macro aligns the address of a variable with auto storage 53 duration down to CPU_STACK_ALIGNMENT. 54 55 Since the stack grows downward, the result preserves more of the 56 stack than the original address (or the same amount), not less. 57 **/ 58 #define STACK_ALIGN_DOWN(Ptr) \ 59 ((UINTN)(Ptr) & ~(UINTN)(CPU_STACK_ALIGNMENT - 1)) 50 60 51 61 #pragma pack(1) … … 194 204 ); 195 205 206 /** 207 Set data segment selectors value including DS/ES/FS/GS/SS. 208 209 @param[in] SelectorValue Segment selector value to be set. 210 211 **/ 212 VOID 213 EFIAPI 214 AsmSetDataSelectors ( 215 IN UINT16 SelectorValue 216 ); 217 196 218 // 197 219 // Globals … … 232 254 /* 0x40 */ {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 233 255 }; 256 257 #define DATA_SEGEMENT_SELECTOR 0x18 234 258 235 259 // … … 285 309 (VOID **) &VariableServices 286 310 ); 287 ASSERT_EFI_ERROR (Status); 311 if (EFI_ERROR (Status)) { 312 return; 313 } 288 314 289 315 VarSize = sizeof (EFI_PHYSICAL_ADDRESS); … … 342 368 } else { 343 369 AsciiStrnCpy (PerfData->Token, Token, PERF_TOKEN_LENGTH); 370 PerfData->Token[PERF_TOKEN_LENGTH] = '\0'; 344 371 } 345 372 if (StartTicker == 1) { … … 364 391 } 365 392 PerfHeader->S3EntryNum = (UINT32) Index; 393 } 394 395 /** 396 The function will check if current waking vector is long mode. 397 398 @param AcpiS3Context a pointer to a structure of ACPI_S3_CONTEXT 399 400 @retval TRUE Current context need long mode waking vector. 401 @retval FALSE Current context need not long mode waking vector. 402 **/ 403 BOOLEAN 404 IsLongModeWakingVector ( 405 IN ACPI_S3_CONTEXT *AcpiS3Context 406 ) 407 { 408 EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs; 409 410 Facs = (EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) ((UINTN) (AcpiS3Context->AcpiFacsTable)); 411 if ((Facs == NULL) || 412 (Facs->Signature != EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) || 413 ((Facs->FirmwareWakingVector == 0) && (Facs->XFirmwareWakingVector == 0)) ) { 414 // Something wrong with FACS 415 return FALSE; 416 } 417 if (Facs->XFirmwareWakingVector != 0) { 418 if ((Facs->Version == EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) && 419 ((Facs->Flags & EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F) != 0) && 420 ((Facs->Flags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0)) { 421 // Both BIOS and OS wants 64bit vector 422 if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { 423 return TRUE; 424 } 425 } 426 } 427 return FALSE; 366 428 } 367 429 … … 391 453 AsmWriteIdtr (&PeiS3ResumeState->Idtr); 392 454 455 if (PeiS3ResumeState->ReturnStatus != EFI_SUCCESS) { 456 // 457 // Report Status code that boot script execution is failed 458 // 459 REPORT_STATUS_CODE ( 460 EFI_ERROR_CODE | EFI_ERROR_MINOR, 461 (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_BOOT_SCRIPT_ERROR) 462 ); 463 } 464 465 // 466 // NOTE: Because Debug Timer interrupt and system interrupts will be disabled 467 // in BootScriptExecuteDxe, the rest code in S3ResumeBootOs() cannot be halted 468 // by soft debugger. 469 // 470 471 PERF_END (NULL, "ScriptExec", NULL, 0); 472 393 473 // 394 474 // Install BootScriptDonePpi … … 405 485 (Facs->Signature != EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) || 406 486 ((Facs->FirmwareWakingVector == 0) && (Facs->XFirmwareWakingVector == 0)) ) { 487 // 488 // Report Status code that no valid vector is found 489 // 490 REPORT_STATUS_CODE ( 491 EFI_ERROR_CODE | EFI_ERROR_MAJOR, 492 (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR) 493 ); 407 494 CpuDeadLoop (); 408 495 return ; … … 410 497 411 498 // 412 // report status code on S3 resume413 //414 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_OS_WAKE);415 416 //417 499 // Install EndOfPeiPpi 418 500 // 419 501 Status = PeiServicesInstallPpi (&mPpiListEndOfPeiTable); 420 502 ASSERT_EFI_ERROR (Status); 503 504 // 505 // report status code on S3 resume 506 // 507 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_OS_WAKE); 421 508 422 509 PERF_CODE ( … … 446 533 ); 447 534 } else { 535 // 536 // Report Status code that no valid waking vector is found 537 // 538 REPORT_STATUS_CODE ( 539 EFI_ERROR_CODE | EFI_ERROR_MAJOR, 540 (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR) 541 ); 448 542 DEBUG (( EFI_D_ERROR, "Unsupported for 32bit DXE transfer to 64bit OS waking vector!\r\n")); 449 543 ASSERT (FALSE); 544 CpuDeadLoop (); 545 return ; 450 546 } 451 547 } else { … … 470 566 471 567 // 568 // Report Status code the failure of S3Resume 569 // 570 REPORT_STATUS_CODE ( 571 EFI_ERROR_CODE | EFI_ERROR_MAJOR, 572 (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR) 573 ); 574 575 // 472 576 // Never run to here 473 577 // … … 480 584 481 585 @param S3NvsPageTableAddress PageTableAddress in ACPINvs 586 @param Build4GPageTableOnly If BIOS just build 4G page table only 482 587 **/ 483 588 VOID 484 589 RestoreS3PageTables ( 485 IN UINTN S3NvsPageTableAddress 590 IN UINTN S3NvsPageTableAddress, 591 IN BOOLEAN Build4GPageTableOnly 486 592 ) 487 593 { … … 510 616 // The assumption is : whole page table is allocated in CONTINOUS memory and CR3 points to TOP page. 511 617 // 512 DEBUG ((EFI_D_ERROR, "S3NvsPageTableAddress - %x \n", S3NvsPageTableAddress));618 DEBUG ((EFI_D_ERROR, "S3NvsPageTableAddress - %x (%x)\n", (UINTN)S3NvsPageTableAddress, (UINTN)Build4GPageTableOnly)); 513 619 514 620 // … … 553 659 } 554 660 661 // 662 // NOTE: In order to save time to create full page table, we just create 4G page table by default. 663 // And let PF handler in BootScript driver to create more on request. 664 // 665 if (Build4GPageTableOnly) { 666 PhysicalAddressBits = 32; 667 ZeroMem (PageMap, EFI_PAGES_TO_SIZE(2)); 668 } 555 669 // 556 670 // Calculate the table entries needed. … … 653 767 VOID *IdtBuffer; 654 768 PEI_S3_RESUME_STATE *PeiS3ResumeState; 769 BOOLEAN InterruptStatus; 655 770 656 771 DEBUG ((EFI_D_ERROR, "S3ResumeExecuteBootScript()\n")); … … 680 795 (VOID **) &SmmAccess 681 796 ); 682 683 DEBUG ((EFI_D_ERROR, "Close all SMRAM regions before executing boot script\n")); 684 685 for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) { 686 Status = SmmAccess->Close ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index); 687 } 688 689 DEBUG ((EFI_D_ERROR, "Lock all SMRAM regions before executing boot script\n")); 690 691 for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) { 692 Status = SmmAccess->Lock ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index); 797 if (!EFI_ERROR (Status)) { 798 DEBUG ((EFI_D_ERROR, "Close all SMRAM regions before executing boot script\n")); 799 800 for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) { 801 Status = SmmAccess->Close ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index); 802 } 803 804 DEBUG ((EFI_D_ERROR, "Lock all SMRAM regions before executing boot script\n")); 805 806 for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) { 807 Status = SmmAccess->Lock ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index); 808 } 693 809 } 694 810 } … … 709 825 IdtBuffer = AllocatePages (EFI_SIZE_TO_PAGES((IdtDescriptor->Limit + 1) + 16)); 710 826 ASSERT (IdtBuffer != NULL); 827 // 828 // Additional 16 bytes allocated to save IA32 IDT descriptor and Pei Service Table Pointer 829 // IA32 IDT descriptor will be used to setup IA32 IDT table for 32-bit Framework Boot Script code 830 // 831 ZeroMem (IdtBuffer, 16); 832 AsmReadIdtr ((IA32_DESCRIPTOR *)IdtBuffer); 711 833 CopyMem ((VOID*)((UINT8*)IdtBuffer + 16),(VOID*)(IdtDescriptor->Base), (IdtDescriptor->Limit + 1)); 712 834 IdtDescriptor->Base = (UINTN)((UINT8*)IdtBuffer + 16); … … 714 836 } 715 837 838 InterruptStatus = SaveAndDisableInterrupts (); 716 839 // 717 840 // Need to make sure the GDT is loaded with values that support long mode and real mode. 718 841 // 719 842 AsmWriteGdtr (&mGdt); 843 // 844 // update segment selectors per the new GDT. 845 // 846 AsmSetDataSelectors (DATA_SEGEMENT_SELECTOR); 847 // 848 // Restore interrupt state. 849 // 850 SetInterruptState (InterruptStatus); 720 851 721 852 // … … 727 858 PeiS3ResumeState->ReturnCs = 0x10; 728 859 PeiS3ResumeState->ReturnEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)S3ResumeBootOs; 729 PeiS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS) (UINTN)&Status;860 PeiS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)STACK_ALIGN_DOWN (&Status); 730 861 // 731 862 // Save IDT 732 863 // 733 864 AsmReadIdtr (&PeiS3ResumeState->Idtr); 865 866 // 867 // Report Status Code to indicate S3 boot script execution 868 // 869 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_S3_BOOT_SCRIPT); 870 871 PERF_START (NULL, "ScriptExec", NULL, 0); 734 872 735 873 if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { … … 808 946 UINTN Index; 809 947 ACPI_S3_CONTEXT *AcpiS3Context; 810 EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;811 948 EFI_PHYSICAL_ADDRESS TempEfiBootScriptExecutorVariable; 812 949 EFI_PHYSICAL_ADDRESS TempAcpiS3Context; … … 816 953 SMM_S3_RESUME_STATE *SmmS3ResumeState; 817 954 VOID *GuidHob; 955 BOOLEAN Build4GPageTableOnly; 956 BOOLEAN InterruptStatus; 957 958 TempAcpiS3Context = 0; 959 TempEfiBootScriptExecutorVariable = 0; 818 960 819 961 DEBUG ((EFI_D_ERROR, "Enter S3 PEIM\r\n")); 820 821 Status = PeiServicesLocatePpi (822 &gPeiSmmAccessPpiGuid,823 0,824 NULL,825 (VOID **) &SmmAccess826 );827 for (Index = 0; !EFI_ERROR (Status); Index++) {828 Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);829 }830 831 Status = PeiServicesLocatePpi (832 &gEfiPeiReadOnlyVariable2PpiGuid,833 0,834 NULL,835 (VOID **) &VariableServices836 );837 if (EFI_ERROR (Status)) {838 return Status;839 }840 962 841 963 VarSize = sizeof (EFI_PHYSICAL_ADDRESS); … … 847 969 ASSERT_EFI_ERROR (Status); 848 970 849 AcpiS3Context = (ACPI_S3_CONTEXT *)(UINTN)TempAcpiS3Context;850 ASSERT (AcpiS3Context != NULL);851 852 971 Status = RestoreLockBox ( 853 972 &gEfiAcpiS3ContextGuid, … … 857 976 ASSERT_EFI_ERROR (Status); 858 977 859 VarSize = sizeof (TempEfiBootScriptExecutorVariable); 978 AcpiS3Context = (ACPI_S3_CONTEXT *)(UINTN)TempAcpiS3Context; 979 ASSERT (AcpiS3Context != NULL); 980 981 VarSize = sizeof (EFI_PHYSICAL_ADDRESS); 860 982 Status = RestoreLockBox ( 861 983 &gEfiBootScriptExecutorVariableGuid, … … 873 995 874 996 EfiBootScriptExecutorVariable = (BOOT_SCRIPT_EXECUTOR_VARIABLE *) (UINTN) TempEfiBootScriptExecutorVariable; 997 ASSERT (EfiBootScriptExecutorVariable != NULL); 875 998 876 999 DEBUG (( EFI_D_ERROR, "AcpiS3Context = %x\n", AcpiS3Context)); 877 1000 DEBUG (( EFI_D_ERROR, "Waking Vector = %x\n", ((EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) ((UINTN) (AcpiS3Context->AcpiFacsTable)))->FirmwareWakingVector)); 878 1001 DEBUG (( EFI_D_ERROR, "AcpiS3Context->AcpiFacsTable = %x\n", AcpiS3Context->AcpiFacsTable)); 1002 DEBUG (( EFI_D_ERROR, "AcpiS3Context->IdtrProfile = %x\n", AcpiS3Context->IdtrProfile)); 879 1003 DEBUG (( EFI_D_ERROR, "AcpiS3Context->S3NvsPageTableAddress = %x\n", AcpiS3Context->S3NvsPageTableAddress)); 880 1004 DEBUG (( EFI_D_ERROR, "AcpiS3Context->S3DebugBufferAddress = %x\n", AcpiS3Context->S3DebugBufferAddress)); 1005 DEBUG (( EFI_D_ERROR, "AcpiS3Context->BootScriptStackBase = %x\n", AcpiS3Context->BootScriptStackBase)); 1006 DEBUG (( EFI_D_ERROR, "AcpiS3Context->BootScriptStackSize = %x\n", AcpiS3Context->BootScriptStackSize)); 881 1007 DEBUG (( EFI_D_ERROR, "EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint = %x\n", EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint)); 882 1008 … … 897 1023 // Need reconstruct page table here, since we do not trust ACPINvs. 898 1024 // 899 RestoreS3PageTables ((UINTN)AcpiS3Context->S3NvsPageTableAddress); 1025 if (IsLongModeWakingVector (AcpiS3Context)) { 1026 Build4GPageTableOnly = FALSE; 1027 } else { 1028 Build4GPageTableOnly = TRUE; 1029 } 1030 RestoreS3PageTables ((UINTN)AcpiS3Context->S3NvsPageTableAddress, Build4GPageTableOnly); 900 1031 } 901 1032 … … 905 1036 GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid); 906 1037 if (GuidHob != NULL) { 1038 Status = PeiServicesLocatePpi ( 1039 &gPeiSmmAccessPpiGuid, 1040 0, 1041 NULL, 1042 (VOID **) &SmmAccess 1043 ); 1044 for (Index = 0; !EFI_ERROR (Status); Index++) { 1045 Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index); 1046 } 1047 907 1048 SmramDescriptor = (EFI_SMRAM_DESCRIPTOR *) GET_GUID_HOB_DATA (GuidHob); 908 1049 SmmS3ResumeState = (SMM_S3_RESUME_STATE *)(UINTN)SmramDescriptor->CpuStart; … … 912 1053 SmmS3ResumeState->ReturnContext1 = (EFI_PHYSICAL_ADDRESS)(UINTN)AcpiS3Context; 913 1054 SmmS3ResumeState->ReturnContext2 = (EFI_PHYSICAL_ADDRESS)(UINTN)EfiBootScriptExecutorVariable; 914 SmmS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS) (UINTN)&Status;1055 SmmS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)STACK_ALIGN_DOWN (&Status); 915 1056 916 1057 DEBUG (( EFI_D_ERROR, "SMM S3 Signature = %x\n", SmmS3ResumeState->Signature)); … … 928 1069 DEBUG (( EFI_D_ERROR, "SMM S3 Smst = %x\n", SmmS3ResumeState->Smst)); 929 1070 930 //931 // Disable interrupt of Debug timer.932 //933 SaveAndSetDebugTimerInterrupt (FALSE);934 935 1071 if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_32) { 936 1072 SwitchStack ( … … 946 1082 // 947 1083 1084 InterruptStatus = SaveAndDisableInterrupts (); 948 1085 // 949 1086 // Need to make sure the GDT is loaded with values that support long mode and real mode. 950 1087 // 951 1088 AsmWriteGdtr (&mGdt); 1089 // 1090 // update segment selectors per the new GDT. 1091 // 1092 AsmSetDataSelectors (DATA_SEGEMENT_SELECTOR); 1093 // 1094 // Restore interrupt state. 1095 // 1096 SetInterruptState (InterruptStatus); 1097 952 1098 AsmWriteCr3 ((UINTN)SmmS3ResumeState->SmmS3Cr3); 1099 1100 // 1101 // Disable interrupt of Debug timer, since IDT table cannot work in long mode. 1102 // NOTE: On x64 platforms, because DisablePaging64() will disable interrupts, 1103 // the code in S3ResumeExecuteBootScript() cannot be halted by soft debugger. 1104 // 1105 SaveAndSetDebugTimerInterrupt (FALSE); 1106 953 1107 AsmEnablePaging64 ( 954 1108 0x38, -
trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
r48674 r58459 1 1 ## @file 2 # S3 Resume Module: 2 # S3 Resume Module installs EFI_PEI_S3_RESUME2_PPI. 3 # 3 4 # This module works with StandAloneBootScriptExecutor to S3 resume to OS. 4 5 # This module will excute the boot script saved during last boot and after that, 5 6 # control is passed to OS waking up handler. 6 7 # 7 # Copyright (c) 2010 - 201 1, Intel Corporation. All rights reserved.<BR>8 # Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 8 9 # 9 10 # This program and the accompanying materials are … … 20 21 INF_VERSION = 0x00010005 21 22 BASE_NAME = S3Resume2Pei 23 MODULE_UNI_FILE = S3Resume2Pei.uni 22 24 FILE_GUID = 89E549B0-7CFE-449d-9BA3-10D8B2312D71 23 25 MODULE_TYPE = PEIM … … 33 35 [Sources] 34 36 S3Resume.c 37 38 [Sources.IA32] 39 Ia32/AsmFuncs.asm 40 Ia32/AsmFuncs.S | GCC 41 42 [Sources.X64] 43 X64/AsmFuncs.asm 44 X64/AsmFuncs.S | GCC 35 45 36 46 [Packages] … … 59 69 60 70 [Guids] 61 gEfiBootScriptExecutorVariableGuid # SOMETIMES_CONSUMED 62 gEfiBootScriptExecutorContextGuid # SOMETIMES_CONSUMED 63 gPerformanceProtocolGuid # ALWAYS_CONSUMED L"PerfDataMemAddr" 64 gEfiAcpiVariableGuid # ALWAYS_CONSUMED Hob: GUID_EXTENSION 65 gEfiAcpiS3ContextGuid # ALWAYS_CONSUMED 71 gEfiBootScriptExecutorVariableGuid ## SOMETIMES_CONSUMES ## UNDEFINED # LockBox 72 gEfiBootScriptExecutorContextGuid ## SOMETIMES_CONSUMES ## UNDEFINED # LockBox 73 gPerformanceProtocolGuid ## SOMETIMES_CONSUMES ## Variable:L"PerfDataMemAddr" 74 ## SOMETIMES_CONSUMES ## HOB 75 ## SOMETIMES_CONSUMES ## UNDEFINED # LockBox 76 gEfiAcpiVariableGuid 77 gEfiAcpiS3ContextGuid ## SOMETIMES_CONSUMES ## UNDEFINED # LockBox 66 78 67 79 [Ppis] 68 gEfiPeiReadOnlyVariable2PpiGuid # PPI ALWAYS_CONSUMED69 gEfiPeiS3Resume2PpiGuid # PPI ALWAYS_PRODUCED70 gPeiSmmAccessPpiGuid # PPI ALWAYS_CONSUMED71 gPeiPostScriptTablePpiGuid # PPI ALWAYS_PRODUCED72 gEfiEndOfPeiSignalPpiGuid # PPI ALWAYS_PRODUCED80 gEfiPeiReadOnlyVariable2PpiGuid ## CONSUMES 81 gEfiPeiS3Resume2PpiGuid ## PRODUCES 82 gPeiSmmAccessPpiGuid ## SOMETIMES_CONSUMES 83 gPeiPostScriptTablePpiGuid ## SOMETIMES_PRODUCES 84 gEfiEndOfPeiSignalPpiGuid ## SOMETIMES_PRODUCES 73 85 74 86 [FeaturePcd] 75 gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode 76 gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport 87 gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES 88 gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport ## CONSUMES 77 89 78 90 [Pcd] 79 gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable 91 gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES 80 92 81 93 [Depex] 82 gEfiPeiReadOnlyVariable2PpiGuid 94 TRUE 95 96 [UserExtensions.TianoCore."ExtraFiles"] 97 S3Resume2PeiExtra.uni
Note:
See TracChangeset
for help on using the changeset viewer.