vserver 1.9.5.x5
[linux-2.6.git] / arch / m32r / boot / compressed / head.S
index 28de481..10b928e 100644 (file)
 #include <asm/page.h>
 #include <asm/assembler.h>
 
+       /*
+        * This code can be loaded anywhere, as long as output will not
+        * overlap it.
+        *
+        * NOTE: This head.S should *NOT* be compiled with -fpic.
+        *
+        */
+
        .global startup
+       .global __bss_start, _ebss, end, zimage_data, zimage_len
        __ALIGN
 startup:
        ldi     r0, #0x0000                     /* SPI, disable EI */
        mvtc    r0, psw
 
+       ldi     r12, #-8
+       bl      1f
+       .fillinsn
+1:
+       seth    r1, #high(CONFIG_MEMORY_START + 0x00400000) /* Start address */
+       add     r12, r14                                /* Real address */
+       sub     r12, r1                                 /* difference */
+
+       .global got_len
+       seth    r3, #high(_GLOBAL_OFFSET_TABLE_+8)
+       or3     r3, r3, #low(_GLOBAL_OFFSET_TABLE_+12)
+       add     r3, r14
+
+       /* Update the contents of global offset table */
+       ldi     r1, #low(got_len)
+       srli    r1, #2
+       beqz    r1, 2f
+       .fillinsn
+1:
+       ld      r2, @r3
+       add     r2, r12
+       st      r2, @r3
+       addi    r3, #4
+       addi    r1, #-1
+       bnez    r1, 1b
+       .fillinsn
+2:
+       /* XXX: resolve plt */
+
 /*
  * Clear BSS first so that there are no surprises...
  */
 #ifdef CONFIG_ISA_DUAL_ISSUE
+       seth    r2, #high(__bss_start)
+       or3     r2, r2, #low(__bss_start)
+       add     r2, r12
+       seth    r3, #high(_ebss)
+       or3     r3, r3, #low(_ebss)
+       add     r3, r12
+       sub     r3, r2
 
-       LDIMM   (r2, __bss_start)
-       LDIMM   (r3, _end)
-       sub     r3, r2          ; BSS size in bytes
        ; R4 = BSS size in longwords (rounded down)
        mv      r4, r3              ||  ldi     r1, #0
        srli    r4, #4              ||  addi    r2, #-4
@@ -52,10 +94,13 @@ startup:
 .Lendloop2:
 
 #else /* not CONFIG_ISA_DUAL_ISSUE */
-
-       LDIMM   (r2, __bss_start)
-       LDIMM   (r3, _end)
-       sub     r3, r2          ; BSS size in bytes
+       seth    r2, #high(__bss_start)
+       or3     r2, r2, #low(__bss_start)
+       add     r2, r12
+       seth    r3, #high(_ebss)
+       or3     r3, r3, #low(_ebss)
+       add     r3, r12
+       sub     r3, r2
        mv      r4, r3
        srli    r4, #2          ; R4 = BSS size in longwords (rounded down)
        ldi     r1, #0          ; clear R1 for longwords store
@@ -66,27 +111,29 @@ startup:
        addi    r4, #-1         ; decrement count
        bnez    r4, .Lloop1     ; go do some more
 .Lendloop1:
-       and3    r4, r3, #3      ; get no. of remaining BSS bytes to clear
-       addi    r2, #4          ; account for pre-inc store
-       beqz    r4, .Lendloop2  ; any more to go?
-.Lloop2:
-       stb     r1, @r2         ; yep, zero out another byte
-       addi    r2, #1          ; bump address
-       addi    r4, #-1         ; decrement count
-       bnez    r4, .Lloop2     ; go do some more
-.Lendloop2:
 
 #endif /* not CONFIG_ISA_DUAL_ISSUE */
 
-       seth    r0, #shigh(stack_start)
-       ld      sp, @(r0, low(stack_start))     /* set stack point */
+       seth    r1, #high(end)
+       or3     r1, r1, #low(end)
+       add     r1, r12
+       mv      sp, r1
 
 /*
  * decompress the kernel
  */
+       mv      r0, sp
+       srli    r0, 31                          /* MMU is ON or OFF */
+        seth   r1, #high(zimage_data)
+        or3    r1, r1, #low(zimage_data)
+       add     r1, r12
+        seth   r2, #high(zimage_len)
+        or3    r2, r2, #low(zimage_len)
+       mv      r3, sp
+
        bl      decompress_kernel
 
-#if defined(CONFIG_CHIP_M32700)
+#if defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_VDEC2)
        /* Cache flush */
        ldi     r0, -1
        ldi     r1, 0xd0        ; invalidate i-cache, copy back d-cache
@@ -94,9 +141,14 @@ startup:
 #else
 #error "put your cache flush function, please"
 #endif
-        seth   r0, #high(CONFIG_MEMORY_START)
-        or3    r0, r0, #0x2000
-        jmp    r0
+
+       mv      r0, sp
+       srli    r0, 31                          /* MMU is ON or OFF */
+       slli    r0, 31
+       or3     r0, r0, #0x2000
+       seth    r1, #high(CONFIG_MEMORY_START)
+       or      r0, r1
+       jmp     r0
 
        .balign 512
 fake_headers_as_bzImage: