diff --git a/sdk/xtdk/amd64/arfuncs.h b/sdk/xtdk/amd64/arfuncs.h index 6e059dd..0ec7341 100644 --- a/sdk/xtdk/amd64/arfuncs.h +++ b/sdk/xtdk/amd64/arfuncs.h @@ -32,6 +32,10 @@ XTCDECL ULONG_PTR ArReadControlRegister(IN USHORT ControlRegister); +XTCDECL +ULONGLONG +ArReadModelSpecificRegister(IN ULONG Register); + XTCDECL VOID ArWriteControlRegister(IN USHORT ControlRegister, diff --git a/sdk/xtdk/amd64/hltypes.h b/sdk/xtdk/amd64/hltypes.h index 33926fe..55a3717 100644 --- a/sdk/xtdk/amd64/hltypes.h +++ b/sdk/xtdk/amd64/hltypes.h @@ -14,6 +14,9 @@ #include +/* APIC base address */ +#define APIC_BASE 0xFFFFFFFFFFFE0000ULL + /* Serial port I/O addresses */ #define COMPORT_ADDRESSES {0x000, 0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8} diff --git a/sdk/xtdk/i686/arfuncs.h b/sdk/xtdk/i686/arfuncs.h index ceab1ec..176313f 100644 --- a/sdk/xtdk/i686/arfuncs.h +++ b/sdk/xtdk/i686/arfuncs.h @@ -32,6 +32,10 @@ XTCDECL ULONG_PTR ArReadControlRegister(IN USHORT ControlRegister); +XTCDECL +ULONGLONG +ArReadModelSpecificRegister(IN ULONG Register); + XTCDECL VOID ArWriteControlRegister(IN USHORT ControlRegister, diff --git a/sdk/xtdk/i686/hltypes.h b/sdk/xtdk/i686/hltypes.h index f368b1c..c171d81 100644 --- a/sdk/xtdk/i686/hltypes.h +++ b/sdk/xtdk/i686/hltypes.h @@ -14,6 +14,9 @@ #include +/* APIC base address */ +#define APIC_BASE 0xFFFE0000 + /* Serial port I/O addresses */ #define COMPORT_ADDRESSES {0x000, 0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8} diff --git a/xtldr/modules/xtos/includes/xtos.h b/xtldr/modules/xtos/includes/xtos.h index 3fe323e..272b93f 100644 --- a/xtldr/modules/xtos/includes/xtos.h +++ b/xtldr/modules/xtos/includes/xtos.h @@ -29,6 +29,10 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters); +XTCDECL +EFI_STATUS +XtpInitializeApicBase(IN PLIST_ENTRY MemoryMappings); + XTCDECL EFI_STATUS XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings, diff --git a/xtldr/modules/xtos/xtos.c b/xtldr/modules/xtos/xtos.c index 1a40f3c..c45b169 100644 --- a/xtldr/modules/xtos/xtos.c +++ b/xtldr/modules/xtos/xtos.c @@ -229,6 +229,21 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, /* Setup and map kernel initialization block */ Status = XtpInitializeLoaderBlock(&MemoryMappings, &VirtualAddress); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to setup kernel initialization block */ + XtLdrProtocol->DbgPrint(L"Failed to setup kernel initialization block (Status Code: %lx)\n", Status); + return Status; + } + + /* Find and map APIC base address */ + Status = XtpInitializeApicBase(&MemoryMappings); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to setup kernel initialization block */ + XtLdrProtocol->DbgPrint(L"Failed to initialize APIC (Status Code: %lx)\n", Status); + return Status; + } /* Get kernel entry point */ XtPeCoffProtocol->GetEntryPoint(ImageContext, (PVOID)&KernelEntryPoint); @@ -254,6 +269,47 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, return STATUS_EFI_SUCCESS; } +/** + * Checks if APIC is present in the system and finds its base address. + * + * @param MemoryMappings + * Supplies a pointer to linked list containing all memory mappings. + * + * @return This routine returns an EFI status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtpInitializeApicBase(IN PLIST_ENTRY MemoryMappings) +{ + PCPUID_REGISTERS CpuRegisters = NULL; + PVOID ApicBaseAddress; + + /* Get CPU features list */ + CpuRegisters->Leaf = CPUID_GET_CPU_FEATURES; + CpuRegisters->SubLeaf = 0; + CpuRegisters->Eax = 0; + CpuRegisters->Ebx = 0; + CpuRegisters->Ecx = 0; + CpuRegisters->Edx = 0; + ArCpuId(CpuRegisters); + + /* Check if APIC is present */ + if((CpuRegisters->Edx & CPUID_FEATURES_EDX_APIC) == 0) + { + /* APIC is not supported by the CPU */ + return STATUS_EFI_UNSUPPORTED; + } + + /* Get APIC base address */ + ApicBaseAddress = (PVOID)((UINT_PTR)ArReadModelSpecificRegister(0x1B) & 0xFFFFF000); + + /* Map APIC base address */ + XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, (PVOID)APIC_BASE, ApicBaseAddress, 1, LoaderFirmwarePermanent); + return STATUS_EFI_SUCCESS; +} + /** * Initializes and maps the kernel initialization block. *