1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
|
/*
* linux/arch/unicore32/boot/compressed/head.S
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <mach/memory.h>
#define csub cmpsub
#define cand cmpand
#define nop8 nop; nop; nop; nop; nop; nop; nop; nop
.section ".start", #alloc, #execinstr
.text
start:
.type start,#function
/* Initialize ASR, PRIV mode and INTR off */
mov r0, #0xD3
mov.a asr, r0
adr r0, LC0
ldm (r1, r2, r3, r5, r6, r7, r8), [r0]+
ldw sp, [r0+], #28
sub.a r0, r0, r1 @ calculate the delta offset
/*
* if delta is zero, we are running at the address
* we were linked at.
*/
beq not_relocated
/*
* We're running at a different address. We need to fix
* up various pointers:
* r5 - zImage base address (_start)
* r7 - GOT start
* r8 - GOT end
*/
add r5, r5, r0
add r7, r7, r0
add r8, r8, r0
/*
* we need to fix up pointers into the BSS region.
* r2 - BSS start
* r3 - BSS end
* sp - stack pointer
*/
add r2, r2, r0
add r3, r3, r0
add sp, sp, r0
/*
* Relocate all entries in the GOT table.
* This fixes up the C references.
* r7 - GOT start
* r8 - GOT end
*/
1001: ldw r1, [r7+], #0
add r1, r1, r0
stw.w r1, [r7]+, #4
csub.a r7, r8
bub 1001b
not_relocated:
/*
* Clear BSS region.
* r2 - BSS start
* r3 - BSS end
*/
mov r0, #0
1002: stw.w r0, [r2]+, #4
csub.a r2, r3
bub 1002b
/*
* Turn on the cache.
*/
mov r0, #0
movc p0.c5, r0, #28 @ cache invalidate all
nop8
movc p0.c6, r0, #6 @ tlb invalidate all
nop8
mov r0, #0x1c @ en icache and wb dcache
movc p0.c1, r0, #0
nop8
/*
* Set up some pointers, for starting decompressing.
*/
mov r1, sp @ malloc space above stack
add r2, sp, #0x10000 @ 64k max
/*
* Check to see if we will overwrite ourselves.
* r4 = final kernel address
* r5 = start of this image
* r6 = size of decompressed image
* r2 = end of malloc space (and therefore this image)
* We basically want:
* r4 >= r2 -> OK
* r4 + image length <= r5 -> OK
*/
ldw r4, =KERNEL_IMAGE_START
csub.a r4, r2
bea wont_overwrite
add r0, r4, r6
csub.a r0, r5
beb wont_overwrite
/*
* If overwrite, just print error message
*/
b __error_overwrite
/*
* We're not in danger of overwriting ourselves.
* Do this the simple way.
*/
wont_overwrite:
/*
* decompress_kernel:
* r0: output_start
* r1: free_mem_ptr_p
* r2: free_mem_ptr_end_p
*/
mov r0, r4
b.l decompress_kernel @ C functions
/*
* Clean and flush the cache to maintain consistency.
*/
mov r0, #0
movc p0.c5, r0, #14 @ flush dcache
nop8
movc p0.c5, r0, #20 @ icache invalidate all
nop8
/*
* Turn off the Cache and MMU.
*/
mov r0, #0 @ disable i/d cache and MMU
movc p0.c1, r0, #0
nop8
mov r0, #0 @ must be zero
ldw r4, =KERNEL_IMAGE_START
mov pc, r4 @ call kernel
.align 2
.type LC0, #object
LC0: .word LC0 @ r1
.word __bss_start @ r2
.word _end @ r3
.word _start @ r5
.word _image_size @ r6
.word _got_start @ r7
.word _got_end @ r8
.word decompress_stack_end @ sp
.size LC0, . - LC0
print_string:
#ifdef CONFIG_DEBUG_OCD
2001: ldb.w r1, [r0]+, #1
csub.a r1, #0
bne 2002f
mov pc, lr
2002:
movc r2, p1.c0, #0
cand.a r2, #2
bne 2002b
movc p1.c1, r1, #1
csub.a r1, #'\n'
cmoveq r1, #'\r'
beq 2002b
b 2001b
#else
mov pc, lr
#endif
__error_overwrite:
adr r0, str_error
b.l print_string
2001: nop8
b 2001b
str_error: .asciz "\nError: Kernel address OVERWRITE\n"
.align
.ltorg
.align 4
.section ".stack", "aw", %nobits
decompress_stack: .space 4096
decompress_stack_end:
|