[haiku-commits] BRANCH xyzzy-github.x86_64 - src/system/boot/platform/bios_ia32 headers/posix/arch/x86_64

  • From: xyzzy-github.x86_64 <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 5 Jul 2012 15:49:14 +0200 (CEST)

added 2 changesets to branch 'refs/remotes/xyzzy-github/x86_64'
old head: 78d482e3b8a7b67ed37a7479fddeb735897f282d
new head: 0da10c8b51f9ec443a53873b37d07fab30a5734e

----------------------------------------------------------------------------

2f36ef5: Fixed the x86_64 setjmp implementation.
  
  * typedef for jmp_buf was using int where it should be long.
  * setjmp was clearing the buffer pointer rather than the signal mask before
    calling sigsetjmp.
  * KDL now works without crashing on x86_64.

0da10c8: Some fixes to the long mode switch code.
  
  * Wasn't storing the fixed virtual address of the PML4 in kernel_args.
  * After switching to long mode, reload GDTR with the virtual address of
    the GDT. This was working fine until now because the physical address
    was identity mapped, but broke as soon as I removed the identity
    mapping.

                                      [ Alex Smith <alex@xxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

5 files changed, 38 insertions(+), 18 deletions(-)
headers/posix/arch/x86_64/arch_setjmp.h          |    2 +-
src/system/boot/platform/bios_ia32/long.cpp      |   13 +++----
src/system/boot/platform/bios_ia32/long.h        |    5 +--
src/system/boot/platform/bios_ia32/long_asm.S    |   34 ++++++++++++++----
src/system/libroot/posix/arch/x86_64/sigsetjmp.S |    2 +-

############################################################################

Commit:      2f36ef5afe5aae9b150597d6281826a1c3ed2f3a

Author:      Alex Smith <alex@xxxxxxxxxxxxxxxx>
Date:        Thu Jul  5 12:52:36 2012 UTC

Fixed the x86_64 setjmp implementation.

* typedef for jmp_buf was using int where it should be long.
* setjmp was clearing the buffer pointer rather than the signal mask before
  calling sigsetjmp.
* KDL now works without crashing on x86_64.

----------------------------------------------------------------------------

diff --git a/headers/posix/arch/x86_64/arch_setjmp.h 
b/headers/posix/arch/x86_64/arch_setjmp.h
index 2d8f39e..e1043da 100644
--- a/headers/posix/arch/x86_64/arch_setjmp.h
+++ b/headers/posix/arch/x86_64/arch_setjmp.h
@@ -6,6 +6,6 @@
 #define _ARCH_SETJMP_H_
 
 
-typedef int __jmp_buf[8];
+typedef unsigned long __jmp_buf[8];
 
 #endif /* _ARCH_SETJMP_H_ */
diff --git a/src/system/libroot/posix/arch/x86_64/sigsetjmp.S 
b/src/system/libroot/posix/arch/x86_64/sigsetjmp.S
index 25bef80..0e7b5af 100644
--- a/src/system/libroot/posix/arch/x86_64/sigsetjmp.S
+++ b/src/system/libroot/posix/arch/x86_64/sigsetjmp.S
@@ -31,7 +31,7 @@ FUNCTION_END(setjmp)
 /* int setjmp(jmp_buf buffer) */
 FUNCTION(setjmp):
        // Jump to sigsetjmp with a zero saveMask.
-       xorl    %edi, %edi
+       xorl    %esi, %esi
        jmp             sigsetjmp
 FUNCTION_END(setjmp)
 

############################################################################

Commit:      0da10c8b51f9ec443a53873b37d07fab30a5734e

Author:      Alex Smith <alex@xxxxxxxxxxxxxxxx>
Date:        Thu Jul  5 12:55:59 2012 UTC

Some fixes to the long mode switch code.

* Wasn't storing the fixed virtual address of the PML4 in kernel_args.
* After switching to long mode, reload GDTR with the virtual address of
  the GDT. This was working fine until now because the physical address
  was identity mapped, but broke as soon as I removed the identity
  mapping.

----------------------------------------------------------------------------

diff --git a/src/system/boot/platform/bios_ia32/long.cpp 
b/src/system/boot/platform/bios_ia32/long.cpp
index 60bcdcf..2a942df 100644
--- a/src/system/boot/platform/bios_ia32/long.cpp
+++ b/src/system/boot/platform/bios_ia32/long.cpp
@@ -104,7 +104,7 @@ long_mmu_init()
        // Allocate the top level PML4.
        pml4 = (uint64*)mmu_allocate_page(&gKernelArgs.arch_args.phys_pgdir);
        memset(pml4, 0, B_PAGE_SIZE);
-       gKernelArgs.arch_args.vir_pgdir = (uint64)(addr_t)pml4;
+       gKernelArgs.arch_args.vir_pgdir = fix_address((uint64)(addr_t)pml4);
 
        // Find the highest physical memory address. We map all physical memory
        // into the kernel address space, so we want to make sure we map 
everything
@@ -319,14 +319,11 @@ long_start_kernel()
        // We're about to enter the kernel -- disable console output.
        stdout = NULL;
 
-       // Load the new GDT. The physical address is used because 
long_enter_kernel
-       // disables 32-bit paging.
-       gdt_idt_descr gdtr = { GDT_LIMIT - 1, gKernelArgs.arch_args.phys_gdt };
-       asm volatile("lgdt %0" :: "m"(gdtr));
-
        // Enter the kernel!
-       long_enter_kernel(gKernelArgs.arch_args.phys_pgdir, entry, stackTop,
-               kernelArgs, 0);
+       long_enter_kernel(gKernelArgs.arch_args.phys_pgdir,
+               gKernelArgs.arch_args.phys_gdt, gKernelArgs.arch_args.vir_gdt,
+               entry, stackTop, kernelArgs, 0);
+
        panic("Shouldn't get here");
 }
 
