Back to home page

LXR

 
 

    


0001 /*
0002  * linux/arch/unicore32/boot/compressed/head.S
0003  *
0004  * Code specific to PKUnity SoC and UniCore ISA
0005  *
0006  * Copyright (C) 2001-2010 GUAN Xue-tao
0007  *
0008  * This program is free software; you can redistribute it and/or modify
0009  * it under the terms of the GNU General Public License version 2 as
0010  * published by the Free Software Foundation.
0011  */
0012 #include <linux/linkage.h>
0013 #include <mach/memory.h>
0014 
0015 #define csub    cmpsub
0016 #define cand    cmpand
0017 #define nop8    nop; nop; nop; nop; nop; nop; nop; nop
0018 
0019         .section ".start", #alloc, #execinstr
0020         .text
0021 start:
0022         .type   start,#function
0023 
0024         /* Initialize ASR, PRIV mode and INTR off */
0025         mov r0, #0xD3
0026         mov.a   asr, r0
0027 
0028         adr r0, LC0
0029         ldm (r1, r2, r3, r5, r6, r7, r8), [r0]+
0030         ldw sp, [r0+], #28
0031         sub.a   r0, r0, r1      @ calculate the delta offset
0032 
0033         /*
0034          * if delta is zero, we are running at the address
0035          * we were linked at.
0036          */
0037         beq not_relocated
0038 
0039         /*
0040          * We're running at a different address.  We need to fix
0041          * up various pointers:
0042          *   r5 - zImage base address (_start)
0043          *   r7 - GOT start
0044          *   r8 - GOT end
0045          */
0046         add r5, r5, r0
0047         add r7, r7, r0
0048         add r8, r8, r0
0049 
0050         /*
0051          * we need to fix up pointers into the BSS region.
0052          *   r2 - BSS start
0053          *   r3 - BSS end
0054          *   sp - stack pointer
0055          */
0056         add r2, r2, r0
0057         add r3, r3, r0
0058         add sp, sp, r0
0059 
0060         /*
0061          * Relocate all entries in the GOT table.
0062          * This fixes up the C references.
0063          *   r7 - GOT start
0064          *   r8 - GOT end
0065          */
0066 1001:       ldw r1, [r7+], #0
0067         add r1, r1, r0
0068         stw.w   r1, [r7]+, #4
0069         csub.a  r7, r8
0070         bub 1001b
0071 
0072 not_relocated:
0073         /*
0074          * Clear BSS region.
0075          *   r2 - BSS start
0076          *   r3 - BSS end
0077          */
0078         mov r0, #0
0079 1002:       stw.w   r0, [r2]+, #4
0080         csub.a  r2, r3
0081         bub 1002b
0082 
0083         /*
0084          * Turn on the cache.
0085          */
0086                 mov     r0, #0
0087                 movc    p0.c5, r0, #28      @ cache invalidate all
0088                 nop8
0089                 movc    p0.c6, r0, #6       @ tlb invalidate all
0090                 nop8
0091 
0092                 mov     r0, #0x1c       @ en icache and wb dcache
0093                 movc    p0.c1, r0, #0
0094                 nop8
0095 
0096         /*
0097          * Set up some pointers, for starting decompressing.
0098          */
0099 
0100         mov r1, sp          @ malloc space above stack
0101         add r2, sp, #0x10000    @ 64k max
0102 
0103         /*
0104          * Check to see if we will overwrite ourselves.
0105          *   r4 = final kernel address
0106          *   r5 = start of this image
0107          *   r6 = size of decompressed image
0108          *   r2 = end of malloc space (and therefore this image)
0109          * We basically want:
0110          *   r4 >= r2 -> OK
0111          *   r4 + image length <= r5 -> OK
0112          */
0113         ldw r4, =KERNEL_IMAGE_START
0114         csub.a  r4, r2
0115         bea wont_overwrite
0116         add r0, r4, r6
0117         csub.a  r0, r5
0118         beb wont_overwrite
0119 
0120         /*
0121          * If overwrite, just print error message
0122          */
0123         b   __error_overwrite
0124 
0125         /*
0126          * We're not in danger of overwriting ourselves.
0127          * Do this the simple way.
0128          */
0129 wont_overwrite:
0130         /*
0131          * decompress_kernel:
0132          *   r0: output_start
0133          *   r1: free_mem_ptr_p
0134          *   r2: free_mem_ptr_end_p
0135          */
0136         mov r0, r4
0137         b.l decompress_kernel   @ C functions
0138 
0139         /*
0140          * Clean and flush the cache to maintain consistency.
0141          */
0142         mov r0, #0
0143                 movc    p0.c5, r0, #14      @ flush dcache
0144         nop8
0145                 movc    p0.c5, r0, #20      @ icache invalidate all
0146                 nop8
0147 
0148         /*
0149          * Turn off the Cache and MMU.
0150          */
0151         mov r0, #0          @ disable i/d cache and MMU
0152         movc    p0.c1, r0, #0
0153                 nop8
0154 
0155         mov r0, #0          @ must be zero
0156         ldw r4, =KERNEL_IMAGE_START
0157         mov pc, r4          @ call kernel
0158 
0159 
0160         .align  2
0161         .type   LC0, #object
0162 LC0:        .word   LC0         @ r1
0163         .word   __bss_start     @ r2
0164         .word   _end            @ r3
0165         .word   _start          @ r5
0166         .word   _image_size     @ r6
0167         .word   _got_start      @ r7
0168         .word   _got_end        @ r8
0169         .word   decompress_stack_end    @ sp
0170         .size   LC0, . - LC0
0171 
0172 print_string:
0173 #ifdef CONFIG_DEBUG_OCD
0174 2001:       ldb.w   r1, [r0]+, #1
0175         csub.a  r1, #0
0176         bne 2002f
0177         mov pc, lr
0178 2002:
0179         movc    r2, p1.c0, #0
0180         cand.a  r2, #2
0181         bne 2002b
0182         movc    p1.c1, r1, #1
0183         csub.a  r1, #'\n'
0184         cmoveq  r1, #'\r'
0185         beq 2002b
0186         b   2001b
0187 #else
0188         mov pc, lr
0189 #endif
0190 
0191 __error_overwrite:
0192         adr r0, str_error
0193         b.l print_string
0194 2001:       nop8
0195         b   2001b
0196 str_error:  .asciz  "\nError: Kernel address OVERWRITE\n"
0197         .align
0198 
0199         .ltorg
0200 
0201         .align  4
0202         .section ".stack", "aw", %nobits
0203 decompress_stack:   .space  4096
0204 decompress_stack_end: