Merge branch 'oprofile-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[deliverable/linux.git] / arch / x86 / boot / compressed / head_64.S
index a0b18426069a17a4ff7dfda0acf8f08a7876ed0a..f62c284db9eb5c94edf1df794b26e13ace0b4113 100644 (file)
@@ -84,22 +84,17 @@ ENTRY(startup_32)
 
 #ifdef CONFIG_RELOCATABLE
        movl    %ebp, %ebx
-       addl    $(PMD_PAGE_SIZE -1), %ebx
-       andl    $PMD_PAGE_MASK, %ebx
+       movl    BP_kernel_alignment(%esi), %eax
+       decl    %eax
+       addl    %eax, %ebx
+       notl    %eax
+       andl    %eax, %ebx
 #else
-       movl    $CONFIG_PHYSICAL_START, %ebx
+       movl    $LOAD_PHYSICAL_ADDR, %ebx
 #endif
 
-       /* Replace the compressed data size with the uncompressed size */
-       subl    input_len(%ebp), %ebx
-       movl    output_len(%ebp), %eax
-       addl    %eax, %ebx
-       /* Add 8 bytes for every 32K input block */
-       shrl    $12, %eax
-       addl    %eax, %ebx
-       /* Add 32K + 18 bytes of extra slack and align on a 4K boundary */
-       addl    $(32768 + 18 + 4095), %ebx
-       andl    $~4095, %ebx
+       /* Target address to relocate to for decompression */
+       addl    $z_extract_offset, %ebx
 
 /*
  * Prepare for entering 64 bit mode
@@ -223,31 +218,26 @@ ENTRY(startup_64)
         *
         * If it is a relocatable kernel then decompress and run the kernel
         * from load address aligned to 2MB addr, otherwise decompress and
-        * run the kernel from CONFIG_PHYSICAL_START
+        * run the kernel from LOAD_PHYSICAL_ADDR
+        *
+        * We cannot rely on the calculation done in 32-bit mode, since we
+        * may have been invoked via the 64-bit entry point.
         */
 
        /* Start with the delta to where the kernel will run at. */
 #ifdef CONFIG_RELOCATABLE
        leaq    startup_32(%rip) /* - $startup_32 */, %rbp
-       addq    $(PMD_PAGE_SIZE - 1), %rbp
-       andq    $PMD_PAGE_MASK, %rbp
-       movq    %rbp, %rbx
+       movl    BP_kernel_alignment(%rsi), %eax
+       decl    %eax
+       addq    %rax, %rbp
+       notq    %rax
+       andq    %rax, %rbp
 #else
-       movq    $CONFIG_PHYSICAL_START, %rbp
-       movq    %rbp, %rbx
+       movq    $LOAD_PHYSICAL_ADDR, %rbp
 #endif
 
-       /* Replace the compressed data size with the uncompressed size */
-       movl    input_len(%rip), %eax
-       subq    %rax, %rbx
-       movl    output_len(%rip), %eax
-       addq    %rax, %rbx
-       /* Add 8 bytes for every 32K input block */
-       shrq    $12, %rax
-       addq    %rax, %rbx
-       /* Add 32K + 18 bytes of extra slack and align on a 4K boundary */
-       addq    $(32768 + 18 + 4095), %rbx
-       andq    $~4095, %rbx
+       /* Target address to relocate to for decompression */
+       leaq    z_extract_offset(%rbp), %rbx
 
        /* Set up the stack */
        leaq    boot_stack_end(%rbx), %rsp
@@ -260,15 +250,15 @@ ENTRY(startup_64)
  * Copy the compressed kernel to the end of our buffer
  * where decompression in place becomes safe.
  */
-       leaq    _bss(%rip), %r8
-       leaq    _bss(%rbx), %r9
+       pushq   %rsi
+       leaq    (_bss-8)(%rip), %rsi
+       leaq    (_bss-8)(%rbx), %rdi
        movq    $_bss /* - $startup_32 */, %rcx
-1:     subq    $8, %r8
-       subq    $8, %r9
-       movq    0(%r8), %rax
-       movq    %rax, 0(%r9)
-       subq    $8, %rcx
-       jnz     1b
+       shrq    $3, %rcx
+       std
+       rep     movsq
+       cld
+       popq    %rsi
 
 /*
  * Jump to the relocated address.
@@ -282,23 +272,22 @@ relocated:
 /*
  * Clear BSS (stack is currently empty)
  */
-       xorq    %rax, %rax
-       leaq    _bss(%rbx), %rdi
-       leaq    _ebss(%rbx), %rcx
+       xorl    %eax, %eax
+       leaq    _bss(%rip), %rdi
+       leaq    _ebss(%rip), %rcx
        subq    %rdi, %rcx
-       cld
-       rep     stosb
+       shrq    $3, %rcx
+       rep     stosq
 
 /*
  * Do the decompression, and jump to the new kernel..
  */
-       pushq   %rsi                    # Save the real mode argument
-       movq    %rsi, %rdi              # real mode address
-       leaq    boot_heap(%rip), %rsi   # malloc area for uncompression
-       leaq    input_data(%rip), %rdx  # input_data
-       movl    input_len(%rip), %eax
-       movq    %rax, %rcx              # input_len
-       movq    %rbp, %r8               # output
+       pushq   %rsi                    /* Save the real mode argument */
+       movq    %rsi, %rdi              /* real mode address */
+       leaq    boot_heap(%rip), %rsi   /* malloc area for uncompression */
+       leaq    input_data(%rip), %rdx  /* input_data */
+       movl    $z_input_len, %ecx      /* input_len */
+       movq    %rbp, %r8               /* output target address */
        call    decompress_kernel
        popq    %rsi
 
This page took 0.031363 seconds and 5 git commands to generate.