From c4a7df6f38f0695bf714c9b62d2f61ca690db28f Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Wed, 20 Aug 2025 20:20:35 +0200 Subject: [PATCH] Extract trampoline code into a separate file --- xtoskrnl/CMakeLists.txt | 2 + xtoskrnl/ar/amd64/archsup.S | 121 -------------------------------- xtoskrnl/ar/amd64/boot.S | 133 ++++++++++++++++++++++++++++++++++++ xtoskrnl/ar/i686/boot.S | 14 ++++ 4 files changed, 149 insertions(+), 121 deletions(-) create mode 100644 xtoskrnl/ar/amd64/boot.S create mode 100644 xtoskrnl/ar/i686/boot.S diff --git a/xtoskrnl/CMakeLists.txt b/xtoskrnl/CMakeLists.txt index 0e36cba..9f208da 100644 --- a/xtoskrnl/CMakeLists.txt +++ b/xtoskrnl/CMakeLists.txt @@ -9,6 +9,7 @@ include_directories( # Specify list of library source code files list(APPEND LIBXTOS_SOURCE + ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.c ${XTOSKRNL_SOURCE_DIR}/hl/cport.c ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c @@ -23,6 +24,7 @@ list(APPEND LIBXTOS_SOURCE # Specify list of kernel source code files list(APPEND XTOSKRNL_SOURCE ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/archsup.S + ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/globals.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.c diff --git a/xtoskrnl/ar/amd64/archsup.S b/xtoskrnl/ar/amd64/archsup.S index 6cee551..849df4f 100644 --- a/xtoskrnl/ar/amd64/archsup.S +++ b/xtoskrnl/ar/amd64/archsup.S @@ -4,7 +4,6 @@ * FILE: xtoskrnl/ar/amd64/archsup.S * DESCRIPTION: Provides AMD64 architecture features not implementable in C * DEVELOPERS: Rafal Kupiec - * Aiken Harris */ #include @@ -13,126 +12,6 @@ .text -/** - * Enables eXtended Physical Addressing (XPA). - * - * @param PageMap - * Supplies a pointer to the page map to be used. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -.global ArEnableExtendedPhysicalAddressing -ArEnableExtendedPhysicalAddressing: - /* Save the original CR4 register */ - movq %cr4, %rax - - /* Save the state of stack pointer and non-volatile registers */ - movq %rsp, XpaRegisterSaveArea(%rip) - movq %rbp, XpaRegisterSaveArea+0x08(%rip) - movq %rax, XpaRegisterSaveArea+0x10(%rip) - movq %rbx, XpaRegisterSaveArea+0x18(%rip) - - /* Save the original CR0 register */ - movq %cr0, %rbp - - /* Load temporary GDT required for mode transitions */ - leaq XpaTemporaryGdtDesc(%rip), %rax - movq %rax, XpaTemporaryGdtBase(%rip) - lgdtq XpaTemporaryGdtSize(%rip) - - /* Load addresses for entering compatibility mode and re-entering long mode */ - leaq XpaEnterCompatMode(%rip), %rax - leaq XpaEnterLongMode(%rip), %rbx - - /* Push the 32-bit code segment selector and the target address for a far jump */ - pushq $GDT_R0_CMCODE - pushq %rax - - /* Perform a far return to switch to 32-bit compatibility mode */ - lretq - -XpaEnterCompatMode: - /* Enter 32-bit compatibility mode */ - .code32 - - /* Store the PageMap pointer on the stack for future use */ - pushl %ecx - - /* Set the stack segment to the 32-bit data segment selector */ - movl $GDT_R0_DATA, %eax - movl %eax, %ss - - /* Disable PGE and PCIDE to ensure all TLB entries will be flushed */ - movl %cr4, %eax - andl $~(CR4_PGE | CR4_PCIDE), %eax - movl %eax, %cr4 - - /* Temporarily disable paging */ - movl %ebp, %eax - andl $~CR0_PG, %eax - movl %eax, %cr0 - - /* Disable Long Mode as prerequisite for enabling 5-level paging */ - movl $X86_MSR_EFER, %ecx - rdmsr - andl $~X86_MSR_EFER_LME, %eax - wrmsr - - /* Transition to 5-level paging (PML5/LA57) */ - movl %cr4, %eax - orl $CR4_LA57, %eax - movl %eax, %cr4 - - /* Restore the PageMap pointer from the stack and load it into CR3 */ - popl %ecx - movl %ecx, %cr3 - - /* Re-enable Long Mode */ - movl $X86_MSR_EFER, %ecx - rdmsr - orl $X86_MSR_EFER_LME, %eax - wrmsr - - /* Restore CR0 with paging enabled and flush the instruction pipeline */ - movl %ebp, %cr0 - call XpaFlushInstructions - -XpaFlushInstructions: - /* Push the 64-bit code segment selector and the target address for a far jump */ - pushl $GDT_R0_CODE - pushl %ebx - - /* Perform a far return to switch to 64-bit long mode */ - lretl - -XpaEnterLongMode: - /* Enter 64-bit long mode */ - .code64 - - /* Restore the stack pointer and non-volatile registers */ - movq XpaRegisterSaveArea(%rip), %rsp - movq XpaRegisterSaveArea+8(%rip), %rbp - movq XpaRegisterSaveArea+0x10(%rip), %rax - movq XpaRegisterSaveArea+0x18(%rip), %rbx - - /* Restore the original CR4 register with LA57 bit set */ - orq $CR4_LA57, %rax - movq %rax, %cr4 - - /* Return to the caller */ - retq - -/* Data section for saving registers and temporary GDT */ -XpaRegisterSaveArea: .quad 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 -XpaTemporaryGdtSize: .short ArEnableExtendedPhysicalAddressingEnd - XpaTemporaryGdtDesc - 1 -XpaTemporaryGdtBase: .quad 0x0000000000000000 -XpaTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF - -.global ArEnableExtendedPhysicalAddressingEnd -ArEnableExtendedPhysicalAddressingEnd: - /** * Creates a trap handler for the specified vector. * diff --git a/xtoskrnl/ar/amd64/boot.S b/xtoskrnl/ar/amd64/boot.S new file mode 100644 index 0000000..d631845 --- /dev/null +++ b/xtoskrnl/ar/amd64/boot.S @@ -0,0 +1,133 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ar/amd64/boot.S + * DESCRIPTION: AMD64-specific boot code for setting up the low-level CPU environment + * DEVELOPERS: Aiken Harris + */ + +#include + +.altmacro +.text + + +/** + * Enables eXtended Physical Addressing (XPA). + * + * @param PageMap + * Supplies a pointer to the page map to be used. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +.global ArEnableExtendedPhysicalAddressing +ArEnableExtendedPhysicalAddressing: + /* Save the original CR4 register */ + movq %cr4, %rax + + /* Save the state of stack pointer and non-volatile registers */ + movq %rsp, XpaRegisterSaveArea(%rip) + movq %rbp, XpaRegisterSaveArea+0x08(%rip) + movq %rax, XpaRegisterSaveArea+0x10(%rip) + movq %rbx, XpaRegisterSaveArea+0x18(%rip) + + /* Save the original CR0 register */ + movq %cr0, %rbp + + /* Load temporary GDT required for mode transitions */ + leaq XpaTemporaryGdtDesc(%rip), %rax + movq %rax, XpaTemporaryGdtBase(%rip) + lgdtq XpaTemporaryGdtSize(%rip) + + /* Load addresses for entering compatibility mode and re-entering long mode */ + leaq XpaEnterCompatMode(%rip), %rax + leaq XpaEnterLongMode(%rip), %rbx + + /* Push the 32-bit code segment selector and the target address for a far jump */ + pushq $GDT_R0_CMCODE + pushq %rax + + /* Perform a far return to switch to 32-bit compatibility mode */ + lretq + +XpaEnterCompatMode: + /* Enter 32-bit compatibility mode */ + .code32 + + /* Store the PageMap pointer on the stack for future use */ + pushl %ecx + + /* Set the stack segment to the 32-bit data segment selector */ + movl $GDT_R0_DATA, %eax + movl %eax, %ss + + /* Disable PGE and PCIDE to ensure all TLB entries will be flushed */ + movl %cr4, %eax + andl $~(CR4_PGE | CR4_PCIDE), %eax + movl %eax, %cr4 + + /* Temporarily disable paging */ + movl %ebp, %eax + andl $~CR0_PG, %eax + movl %eax, %cr0 + + /* Disable Long Mode as prerequisite for enabling 5-level paging */ + movl $X86_MSR_EFER, %ecx + rdmsr + andl $~X86_MSR_EFER_LME, %eax + wrmsr + + /* Transition to 5-level paging (PML5/LA57) */ + movl %cr4, %eax + orl $CR4_LA57, %eax + movl %eax, %cr4 + + /* Restore the PageMap pointer from the stack and load it into CR3 */ + popl %ecx + movl %ecx, %cr3 + + /* Re-enable Long Mode */ + movl $X86_MSR_EFER, %ecx + rdmsr + orl $X86_MSR_EFER_LME, %eax + wrmsr + + /* Restore CR0 with paging enabled and flush the instruction pipeline */ + movl %ebp, %cr0 + call XpaFlushInstructions + +XpaFlushInstructions: + /* Push the 64-bit code segment selector and the target address for a far jump */ + pushl $GDT_R0_CODE + pushl %ebx + + /* Perform a far return to switch to 64-bit long mode */ + lretl + +XpaEnterLongMode: + /* Enter 64-bit long mode */ + .code64 + + /* Restore the stack pointer and non-volatile registers */ + movq XpaRegisterSaveArea(%rip), %rsp + movq XpaRegisterSaveArea+8(%rip), %rbp + movq XpaRegisterSaveArea+0x10(%rip), %rax + movq XpaRegisterSaveArea+0x18(%rip), %rbx + + /* Restore the original CR4 register with LA57 bit set */ + orq $CR4_LA57, %rax + movq %rax, %cr4 + + /* Return to the caller */ + retq + +/* Data section for saving registers and temporary GDT */ +XpaRegisterSaveArea: .quad 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 +XpaTemporaryGdtSize: .short ArEnableExtendedPhysicalAddressingEnd - XpaTemporaryGdtDesc - 1 +XpaTemporaryGdtBase: .quad 0x0000000000000000 +XpaTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF + +.global ArEnableExtendedPhysicalAddressingEnd +ArEnableExtendedPhysicalAddressingEnd: diff --git a/xtoskrnl/ar/i686/boot.S b/xtoskrnl/ar/i686/boot.S new file mode 100644 index 0000000..edb4c05 --- /dev/null +++ b/xtoskrnl/ar/i686/boot.S @@ -0,0 +1,14 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ar/i686/boot.S + * DESCRIPTION: i686-specific boot code for setting up the low-level CPU environment + * DEVELOPERS: Aiken Harris + */ + +#include + +.altmacro +.text + +