1#include <asm/ppc_asm.h> 2#include <asm/processor.h> 3#include <asm/cache.h> 4 5 .text 6 7/* 8 * Boot loader philosophy: 9 * ROM loads us to some arbitrary location 10 * Move the boot code to the link address (8M) 11 * Call decompress_kernel() 12 * Relocate the initrd, zimage and residual data to 8M 13 * Decompress the kernel to 0 14 * Jump to the kernel entry 15 * -- Cort 16 */ 17 .globl start 18start: 19 bl start_ 20start_: 21 22 /* Enable, invalidate, Disable L1 icache/dcache */ 23 li r8, 0 24 ori r8, r8, (HID0_ICE|HID0_DCE|HID0_ICFI|HID0_DCI) 25 mfspr r11,HID0 26 or r11,r11,r8 27 andc r10,r11,r8 28 isync 29 mtspr HID0,r8 30 sync 31 isync 32 mtspr HID0,r10 33 sync 34 isync 35 36 mr r11,r3 /* Save pointer to residual/board data */ 37 38/* 39 * Save the OF pointer to r25, but only if the entry point is in a sane 40 * location; if not we store 0. If there is no entry point, or it is 41 * invalid, we establish the default MSR value immediately. Otherwise, 42 * we defer doing that, to allow OF functions to be called, until we 43 * begin uncompressing the kernel. 44 */ 45 lis r3,0x0fff /* r3 = 0x0fffffff */ 46 ori r3,r3,0xffff 47 48 subc r3,r3,r5 /* r3 = (r5 <= r3) ? ~0 : 0 */ 49 subfe r3,r3,r3 50 nand r3,r3,r3 51 52 and. r5,r5,r3 /* r5 will be cleared if (r5 > r3) */ 53 bne+ haveOF 54 55 li r3,MSR_IP|MSR_FP /* Not OF: set MSR immediately */ 56 mtmsr r3 57 isync 58haveOF: 59 mr r25,r5 60 61 /* compute the size of the whole image in words. */ 62 lis r4,start@h 63 ori r4,r4,start@l 64 lis r5,end@h 65 ori r5,r5,end@l 66 addi r5,r5,3 /* round up */ 67 sub r5,r5,r4 /* end - start */ 68 srwi r5,r5,2 69 mr r7,r5 /* Save for later use. */ 70 71 /* check if we need to relocate ourselves to the link addr or were 72 * we loaded there to begin with -- Cort */ 73 mflr r3 74 subi r3,r3,4 /* we get the nip, not the ip of the branch */ 75 mr r8,r3 76 cmp 0,r3,r4 77 beq start_ldr /* If 0, we don't need to relocate */ 78/* 79 * no matter where we're loaded, move ourselves to -Ttext address 80 */ 81relocate: 82 mflr r3 /* Compute code bias */ 83 subi r3,r3,4 84 mr r8,r3 85 lis r4,start@h 86 ori r4,r4,start@l 87 mr r5,r7 /* Get the # of longwords again */ 88 mtctr r5 /* Setup for loop */ 89 li r6,0 90 subi r3,r3,4 91 subi r4,r4,4 9200: lwzu r5,4(r3) 93 stwu r5,4(r4) 94 xor r6,r6,r5 95 bdnz 00b 96 lis r3,start_ldr@h 97 ori r3,r3,start_ldr@l 98 mtlr r3 /* Easiest way to do an absolute jump */ 99 blr 100 101start_ldr: 102/* Some boards don't boot up with the I-cache enabled. Do that 103 * now because the decompress runs much faster that way. 104 * As a side effect, we have to ensure the data cache is not enabled 105 * so we can access the serial I/O without trouble. 106 */ 107 bl flush_instruction_cache 108 109/* Clear all of BSS */ 110 lis r3,edata@h 111 ori r3,r3,edata@l 112 lis r4,end@h 113 ori r4,r4,end@l 114 subi r3,r3,4 115 subi r4,r4,4 116 li r0,0 11750: stwu r0,4(r3) 118 cmp 0,r3,r4 119 bne 50b 12090: mr r9,r1 /* Save old stack pointer (in case it matters) */ 121 lis r1,.stack@h 122 ori r1,r1,.stack@l 123 addi r1,r1,4096*2 124 subi r1,r1,256 125 li r2,0x000F /* Mask pointer to 16-byte boundary */ 126 andc r1,r1,r2 127 128/* Run loader */ 129 mr r3,r8 /* Load point */ 130 mr r4,r7 /* Program length */ 131 mr r5,r6 /* Checksum */ 132 mr r6,r11 /* Residual data */ 133 mr r7,r25 /* Validated OFW interface */ 134 bl decompress_kernel 135 136 /* 137 * We have to do this after decompress_kernel, just to make 138 * sure we don't wipe out things mapped in BATs which we need. 139 * -- Tom 140 */ 141 li r6,0 142 /* Test for a 601 */ 143 mfspr r9,PVR 144 srwi r9,r9,16 145 cmpi 0,r9,1 /* 601 ? */ 146 beq .clearbats_601 147 148 /* Clear BATS */ 149 mtspr DBAT0U,r6 150 mtspr DBAT0L,r6 151 mtspr DBAT1U,r6 152 mtspr DBAT1L,r6 153 mtspr DBAT2U,r6 154 mtspr DBAT2L,r6 155 mtspr DBAT3U,r6 156 mtspr DBAT3L,r6 157.clearbats_601: 158 mtspr IBAT0U,r6 159 mtspr IBAT0L,r6 160 mtspr IBAT1U,r6 161 mtspr IBAT1L,r6 162 mtspr IBAT2U,r6 163 mtspr IBAT2L,r6 164 mtspr IBAT3U,r6 165 mtspr IBAT3L,r6 166 isync 167 sync 168 sync 169 170 /* Set segment registers */ 171 li r6,16 /* load up segment register values */ 172 mtctr r6 /* for context 0 */ 173 lis r6,0x2000 /* Ku = 1, VSID = 0 */ 174 li r10,0 1753: mtsrin r6,r10 176 addi r6,r6,0x111 /* increment VSID */ 177 addis r10,r10,0x1000 /* address of next segment */ 178 bdnz 3b 179 180 /* tell kernel we're prep, by putting 0xdeadc0de at KERNELLOAD, 181 * and tell the kernel to start on the 4th instruction since we 182 * overwrite the first 3 sometimes (which are 'nop'). 183 */ 184 li r9,0xc 185 mtlr r9 186 lis r10,0xdeadc0de@h 187 ori r10,r10,0xdeadc0de@l 188 li r9,0 189 stw r10,0(r9) 190 blr 191 192 .comm .stack,4096*2,4 193