efi/x86: Remove GDT setup from efi_main
[linux-2.6-microblaze.git] / arch / x86 / boot / compressed / head_32.S
index cb2cb91..356060c 100644 (file)
 SYM_FUNC_START(startup_32)
        cld
        cli
-       movl    $__BOOT_DS, %eax
-       movl    %eax, %ds
-       movl    %eax, %es
-       movl    %eax, %fs
-       movl    %eax, %gs
-       movl    %eax, %ss
 
 /*
  * Calculate the delta between where we were compiled to run
@@ -84,6 +78,19 @@ SYM_FUNC_START(startup_32)
 1:     popl    %ebp
        subl    $1b, %ebp
 
+       /* Load new GDT */
+       leal    gdt(%ebp), %eax
+       movl    %eax, 2(%eax)
+       lgdt    (%eax)
+
+       /* Load segment registers with our descriptors */
+       movl    $__BOOT_DS, %eax
+       movl    %eax, %ds
+       movl    %eax, %es
+       movl    %eax, %fs
+       movl    %eax, %gs
+       movl    %eax, %ss
+
 /*
  * %ebp contains the address we are loaded at by the boot loader and %ebx
  * contains the address where we should move the kernel image temporarily
@@ -129,6 +136,16 @@ SYM_FUNC_START(startup_32)
        cld
        popl    %esi
 
+       /*
+        * The GDT may get overwritten either during the copy we just did or
+        * during extract_kernel below. To avoid any issues, repoint the GDTR
+        * to the new copy of the GDT. EAX still contains the previously
+        * calculated relocation offset of init_size - _end.
+        */
+       leal    gdt(%ebx), %edx
+       addl    %eax, 2(%edx)
+       lgdt    (%edx)
+
 /*
  * Jump to the relocated address.
  */
@@ -201,6 +218,17 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
        jmp     *%eax
 SYM_FUNC_END(.Lrelocated)
 
+       .data
+       .balign 8
+SYM_DATA_START_LOCAL(gdt)
+       .word   gdt_end - gdt - 1
+       .long   0
+       .word   0
+       .quad   0x0000000000000000      /* Reserved */
+       .quad   0x00cf9a000000ffff      /* __KERNEL_CS */
+       .quad   0x00cf92000000ffff      /* __KERNEL_DS */
+SYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end)
+
 /*
  * Stack and heap for uncompression
  */