forked from xt-sys/exectos
Basic IDT setup in the bootloader
This commit is contained in:
parent
e94e50b5d9
commit
bf141fe25e
@ -99,6 +99,9 @@ XtpInitializeGdtEntry(IN PKGDTENTRY Gdt,
|
|||||||
* @param Gdt
|
* @param Gdt
|
||||||
* Supplies a pointer to memory area containing GDT to fill in.
|
* Supplies a pointer to memory area containing GDT to fill in.
|
||||||
*
|
*
|
||||||
|
* @param Idt
|
||||||
|
* Supplies a pointer to memory area containing IDT to fill in.
|
||||||
|
*
|
||||||
* @return This routine returns a status code.
|
* @return This routine returns a status code.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
@ -107,11 +110,14 @@ XTCDECL
|
|||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings,
|
XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings,
|
||||||
IN PVOID *VirtualAddress,
|
IN PVOID *VirtualAddress,
|
||||||
OUT PKGDTENTRY *Gdt)
|
OUT PKGDTENTRY *Gdt,
|
||||||
|
OUT PKIDTENTRY *Idt)
|
||||||
{
|
{
|
||||||
EFI_PHYSICAL_ADDRESS GdtAddress, TssAddress;
|
EFI_PHYSICAL_ADDRESS GdtAddress, IdtAddress, TssAddress;
|
||||||
|
KDESCRIPTOR OriginalIdt;
|
||||||
PKTSS PhysicalTss, Tss;
|
PKTSS PhysicalTss, Tss;
|
||||||
PKGDTENTRY GdtEntry;
|
PKGDTENTRY GdtEntry;
|
||||||
|
PKIDTENTRY IdtEntry;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
/* Print debug message */
|
/* Print debug message */
|
||||||
@ -175,6 +181,33 @@ XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings,
|
|||||||
/* Set next valid virtual address */
|
/* Set next valid virtual address */
|
||||||
*VirtualAddress += (EFI_SIZE_TO_PAGES(128 * sizeof(KGDTENTRY)) * EFI_PAGE_SIZE);
|
*VirtualAddress += (EFI_SIZE_TO_PAGES(128 * sizeof(KGDTENTRY)) * EFI_PAGE_SIZE);
|
||||||
|
|
||||||
|
/* Print debug message */
|
||||||
|
XtLdrProtocol->DbgPrint(L"Initializing Interrupt Descriptor Table (IDT)\n");
|
||||||
|
|
||||||
|
/* Allocate memory for IDT */
|
||||||
|
Status = XtLdrProtocol->AllocatePages(EFI_SIZE_TO_PAGES(256 * sizeof(KIDTENTRY)), &IdtAddress);
|
||||||
|
if (Status != STATUS_EFI_SUCCESS) {
|
||||||
|
/* Memory allocation failure */
|
||||||
|
XtLdrProtocol->DbgPrint(L"Failed to allocate pages for IDT (Status Code: %lx)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set IDT entry and fill it with zeroes */
|
||||||
|
IdtEntry = (PKIDTENTRY)(UINT_PTR)IdtAddress;
|
||||||
|
RtlZeroMemory(IdtEntry, EFI_SIZE_TO_PAGES(256 * sizeof(KIDTENTRY)) * EFI_PAGE_SIZE);
|
||||||
|
|
||||||
|
/* Stores IDT register into new IDT entry */
|
||||||
|
HlStoreInterruptDescriptorTable(&OriginalIdt.Limit);
|
||||||
|
RtlCopyMemory(IdtEntry, OriginalIdt.Base, OriginalIdt.Limit + 1);
|
||||||
|
|
||||||
|
/* Map IDT and set its virtual address */
|
||||||
|
Status = XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, IdtEntry,
|
||||||
|
EFI_SIZE_TO_PAGES(256 * sizeof(KIDTENTRY)), LoaderMemoryData);
|
||||||
|
*Idt = (PKIDTENTRY)*VirtualAddress;
|
||||||
|
|
||||||
|
/* Set next valid virtual address */
|
||||||
|
*VirtualAddress += (EFI_SIZE_TO_PAGES(256 * sizeof(KIDTENTRY)) * EFI_PAGE_SIZE);
|
||||||
|
|
||||||
/* Return success */
|
/* Return success */
|
||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -185,21 +218,29 @@ XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings,
|
|||||||
* @param Gdt
|
* @param Gdt
|
||||||
* Supplies a pointer to memory area containing GDT to load.
|
* Supplies a pointer to memory area containing GDT to load.
|
||||||
*
|
*
|
||||||
|
* @param Idt
|
||||||
|
* Supplies a pointer to memory area containing IDT to load.
|
||||||
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
*/
|
*/
|
||||||
XTCDECL
|
XTCDECL
|
||||||
VOID
|
VOID
|
||||||
XtpLoadProcessorContext(IN PKGDTENTRY Gdt)
|
XtpLoadProcessorContext(IN PKGDTENTRY Gdt,
|
||||||
|
IN PKIDTENTRY Idt)
|
||||||
{
|
{
|
||||||
KDESCRIPTOR GdtDescriptor;
|
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
||||||
|
|
||||||
GdtDescriptor.Base = Gdt;
|
GdtDescriptor.Base = Gdt;
|
||||||
GdtDescriptor.Limit = 128 * sizeof(KGDTENTRY) - 1;
|
GdtDescriptor.Limit = 128 * sizeof(KGDTENTRY) - 1;
|
||||||
|
|
||||||
/* Load GDT and TSS */
|
IdtDescriptor.Base = Idt;
|
||||||
|
IdtDescriptor.Limit = 256 * sizeof(KIDTENTRY) - 1;
|
||||||
|
|
||||||
|
/* Load GDT, IDT and TSS */
|
||||||
HlLoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
HlLoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
||||||
|
HlLoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
||||||
HlLoadTaskRegister((UINT32)KGDT_SYS_TSS);
|
HlLoadTaskRegister((UINT32)KGDT_SYS_TSS);
|
||||||
|
|
||||||
/* Re-enable IDE interrupts */
|
/* Re-enable IDE interrupts */
|
||||||
@ -219,6 +260,9 @@ XtpLoadProcessorContext(IN PKGDTENTRY Gdt)
|
|||||||
* @param Gdt
|
* @param Gdt
|
||||||
* Supplies a pointer to memory area containing GDT to fill in.
|
* Supplies a pointer to memory area containing GDT to fill in.
|
||||||
*
|
*
|
||||||
|
* @param Idt
|
||||||
|
* Supplies a pointer to memory area containing IDT to fill in.
|
||||||
|
*
|
||||||
* @return This routine returns a status code.
|
* @return This routine returns a status code.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
@ -227,7 +271,8 @@ XTCDECL
|
|||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
XtpSetProcessorContext(IN PLIST_ENTRY MemoryMappings,
|
XtpSetProcessorContext(IN PLIST_ENTRY MemoryMappings,
|
||||||
IN PVOID *VirtualAddress,
|
IN PVOID *VirtualAddress,
|
||||||
OUT PKGDTENTRY *Gdt)
|
OUT PKGDTENTRY *Gdt,
|
||||||
|
OUT PKIDTENTRY *Idt)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
@ -238,7 +283,7 @@ XtpSetProcessorContext(IN PLIST_ENTRY MemoryMappings,
|
|||||||
HlClearInterruptFlag();
|
HlClearInterruptFlag();
|
||||||
|
|
||||||
/* Initialize GDT */
|
/* Initialize GDT */
|
||||||
Status = XtpInitializeDescriptors(MemoryMappings, VirtualAddress, Gdt);
|
Status = XtpInitializeDescriptors(MemoryMappings, VirtualAddress, Gdt, Idt);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* GDT initialization failure */
|
/* GDT initialization failure */
|
||||||
|
@ -98,6 +98,9 @@ XtpInitializeGdtEntry(IN PKGDTENTRY Gdt,
|
|||||||
* @param Gdt
|
* @param Gdt
|
||||||
* Supplies a pointer to memory area containing GDT to fill in.
|
* Supplies a pointer to memory area containing GDT to fill in.
|
||||||
*
|
*
|
||||||
|
* @param Idt
|
||||||
|
* Supplies a pointer to memory area containing IDT to fill in.
|
||||||
|
*
|
||||||
* @return This routine returns a status code.
|
* @return This routine returns a status code.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
@ -106,12 +109,15 @@ XTCDECL
|
|||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings,
|
XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings,
|
||||||
IN PVOID *VirtualAddress,
|
IN PVOID *VirtualAddress,
|
||||||
OUT PKGDTENTRY *Gdt)
|
OUT PKGDTENTRY *Gdt,
|
||||||
|
OUT PKIDTENTRY *Idt)
|
||||||
{
|
{
|
||||||
EFI_PHYSICAL_ADDRESS GdtAddress, PcrAddress, TssAddress;
|
EFI_PHYSICAL_ADDRESS GdtAddress, IdtAddress, PcrAddress, TssAddress;
|
||||||
|
KDESCRIPTOR OriginalIdt;
|
||||||
PKTSS PhysicalTss, Tss;
|
PKTSS PhysicalTss, Tss;
|
||||||
PVOID PhysicalPcr, Pcr;
|
PVOID PhysicalPcr, Pcr;
|
||||||
PKGDTENTRY GdtEntry;
|
PKGDTENTRY GdtEntry;
|
||||||
|
PKIDTENTRY IdtEntry;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
/* Print debug message */
|
/* Print debug message */
|
||||||
@ -199,6 +205,32 @@ XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings,
|
|||||||
/* Set next valid virtual address */
|
/* Set next valid virtual address */
|
||||||
*VirtualAddress += (EFI_SIZE_TO_PAGES(128 * sizeof(KGDTENTRY)) * EFI_PAGE_SIZE);
|
*VirtualAddress += (EFI_SIZE_TO_PAGES(128 * sizeof(KGDTENTRY)) * EFI_PAGE_SIZE);
|
||||||
|
|
||||||
|
/* Print debug message */
|
||||||
|
XtLdrProtocol->DbgPrint(L"Initializing Interrupt Descriptor Table (IDT)\n");
|
||||||
|
|
||||||
|
/* Allocate memory for IDT */
|
||||||
|
Status = XtLdrProtocol->AllocatePages(EFI_SIZE_TO_PAGES(256 * sizeof(KIDTENTRY)), &IdtAddress);
|
||||||
|
if (Status != STATUS_EFI_SUCCESS) {
|
||||||
|
/* Memory allocation failure */
|
||||||
|
XtLdrProtocol->DbgPrint(L"Failed to allocate pages for IDT (Status Code: %lx)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set IDT entry and fill it with zeroes */
|
||||||
|
IdtEntry = (PKIDTENTRY)(UINT_PTR)IdtAddress;
|
||||||
|
RtlZeroMemory(IdtEntry, EFI_SIZE_TO_PAGES(256 * sizeof(KIDTENTRY)) * EFI_PAGE_SIZE);
|
||||||
|
|
||||||
|
/* Stores IDT register into new IDT entry */
|
||||||
|
HlStoreInterruptDescriptorTable(&OriginalIdt.Limit);
|
||||||
|
RtlCopyMemory(IdtEntry, OriginalIdt.Base, OriginalIdt.Limit + 1);
|
||||||
|
|
||||||
|
/* Map IDT and set its virtual address */
|
||||||
|
Status = XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, IdtEntry,
|
||||||
|
EFI_SIZE_TO_PAGES(256 * sizeof(KIDTENTRY)), LoaderMemoryData);
|
||||||
|
*Idt = (PKIDTENTRY)*VirtualAddress;
|
||||||
|
|
||||||
|
/* Set next valid virtual address */
|
||||||
|
*VirtualAddress += (EFI_SIZE_TO_PAGES(256 * sizeof(KIDTENTRY)) * EFI_PAGE_SIZE);
|
||||||
/* Return success */
|
/* Return success */
|
||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -209,21 +241,29 @@ XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings,
|
|||||||
* @param Gdt
|
* @param Gdt
|
||||||
* Supplies a pointer to memory area containing GDT to load.
|
* Supplies a pointer to memory area containing GDT to load.
|
||||||
*
|
*
|
||||||
|
* @param Idt
|
||||||
|
* Supplies a pointer to memory area containing IDT to load.
|
||||||
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
*/
|
*/
|
||||||
XTCDECL
|
XTCDECL
|
||||||
VOID
|
VOID
|
||||||
XtpLoadProcessorContext(IN PKGDTENTRY Gdt)
|
XtpLoadProcessorContext(IN PKGDTENTRY Gdt,
|
||||||
|
IN PKIDTENTRY Idt)
|
||||||
{
|
{
|
||||||
KDESCRIPTOR GdtDescriptor;
|
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
||||||
|
|
||||||
GdtDescriptor.Base = (PVOID)(ULONG_PTR)Gdt;
|
GdtDescriptor.Base = (PVOID)(ULONG_PTR)Gdt;
|
||||||
GdtDescriptor.Limit = 128 * sizeof(KGDTENTRY) - 1;
|
GdtDescriptor.Limit = 128 * sizeof(KGDTENTRY) - 1;
|
||||||
|
|
||||||
|
IdtDescriptor.Base = Idt;
|
||||||
|
IdtDescriptor.Limit = 256 * sizeof(KIDTENTRY) - 1;
|
||||||
|
|
||||||
/* Load GDT and TSS */
|
/* Load GDT and TSS */
|
||||||
HlLoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
HlLoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
||||||
|
HlLoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
||||||
HlLoadTaskRegister((UINT32)KGDT_SYS_TSS);
|
HlLoadTaskRegister((UINT32)KGDT_SYS_TSS);
|
||||||
|
|
||||||
/* Load PCR in FS segment */
|
/* Load PCR in FS segment */
|
||||||
@ -246,6 +286,9 @@ XtpLoadProcessorContext(IN PKGDTENTRY Gdt)
|
|||||||
* @param Gdt
|
* @param Gdt
|
||||||
* Supplies a pointer to memory area containing GDT to fill in.
|
* Supplies a pointer to memory area containing GDT to fill in.
|
||||||
*
|
*
|
||||||
|
* @param Idt
|
||||||
|
* Supplies a pointer to memory area containing IDT to fill in.
|
||||||
|
*
|
||||||
* @return This routine returns a status code.
|
* @return This routine returns a status code.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
@ -254,7 +297,8 @@ XTCDECL
|
|||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
XtpSetProcessorContext(IN PLIST_ENTRY MemoryMappings,
|
XtpSetProcessorContext(IN PLIST_ENTRY MemoryMappings,
|
||||||
IN PVOID *VirtualAddress,
|
IN PVOID *VirtualAddress,
|
||||||
OUT PKGDTENTRY *Gdt)
|
OUT PKGDTENTRY *Gdt,
|
||||||
|
OUT PKIDTENTRY *Idt)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
@ -265,7 +309,7 @@ XtpSetProcessorContext(IN PLIST_ENTRY MemoryMappings,
|
|||||||
HlClearInterruptFlag();
|
HlClearInterruptFlag();
|
||||||
|
|
||||||
/* Initialize GDT */
|
/* Initialize GDT */
|
||||||
Status = XtpInitializeDescriptors(MemoryMappings, VirtualAddress, Gdt);
|
Status = XtpInitializeDescriptors(MemoryMappings, VirtualAddress, Gdt, Idt);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* GDT initialization failure */
|
/* GDT initialization failure */
|
||||||
|
@ -42,7 +42,8 @@ XTCDECL
|
|||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings,
|
XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings,
|
||||||
IN PVOID *VirtualAddress,
|
IN PVOID *VirtualAddress,
|
||||||
OUT PKGDTENTRY *Gdt);
|
OUT PKGDTENTRY *Gdt,
|
||||||
|
OUT PKIDTENTRY *Idt);
|
||||||
|
|
||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
@ -59,13 +60,15 @@ XtpLoadModule(IN PEFI_FILE_HANDLE BootDir,
|
|||||||
|
|
||||||
XTCDECL
|
XTCDECL
|
||||||
VOID
|
VOID
|
||||||
XtpLoadProcessorContext(IN PKGDTENTRY Gdt);
|
XtpLoadProcessorContext(IN PKGDTENTRY Gdt,
|
||||||
|
IN PKIDTENTRY Idt);
|
||||||
|
|
||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
XtpSetProcessorContext(IN PLIST_ENTRY MemoryMappings,
|
XtpSetProcessorContext(IN PLIST_ENTRY MemoryMappings,
|
||||||
IN PVOID *VirtualAddress,
|
IN PVOID *VirtualAddress,
|
||||||
OUT PKGDTENTRY *Gdt);
|
OUT PKGDTENTRY *Gdt,
|
||||||
|
OUT PKIDTENTRY *Idt);
|
||||||
|
|
||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
|
@ -189,6 +189,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
|||||||
ULONG KernelStackPages;
|
ULONG KernelStackPages;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
PKGDTENTRY Gdt;
|
PKGDTENTRY Gdt;
|
||||||
|
PKIDTENTRY Idt;
|
||||||
|
|
||||||
/* Initialize XTOS startup sequence */
|
/* Initialize XTOS startup sequence */
|
||||||
XtLdrProtocol->DbgPrint(L"Initializing XTOS startup sequence\n");
|
XtLdrProtocol->DbgPrint(L"Initializing XTOS startup sequence\n");
|
||||||
@ -259,7 +260,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
|||||||
VirtualAddress += (KernelStackPages * EFI_PAGE_SIZE);
|
VirtualAddress += (KernelStackPages * EFI_PAGE_SIZE);
|
||||||
|
|
||||||
/* Set processor context */
|
/* Set processor context */
|
||||||
Status = XtpSetProcessorContext(&MemoryMappings, &VirtualAddress, &Gdt);
|
Status = XtpSetProcessorContext(&MemoryMappings, &VirtualAddress, &Gdt, &Idt);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Failed to set processor context */
|
/* Failed to set processor context */
|
||||||
@ -278,7 +279,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Load processor context */
|
/* Load processor context */
|
||||||
XtpLoadProcessorContext(Gdt);
|
XtpLoadProcessorContext(Gdt, Idt);
|
||||||
|
|
||||||
/* Call XTOS kernel */
|
/* Call XTOS kernel */
|
||||||
XtLdrProtocol->DbgPrint(L"Booting the XTOS kernel\n");
|
XtLdrProtocol->DbgPrint(L"Booting the XTOS kernel\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user