Index: UefiCpuPkg/CpuDxe/CpuDxe.inf =================================================================== --- UefiCpuPkg/CpuDxe/CpuDxe.inf (revision 9332) +++ UefiCpuPkg/CpuDxe/CpuDxe.inf (working copy) @@ -62,6 +62,9 @@ [Protocols] gEfiCpuArchProtocolGuid +[Guids] + gEfiEventVirtualAddressChangeGuid # ALWAYS_CONSUMED Create Event: EVENT_GROUP_GUID + [Depex] TRUE Index: UefiCpuPkg/CpuDxe/CpuGdt.c =================================================================== --- UefiCpuPkg/CpuDxe/CpuGdt.c (revision 9332) +++ UefiCpuPkg/CpuDxe/CpuGdt.c (working copy) @@ -67,6 +67,9 @@ #error CPU type not supported for CPU GDT initialization! #endif +VOID * Gdt; +UINT32 GdtSize; + // // Global descriptor table (GDT) Template // @@ -161,6 +164,20 @@ }, }; +VOID EFIAPI +LoadGdt(VOID* Gdt, UINT32 GdtSize) +{ + IA32_DESCRIPTOR gdtPtr; + + // + // Write GDT register + // + gdtPtr.Base = (UINT32)(UINTN)Gdt; + gdtPtr.Limit = GdtSize - 1; + + AsmWriteGdtr (&gdtPtr); +} + /** Initialize Global Descriptor Table @@ -169,27 +186,27 @@ InitGlobalDescriptorTable ( ) { - GDT_ENTRIES *gdt; - IA32_DESCRIPTOR gdtPtr; - // // Allocate Runtime Data for the GDT // - gdt = AllocateRuntimePool (sizeof (GdtTemplate) + 8); - ASSERT (gdt != NULL); - gdt = ALIGN_POINTER (gdt, 8); + GdtSize = sizeof (GdtTemplate); +#if 0 + Gdt = AllocateRuntimePool (GdtSize + 8); + ASSERT (Gdt != NULL); + Gdt = ALIGN_POINTER (Gdt, 8); +#else + Gdt = (VOID*)(UINTN)HandyCpuPage; +#endif // // Initialize all GDT entries // - CopyMem (gdt, &GdtTemplate, sizeof (GdtTemplate)); + CopyMem (Gdt, &GdtTemplate, GdtSize); // // Write GDT register // - gdtPtr.Base = (UINT32)(UINTN)(VOID*) gdt; - gdtPtr.Limit = sizeof (GdtTemplate) - 1; - AsmWriteGdtr (&gdtPtr); + LoadGdt(Gdt, GdtSize); // // Update selector (segment) registers base on new GDT @@ -197,4 +214,3 @@ SetCodeSelector ((UINT16)CPU_CODE_SEL); SetDataSelectors ((UINT16)CPU_DATA_SEL); } - Index: UefiCpuPkg/CpuDxe/CpuDxe.c =================================================================== --- UefiCpuPkg/CpuDxe/CpuDxe.c (revision 9332) +++ UefiCpuPkg/CpuDxe/CpuDxe.c (working copy) @@ -14,11 +14,14 @@ #include "CpuDxe.h" +EFI_EVENT mEfiVirtualNotifyEvent; +EFI_PHYSICAL_ADDRESS HandyCpuPage; +IA32_IDT_GATE_DESCRIPTOR* Idt; +UINT32 IdtSize; + // // Global Variables // -IA32_IDT_GATE_DESCRIPTOR gIdtTable[INTERRUPT_VECTOR_NUMBER] = { 0 }; - EFI_CPU_INTERRUPT_HANDLER ExternalVectorTable[0x100]; BOOLEAN InterruptState = FALSE; EFI_HANDLE mCpuHandle = NULL; @@ -1004,8 +1007,6 @@ ) { EFI_STATUS Status; - VOID *IdtPtrAlignmentBuffer; - IA32_DESCRIPTOR *IdtPtr; UINTN Index; UINTN CurrentHandler; @@ -1015,27 +1016,33 @@ // Initialize IDT // CurrentHandler = (UINTN)AsmIdtVector00; + + // + // Allocate Runtime Data for the IDT + // + IdtSize = INTERRUPT_VECTOR_NUMBER*sizeof(IA32_IDT_GATE_DESCRIPTOR); +#if 0 + Idt = AllocateRuntimePool (IdtSize + 16); + ASSERT (Idt != NULL); + Idt = ALIGN_POINTER (Idt, 16); +#else + Idt = (VOID*)(UINTN)HandyCpuPage + 0x500; +#endif + for (Index = 0; Index < INTERRUPT_VECTOR_NUMBER; Index ++, CurrentHandler += 0x08) { - gIdtTable[Index].Bits.OffsetLow = (UINT16)CurrentHandler; - gIdtTable[Index].Bits.Selector = AsmReadCs(); - gIdtTable[Index].Bits.Reserved_0 = 0; - gIdtTable[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; - gIdtTable[Index].Bits.OffsetHigh = (UINT16)(CurrentHandler >> 16); + Idt[Index].Bits.OffsetLow = (UINT16)CurrentHandler; + Idt[Index].Bits.Selector = AsmReadCs(); + Idt[Index].Bits.Reserved_0 = 0; + Idt[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; + Idt[Index].Bits.OffsetHigh = (UINT16)(CurrentHandler >> 16); #if defined (MDE_CPU_X64) - gIdtTable[Index].Bits.OffsetUpper = (UINT32)(CurrentHandler >> 32); - gIdtTable[Index].Bits.Reserved_1 = 0; + Idt[Index].Bits.OffsetUpper = (UINT32)(CurrentHandler >> 32); + Idt[Index].Bits.Reserved_1 = 0; #endif } - // - // Load IDT Pointer - // - IdtPtrAlignmentBuffer = AllocatePool (sizeof (*IdtPtr) + 16); - IdtPtr = ALIGN_POINTER (IdtPtrAlignmentBuffer, 16); - IdtPtr->Base = (UINT32)(((UINTN)(VOID*) gIdtTable) & (BASE_4GB-1)); - IdtPtr->Limit = sizeof (gIdtTable) - 1; - AsmWriteIdtr (IdtPtr); - FreePool (IdtPtrAlignmentBuffer); + // Load IDT + LoadIdt(Idt, IdtSize); // // Initialize Exception Handlers @@ -1052,7 +1059,50 @@ } +VOID EFIAPI +LoadIdt(VOID* Idt, UINT32 IdtSize) +{ + IA32_DESCRIPTOR IdtPtr; + IdtPtr.Base = (UINT32)(((UINTN) Idt) & (BASE_4GB-1)); + IdtPtr.Limit = IdtSize - 1; + AsmWriteIdtr (&IdtPtr); +} + +UINT32 +EFIAPI +IoWrite32 ( + IN UINTN Port, + IN UINT32 Value + ) +{ + __asm__ __volatile__ ("outl %0,%w1" : : "a" (Value), "d" ((UINT16)Port)); + return Value; +} + +VOID +EFIAPI +CpuLibVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_RUNTIME_SERVICES * rs = (EFI_RUNTIME_SERVICES *)Context; + + rs->ConvertPointer (0, (VOID **) &Gdt); + rs->ConvertPointer (0, (VOID **) &Idt); + + DisableInterrupts(); + + LoadIdt(Idt, IdtSize); + LoadGdt(Gdt, GdtSize); + + //IoWrite32(0xef11, 1); +} + +extern EFI_GUID gEfiEventVirtualAddressChangeGuid; + + /** Initialize the state information for the CPU Architectural Protocol. @@ -1073,6 +1123,17 @@ { EFI_STATUS Status; + + // Allocate handy page + HandyCpuPage = 0xffffffff; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiReservedMemoryType, + 1, + &HandyCpuPage ); + ASSERT_EFI_ERROR (Status); + ASSERT (HandyCpuPage != 0xffffffff); + // // Make sure interrupts are disabled // @@ -1103,6 +1164,18 @@ // RefreshGcdMemoryAttributes (); + + // Register virtual address change notifier +#if 0 + gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + CpuLibVirtualNotifyEvent, + SystemTable->RuntimeServices, + &gEfiEventVirtualAddressChangeGuid, + &mEfiVirtualNotifyEvent + ); +#endif + return Status; } - Index: UefiCpuPkg/CpuDxe/CpuDxe.h =================================================================== --- UefiCpuPkg/CpuDxe/CpuDxe.h (revision 9332) +++ UefiCpuPkg/CpuDxe/CpuDxe.h (working copy) @@ -136,5 +136,17 @@ ); +VOID EFIAPI +LoadGdt(VOID* Gdt, UINT32 GdtSize); + +VOID EFIAPI +LoadIdt(VOID* Idt, UINT32 IdtSize); + +extern EFI_PHYSICAL_ADDRESS HandyCpuPage; +extern VOID* Gdt; +extern UINT32 GdtSize; +extern IA32_IDT_GATE_DESCRIPTOR* Idt; +extern UINT32 IdtSize; + #endif