diff --git a/src/system/boot/platform/bios_ia32/long.h 
b/src/system/boot/platform/bios_ia32/long.h
index de2a039..084b5b3 100644
--- a/src/system/boot/platform/bios_ia32/long.h
+++ b/src/system/boot/platform/bios_ia32/long.h
@@ -9,8 +9,9 @@
 #include <SupportDefs.h>
 
 
-extern "C" void long_enter_kernel(uint32 pml4, uint64 entry, uint64 stackTop,
-       uint64 kernelArgs, int currentCPU);
+extern "C" void long_enter_kernel(uint32 physPML4, uint32 physGDT,
+       uint64 virtGDT, uint64 entry, uint64 stackTop, uint64 kernelArgs,
+       int currentCPU);
 
 extern void long_start_kernel();
 
diff --git a/src/system/boot/platform/bios_ia32/long_asm.S 
b/src/system/boot/platform/bios_ia32/long_asm.S
index 43be6af..30bfd2b 100644
--- a/src/system/boot/platform/bios_ia32/long_asm.S
+++ b/src/system/boot/platform/bios_ia32/long_asm.S
@@ -11,13 +11,22 @@
 #undef __x86_64__
 
 
+#define GDT_LIMIT 0x800
+
+
 .code32
 
 
-/*!    void long_enter_kernel(uint32 pml4, uint64 entry, uint64 stackTop,
-               uint64 kernelArgs, int currentCPU);
+/*!    void long_enter_kernel(uint32 physPML4, uint32 physGDT, uint64 virtGDT,
+               uint64 entry, uint64 stackTop, uint64 kernelArgs, int 
currentCPU);
 */
 FUNCTION(long_enter_kernel):
+       // We're about to disable paging, so we need to load the the physical
+       // address of our GDT.
+       movl    8(%esp), %eax
+       movl    %eax, (long_gdtr + 2)
+       lgdtl   (long_gdtr)
+
        // Currently running with 32-bit paging tables at an identity mapped
        // address. To switch to 64-bit paging we must first disable 32-bit 
paging,
        // otherwise loading the new CR3 will fault.
@@ -62,11 +71,16 @@ FUNCTION(long_enter_kernel):
        // Clear the high 32 bits of RSP.
        movl    %esp, %esp
 
+       // Load the virtual address of the GDT.
+       movq    12(%rsp), %rax
+       movq    %rax, long_gdtr + 2(%rip)
+       lgdtq   long_gdtr(%rip)
+
        // Get the entry point address, arguments and new stack pointer.
-       movq    8(%rsp), %rax
-       movq    24(%rsp), %rdi
-       movl    32(%rsp), %esi
-       movq    16(%rsp), %rsp
+       movq    20(%rsp), %rax
+       movq    36(%rsp), %rdi
+       movl    44(%rsp), %esi
+       movq    28(%rsp), %rsp
 
        // Clear the stack frame/RFLAGS.
        xorq    %rbp, %rbp
@@ -75,3 +89,11 @@ FUNCTION(long_enter_kernel):
 
        // Call the kernel entry point.
        call    *%rax
+
+       
+.data
+
+
+long_gdtr:
+       .word   GDT_LIMIT - 1
+       .quad   0


Other related posts:

  • » [haiku-commits] BRANCH xyzzy-github.x86_64 - src/system/boot/platform/bios_ia32 headers/posix/arch/x86_64 - xyzzy-github . x86_64