blob: dd8189931a2130d74f8199c6dcaf42127f7c00bd [file] [log] [blame]
wdenk9c53f402003-10-15 23:53:47 +00001/*
wdenka445ddf2004-06-09 00:34:46 +00002 * Copyright 2004 Freescale Semiconductor.
wdenk9c53f402003-10-15 23:53:47 +00003 * Copyright (C) 2003 Motorola,Inc.
4 * Xianghua Xiao<X.Xiao@motorola.com>
5 *
6 * See file CREDITS for list of people who contributed to this
7 * project.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 */
24
25/* U-Boot Startup Code for Motorola 85xx PowerPC based Embedded Boards
26 *
27 * The processor starts at 0xfffffffc and the code is first executed in the
28 * last 4K page(0xfffff000-0xffffffff) in flash/rom.
29 *
30 */
31
32#include <config.h>
33#include <mpc85xx.h>
34#include <version.h>
35
36#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
37
38#include <ppc_asm.tmpl>
39#include <ppc_defs.h>
40
41#include <asm/cache.h>
42#include <asm/mmu.h>
43
44#ifndef CONFIG_IDENT_STRING
45#define CONFIG_IDENT_STRING ""
46#endif
47
48#undef MSR_KERNEL
49#define MSR_KERNEL ( MSR_ME ) /* Machine Check */
50
51/*
52 * Set up GOT: Global Offset Table
53 *
54 * Use r14 to access the GOT
55 */
56 START_GOT
57 GOT_ENTRY(_GOT2_TABLE_)
58 GOT_ENTRY(_FIXUP_TABLE_)
59
60 GOT_ENTRY(_start)
61 GOT_ENTRY(_start_of_vectors)
62 GOT_ENTRY(_end_of_vectors)
63 GOT_ENTRY(transfer_to_handler)
64
65 GOT_ENTRY(__init_end)
66 GOT_ENTRY(_end)
67 GOT_ENTRY(__bss_start)
68 END_GOT
69
70/*
71 * e500 Startup -- after reset only the last 4KB of the effective
72 * address space is mapped in the MMU L2 TLB1 Entry0. The .bootpg
73 * section is located at THIS LAST page and basically does three
74 * things: clear some registers, set up exception tables and
75 * add more TLB entries for 'larger spaces'(e.g. the boot rom) to
76 * continue the boot procedure.
77
78 * Once the boot rom is mapped by TLB entries we can proceed
79 * with normal startup.
80 *
81 */
82
83 .section .bootpg,"ax"
84 .globl _start_e500
85
86_start_e500:
wdenka445ddf2004-06-09 00:34:46 +000087 mfspr r0, PVR
88 lis r1, PVR_85xx_REV1@h
89 ori r1, r1, PVR_85xx_REV1@l
90 cmpw r0, r1
91 bne 1f
92
93 /* Semi-bogus errata fixup for Rev 1 */
wdenk9c53f402003-10-15 23:53:47 +000094 li r0,0x2000
95 mtspr 977,r0
wdenk9c53f402003-10-15 23:53:47 +000096
wdenka445ddf2004-06-09 00:34:46 +000097 /*
98 * Before invalidating MMU L1/L2, read TLB1 Entry 0 and then
99 * write it back immediately to fixup a Rev 1 bug (Errata CPU4)
100 * for this initial TLB1 entry 0, otherwise the TLB1 entry 0
101 * will be invalidated (incorrectly).
102 */
103 lis r2,0x1000
104 mtspr MAS0,r2
105 tlbre
106 tlbwe
107 isync
108
1091:
110 /*
111 * Clear and set up some registers.
112 * Note: Some registers need strict synchronization by
113 * sync/mbar/msync/isync when being "mtspr".
wdenk9c53f402003-10-15 23:53:47 +0000114 * BookE: isync before PID,tlbivax,tlbwe
115 * BookE: isync after MSR,PID; msync_isync after tlbivax & tlbwe
116 * E500: msync,isync before L1CSR0
wdenka445ddf2004-06-09 00:34:46 +0000117 * E500: isync after BBEAR,BBTAR,BUCSR,DBCR0,DBCR1,HID0,HID1,
wdenkf3da7cc2005-05-13 22:49:36 +0000118 * L1CSR0, L1CSR1, MAS[0,1,2,3,4,6],MMUCSR0, PID[0,1,2],
119 * SPEFCSR
wdenk9c53f402003-10-15 23:53:47 +0000120 */
121
122 /* invalidate d-cache */
123 mfspr r0,L1CSR0
124 ori r0,r0,0x0002
125 msync
126 isync
127 mtspr L1CSR0,r0
128 isync
129
130 /* disable d-cache */
131 li r0,0x0
132 mtspr L1CSR0,r0
wdenk9c53f402003-10-15 23:53:47 +0000133
134 /* invalidate i-cache */
135 mfspr r0,L1CSR1
136 ori r0,r0,0x0002
137 mtspr L1CSR1,r0
138 isync
139
140 /* disable i-cache */
141 li r0,0x0
142 mtspr L1CSR1,r0
143 isync
144
145 /* clear registers */
wdenk9c53f402003-10-15 23:53:47 +0000146 li r0,0
147 mtspr SRR0,r0
148 mtspr SRR1,r0
149 mtspr CSRR0,r0
150 mtspr CSRR1,r0
151 mtspr MCSRR0,r0
152 mtspr MCSRR1,r0
153
154 mtspr ESR,r0
155 mtspr MCSR,r0
156 mtspr DEAR,r0
157
158 mtspr DBCR0,r0
wdenk9c53f402003-10-15 23:53:47 +0000159 mtspr DBCR1,r0
wdenk9c53f402003-10-15 23:53:47 +0000160 mtspr DBCR2,r0
wdenk9c53f402003-10-15 23:53:47 +0000161 mtspr IAC1,r0
162 mtspr IAC2,r0
163 mtspr DAC1,r0
164 mtspr DAC2,r0
165
166 mfspr r1,DBSR
167 mtspr DBSR,r1 /* Clear all valid bits */
168
wdenk9c53f402003-10-15 23:53:47 +0000169 mtspr PID0,r0
wdenk9c53f402003-10-15 23:53:47 +0000170 mtspr PID1,r0
wdenk9c53f402003-10-15 23:53:47 +0000171 mtspr PID2,r0
wdenk9c53f402003-10-15 23:53:47 +0000172 mtspr TCR,r0
173
174 mtspr BUCSR,r0 /* disable branch prediction */
wdenkf3da7cc2005-05-13 22:49:36 +0000175 mtspr MAS4,r0
176 mtspr MAS6,r0
Jon Loeliger77a4f6e2005-07-25 14:05:07 -0500177#if defined(CONFIG_ENABLE_36BIT_PHYS)
178 mtspr MAS7,r0
179#endif
wdenk9c53f402003-10-15 23:53:47 +0000180 isync
181
182 /* Setup interrupt vectors */
wdenkf3da7cc2005-05-13 22:49:36 +0000183 lis r1,TEXT_BASE@h
wdenka445ddf2004-06-09 00:34:46 +0000184 mtspr IVPR, r1
wdenk9c53f402003-10-15 23:53:47 +0000185
wdenkf3da7cc2005-05-13 22:49:36 +0000186 li r1,0x0100
wdenk9c53f402003-10-15 23:53:47 +0000187 mtspr IVOR0,r1 /* 0: Critical input */
wdenkf3da7cc2005-05-13 22:49:36 +0000188 li r1,0x0200
wdenk9c53f402003-10-15 23:53:47 +0000189 mtspr IVOR1,r1 /* 1: Machine check */
wdenkf3da7cc2005-05-13 22:49:36 +0000190 li r1,0x0300
wdenk9c53f402003-10-15 23:53:47 +0000191 mtspr IVOR2,r1 /* 2: Data storage */
wdenkf3da7cc2005-05-13 22:49:36 +0000192 li r1,0x0400
wdenk9c53f402003-10-15 23:53:47 +0000193 mtspr IVOR3,r1 /* 3: Instruction storage */
194 li r1,0x0500
195 mtspr IVOR4,r1 /* 4: External interrupt */
196 li r1,0x0600
197 mtspr IVOR5,r1 /* 5: Alignment */
198 li r1,0x0700
199 mtspr IVOR6,r1 /* 6: Program check */
200 li r1,0x0800
201 mtspr IVOR7,r1 /* 7: floating point unavailable */
wdenkf3da7cc2005-05-13 22:49:36 +0000202 li r1,0x0900
wdenk9c53f402003-10-15 23:53:47 +0000203 mtspr IVOR8,r1 /* 8: System call */
204 /* 9: Auxiliary processor unavailable(unsupported) */
wdenkf3da7cc2005-05-13 22:49:36 +0000205 li r1,0x0a00
wdenk9c53f402003-10-15 23:53:47 +0000206 mtspr IVOR10,r1 /* 10: Decrementer */
wdenkf3da7cc2005-05-13 22:49:36 +0000207 li r1,0x0b00
208 mtspr IVOR11,r1 /* 11: Interval timer */
209 li r1,0x0c00
210 mtspr IVOR12,r1 /* 11: Watchdog timer */
211 li r10,0x0d00
wdenk9c53f402003-10-15 23:53:47 +0000212 mtspr IVOR13,r1 /* 13: Data TLB error */
wdenkf3da7cc2005-05-13 22:49:36 +0000213 li r1,0x0e00
wdenk9c53f402003-10-15 23:53:47 +0000214 mtspr IVOR14,r1 /* 14: Instruction TLB error */
wdenkf3da7cc2005-05-13 22:49:36 +0000215 li r1,0x0f00
wdenk9c53f402003-10-15 23:53:47 +0000216 mtspr IVOR15,r1 /* 15: Debug */
217
wdenka445ddf2004-06-09 00:34:46 +0000218 /*
219 * Invalidate MMU L1/L2
220 *
221 * Note: There is a fixup earlier for Errata CPU4 on
222 * Rev 1 parts that must precede this MMU invalidation.
wdenk9c53f402003-10-15 23:53:47 +0000223 */
wdenkf3da7cc2005-05-13 22:49:36 +0000224 li r2, 0x001e
225 mtspr MMUCSR0, r2
wdenk9c53f402003-10-15 23:53:47 +0000226 isync
wdenk9c53f402003-10-15 23:53:47 +0000227
wdenk492b9e72004-08-01 23:02:45 +0000228 /*
229 * Invalidate all TLB0 entries.
230 */
wdenkf3da7cc2005-05-13 22:49:36 +0000231 li r3,4
wdenk492b9e72004-08-01 23:02:45 +0000232 li r4,0
wdenkf3da7cc2005-05-13 22:49:36 +0000233 tlbivax r4,r3
wdenk492b9e72004-08-01 23:02:45 +0000234 /*
235 * To avoid REV1 Errata CPU6 issues, make sure
236 * the instruction following tlbivax is not a store.
237 */
238
239 /*
240 * After reset, CCSRBAR is located at CFG_CCSRBAR_DEFAULT, i.e.
wdenk9c53f402003-10-15 23:53:47 +0000241 * 0xff700000-0xff800000. We need add a TLB1 entry for this 1MB
242 * region before we can access any CCSR registers such as L2
243 * registers, Local Access Registers,etc. We will also re-allocate
244 * CFG_CCSRBAR_DEFAULT to CFG_CCSRBAR immediately after TLB1 setup.
245 *
246 * Please refer to board-specif directory for TLB1 entry configuration.
247 * (e.g. board/<yourboard>/init.S)
248 *
249 */
wdenkf3da7cc2005-05-13 22:49:36 +0000250 bl tlb1_entry
wdenk9c53f402003-10-15 23:53:47 +0000251 mr r5,r0
wdenk492b9e72004-08-01 23:02:45 +0000252 li r1,0x0020 /* max 16 TLB1 plus some TLB0 entries */
wdenk9c53f402003-10-15 23:53:47 +0000253 mtctr r1
254 lwzu r4,0(r5) /* how many TLB1 entries we actually use */
255
2560: cmpwi r4,0
257 beq 1f
258 lwzu r0,4(r5)
259 lwzu r1,4(r5)
260 lwzu r2,4(r5)
261 lwzu r3,4(r5)
262 mtspr MAS0,r0
263 mtspr MAS1,r1
264 mtspr MAS2,r2
265 mtspr MAS3,r3
266 isync
267 msync
268 tlbwe
269 isync
270 addi r4,r4,-1
271 bdnz 0b
272
2731:
274#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
275 /* Special sequence needed to update CCSRBAR itself */
276 lis r4, CFG_CCSRBAR_DEFAULT@h
277 ori r4, r4, CFG_CCSRBAR_DEFAULT@l
278
wdenkf3da7cc2005-05-13 22:49:36 +0000279 lis r5, CFG_CCSRBAR@h
280 ori r5, r5, CFG_CCSRBAR@l
wdenk9c53f402003-10-15 23:53:47 +0000281 srwi r6,r5,12
282 stw r6, 0(r4)
283 isync
284
285 lis r5, 0xffff
286 ori r5,r5,0xf000
287 lwz r5, 0(r5)
288 isync
289
290 lis r3, CFG_CCSRBAR@h
291 lwz r5, CFG_CCSRBAR@l(r3)
292 isync
293#endif
294
wdenk9c53f402003-10-15 23:53:47 +0000295
296 /* set up local access windows, defined at board/<boardname>/init.S */
297 lis r7,CFG_CCSRBAR@h
298 ori r7,r7,CFG_CCSRBAR@l
299
wdenkf3da7cc2005-05-13 22:49:36 +0000300 bl law_entry
wdenk9c53f402003-10-15 23:53:47 +0000301 mr r6,r0
wdenk492b9e72004-08-01 23:02:45 +0000302 li r1,0x0007 /* 8 LAWs, but reserve one for boot-over-rio-or-pci */
wdenk9c53f402003-10-15 23:53:47 +0000303 mtctr r1
304 lwzu r5,0(r6) /* how many windows we actually use */
305
wdenk9c53f402003-10-15 23:53:47 +0000306 li r2,0x0c28 /* the first pair is reserved for boot-over-rio-or-pci */
307 li r1,0x0c30
wdenk9c53f402003-10-15 23:53:47 +0000308
3090: cmpwi r5,0
310 beq 1f
311 lwzu r4,4(r6)
312 lwzu r3,4(r6)
313 stwx r4,r7,r2
314 stwx r3,r7,r1
315 addi r5,r5,-1
316 addi r2,r2,0x0020
317 addi r1,r1,0x0020
318 bdnz 0b
319
320 /* Jump out the last 4K page and continue to 'normal' start */
3211: bl 3f
322 b _start
323
3243: li r0,0
325 mtspr SRR1,r0 /* Keep things disabled for now */
326 mflr r1
327 mtspr SRR0,r1
328 rfi
329
330/*
331 * r3 - 1st arg to board_init(): IMMP pointer
332 * r4 - 2nd arg to board_init(): boot flag
333 */
334 .text
335 .long 0x27051956 /* U-BOOT Magic Number */
336 .globl version_string
337version_string:
338 .ascii U_BOOT_VERSION
339 .ascii " (", __DATE__, " - ", __TIME__, ")"
340 .ascii CONFIG_IDENT_STRING, "\0"
341
342 . = EXC_OFF_SYS_RESET
343 .globl _start
344_start:
345 /* Clear and set up some registers. */
346 li r0,0x0000
347 lis r1,0xffff
348 mtspr DEC,r0 /* prevent dec exceptions */
349 mttbl r0 /* prevent fit & wdt exceptions */
350 mttbu r0
351 mtspr TSR,r1 /* clear all timer exception status */
352 mtspr TCR,r0 /* disable all */
353 mtspr ESR,r0 /* clear exception syndrome register */
354 mtspr MCSR,r0 /* machine check syndrome register */
355 mtxer r0 /* clear integer exception register */
356 lis r1,0x0002 /* set CE bit (Critical Exceptions) */
357 ori r1,r1,0x1200 /* set ME/DE bit */
358 mtmsr r1 /* change MSR */
359 isync
360
361 /* Enable Time Base and Select Time Base Clock */
wdenk13eb2212004-07-09 23:27:13 +0000362 lis r0,HID0_EMCP@h /* Enable machine check */
363 ori r0,r0,0x4000 /* time base is processor clock */
Jon Loeliger77a4f6e2005-07-25 14:05:07 -0500364#if defined(CONFIG_ENABLE_36BIT_PHYS)
365 ori r0,r0,0x0080 /* enable MAS7 updates */
366#endif
wdenk9c53f402003-10-15 23:53:47 +0000367 mtspr HID0,r0
wdenk9c53f402003-10-15 23:53:47 +0000368
369#if defined(CONFIG_ADDR_STREAMING)
wdenka983cc22003-10-26 22:52:58 +0000370 li r0,0x3000
371#else
372 li r0,0x1000
373#endif
wdenk9c53f402003-10-15 23:53:47 +0000374 mtspr HID1,r0
wdenk9c53f402003-10-15 23:53:47 +0000375
376 /* Enable Branch Prediction */
377#if defined(CONFIG_BTB)
378 li r0,0x201 /* BBFI = 1, BPEN = 1 */
379 mtspr BUCSR,r0
wdenk9c53f402003-10-15 23:53:47 +0000380#endif
381
382#if defined(CFG_INIT_DBCR)
383 lis r1,0xffff
384 ori r1,r1,0xffff
wdenk13eb2212004-07-09 23:27:13 +0000385 mtspr DBSR,r1 /* Clear all status bits */
wdenk9c53f402003-10-15 23:53:47 +0000386 lis r0,CFG_INIT_DBCR@h /* DBCR0[IDM] must be set */
387 ori r0,r0,CFG_INIT_DBCR@l
wdenk13eb2212004-07-09 23:27:13 +0000388 mtspr DBCR0,r0
wdenk9c53f402003-10-15 23:53:47 +0000389#endif
390
391/* L1 DCache is used for initial RAM */
392 mfspr r2, L1CSR0
wdenkf3da7cc2005-05-13 22:49:36 +0000393 ori r2, r2, 0x0003
394 oris r2, r2, 0x0001
395 mtspr L1CSR0, r2 /* enable/invalidate L1 Dcache */
wdenk9c53f402003-10-15 23:53:47 +0000396 isync
397
398 /* Allocate Initial RAM in data cache.
399 */
wdenkf3da7cc2005-05-13 22:49:36 +0000400 lis r3, CFG_INIT_RAM_ADDR@h
401 ori r3, r3, CFG_INIT_RAM_ADDR@l
402 li r2, 512 /* 512*32=16K */
403 mtctr r2
wdenk9c53f402003-10-15 23:53:47 +0000404 li r0, 0
4051:
406 dcbz r0, r3
wdenkf3da7cc2005-05-13 22:49:36 +0000407 dcbtls 0,r0, r3
408 addi r3, r3, 32
409 bdnz 1b
wdenk9c53f402003-10-15 23:53:47 +0000410
411#ifndef CFG_RAMBOOT
wdenkf3da7cc2005-05-13 22:49:36 +0000412 /* Calculate absolute address in FLASH and jump there */
wdenk9c53f402003-10-15 23:53:47 +0000413 /*--------------------------------------------------------------*/
wdenkf3da7cc2005-05-13 22:49:36 +0000414 lis r3, CFG_MONITOR_BASE@h
415 ori r3, r3, CFG_MONITOR_BASE@l
416 addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
417 mtlr r3
wdenk9c53f402003-10-15 23:53:47 +0000418 blr
419
420in_flash:
wdenkf3da7cc2005-05-13 22:49:36 +0000421#endif /* CFG_RAMBOOT */
wdenk9c53f402003-10-15 23:53:47 +0000422
423 /* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/
424 lis r1,CFG_INIT_RAM_ADDR@h
425 ori r1,r1,CFG_INIT_SP_OFFSET@l
426
427 li r0,0
428 stwu r0,-4(r1)
429 stwu r0,-4(r1) /* Terminate call chain */
430
431 stwu r1,-8(r1) /* Save back chain and move SP */
432 lis r0,RESET_VECTOR@h /* Address of reset vector */
433 ori r0,r0, RESET_VECTOR@l
434 stwu r1,-8(r1) /* Save back chain and move SP */
435 stw r0,+12(r1) /* Save return addr (underflow vect) */
436
437 GET_GOT
438 bl cpu_init_f
439 bl icache_enable
440 bl board_init_f
wdenk13eb2212004-07-09 23:27:13 +0000441 isync
wdenk9c53f402003-10-15 23:53:47 +0000442
443/* --FIXME-- machine check with MCSRRn and rfmci */
444
445 .globl _start_of_vectors
446_start_of_vectors:
447#if 0
448/* Critical input. */
449 CRIT_EXCEPTION(0x0100, CritcalInput, CritcalInputException)
450#endif
451/* Machine check --FIXME-- Should be MACH_EXCEPTION */
452 CRIT_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
453
454/* Data Storage exception. */
455 STD_EXCEPTION(0x0300, DataStorage, UnknownException)
456
457/* Instruction Storage exception. */
458 STD_EXCEPTION(0x0400, InstStorage, UnknownException)
459
460/* External Interrupt exception. */
461 STD_EXCEPTION(0x0500, ExtInterrupt, UnknownException)
462
463/* Alignment exception. */
464 . = 0x0600
465Alignment:
466 EXCEPTION_PROLOG
467 mfspr r4,DAR
468 stw r4,_DAR(r21)
469 mfspr r5,DSISR
470 stw r5,_DSISR(r21)
471 addi r3,r1,STACK_FRAME_OVERHEAD
472 li r20,MSR_KERNEL
473 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
474 lwz r6,GOT(transfer_to_handler)
475 mtlr r6
476 blrl
477.L_Alignment:
478 .long AlignmentException - _start + EXC_OFF_SYS_RESET
479 .long int_return - _start + EXC_OFF_SYS_RESET
480
481/* Program check exception */
482 . = 0x0700
483ProgramCheck:
484 EXCEPTION_PROLOG
485 addi r3,r1,STACK_FRAME_OVERHEAD
486 li r20,MSR_KERNEL
487 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
488 lwz r6,GOT(transfer_to_handler)
489 mtlr r6
490 blrl
491.L_ProgramCheck:
492 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
493 .long int_return - _start + EXC_OFF_SYS_RESET
494
495 /* No FPU on MPC85xx. This exception is not supposed to happen.
496 */
497 STD_EXCEPTION(0x0800, FPUnavailable, UnknownException)
wdenk9c53f402003-10-15 23:53:47 +0000498
wdenkf3da7cc2005-05-13 22:49:36 +0000499 . = 0x0900
wdenk9c53f402003-10-15 23:53:47 +0000500/*
501 * r0 - SYSCALL number
502 * r3-... arguments
503 */
504SystemCall:
wdenkf3da7cc2005-05-13 22:49:36 +0000505 addis r11,r0,0 /* get functions table addr */
506 ori r11,r11,0 /* Note: this code is patched in trap_init */
507 addis r12,r0,0 /* get number of functions */
508 ori r12,r12,0
wdenk9c53f402003-10-15 23:53:47 +0000509
wdenkf3da7cc2005-05-13 22:49:36 +0000510 cmplw 0, r0, r12
511 bge 1f
wdenk9c53f402003-10-15 23:53:47 +0000512
wdenkf3da7cc2005-05-13 22:49:36 +0000513 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */
514 add r11,r11,r0
515 lwz r11,0(r11)
wdenk9c53f402003-10-15 23:53:47 +0000516
wdenkf3da7cc2005-05-13 22:49:36 +0000517 li r20,0xd00-4 /* Get stack pointer */
518 lwz r12,0(r20)
519 subi r12,r12,12 /* Adjust stack pointer */
520 li r0,0xc00+_end_back-SystemCall
521 cmplw 0, r0, r12 /* Check stack overflow */
522 bgt 1f
523 stw r12,0(r20)
wdenk9c53f402003-10-15 23:53:47 +0000524
wdenkf3da7cc2005-05-13 22:49:36 +0000525 mflr r0
526 stw r0,0(r12)
527 mfspr r0,SRR0
528 stw r0,4(r12)
529 mfspr r0,SRR1
530 stw r0,8(r12)
wdenk9c53f402003-10-15 23:53:47 +0000531
wdenkf3da7cc2005-05-13 22:49:36 +0000532 li r12,0xc00+_back-SystemCall
533 mtlr r12
534 mtspr SRR0,r11
wdenk9c53f402003-10-15 23:53:47 +0000535
wdenkf3da7cc2005-05-13 22:49:36 +00005361: SYNC
wdenk9c53f402003-10-15 23:53:47 +0000537 rfi
538_back:
539
wdenkf3da7cc2005-05-13 22:49:36 +0000540 mfmsr r11 /* Disable interrupts */
541 li r12,0
542 ori r12,r12,MSR_EE
543 andc r11,r11,r12
544 SYNC /* Some chip revs need this... */
545 mtmsr r11
wdenk9c53f402003-10-15 23:53:47 +0000546 SYNC
547
wdenkf3da7cc2005-05-13 22:49:36 +0000548 li r12,0xd00-4 /* restore regs */
549 lwz r12,0(r12)
wdenk9c53f402003-10-15 23:53:47 +0000550
wdenkf3da7cc2005-05-13 22:49:36 +0000551 lwz r11,0(r12)
552 mtlr r11
553 lwz r11,4(r12)
554 mtspr SRR0,r11
555 lwz r11,8(r12)
556 mtspr SRR1,r11
wdenk9c53f402003-10-15 23:53:47 +0000557
wdenkf3da7cc2005-05-13 22:49:36 +0000558 addi r12,r12,12 /* Adjust stack pointer */
559 li r20,0xd00-4
560 stw r12,0(r20)
wdenk9c53f402003-10-15 23:53:47 +0000561
562 SYNC
563 rfi
564_end_back:
565
wdenkf3da7cc2005-05-13 22:49:36 +0000566 STD_EXCEPTION(0x0a00, Decrementer, timer_interrupt)
567 STD_EXCEPTION(0x0b00, IntervalTimer, UnknownException)
568 STD_EXCEPTION(0x0c00, WatchdogTimer, UnknownException)
wdenk9c53f402003-10-15 23:53:47 +0000569
wdenkf3da7cc2005-05-13 22:49:36 +0000570 STD_EXCEPTION(0x0d00, DataTLBError, UnknownException)
571 STD_EXCEPTION(0x0e00, InstructionTLBError, UnknownException)
wdenk9c53f402003-10-15 23:53:47 +0000572
wdenkf3da7cc2005-05-13 22:49:36 +0000573 CRIT_EXCEPTION(0x0f00, DebugBreakpoint, DebugException )
wdenk9c53f402003-10-15 23:53:47 +0000574
wdenkf3da7cc2005-05-13 22:49:36 +0000575 .globl _end_of_vectors
wdenk9c53f402003-10-15 23:53:47 +0000576_end_of_vectors:
577
578
579 . = 0x2100
580
581/*
582 * This code finishes saving the registers to the exception frame
583 * and jumps to the appropriate handler for the exception.
584 * Register r21 is pointer into trap frame, r1 has new stack pointer.
585 */
586 .globl transfer_to_handler
587transfer_to_handler:
588 stw r22,_NIP(r21)
589 lis r22,MSR_POW@h
590 andc r23,r23,r22
591 stw r23,_MSR(r21)
592 SAVE_GPR(7, r21)
593 SAVE_4GPRS(8, r21)
594 SAVE_8GPRS(12, r21)
595 SAVE_8GPRS(24, r21)
596
597 mflr r23
598 andi. r24,r23,0x3f00 /* get vector offset */
599 stw r24,TRAP(r21)
600 li r22,0
601 stw r22,RESULT(r21)
602 mtspr SPRG2,r22 /* r1 is now kernel sp */
603
604 lwz r24,0(r23) /* virtual address of handler */
605 lwz r23,4(r23) /* where to go when done */
606 mtspr SRR0,r24
607 mtspr SRR1,r20
608 mtlr r23
609 SYNC
610 rfi /* jump to handler, enable MMU */
611
612int_return:
613 mfmsr r28 /* Disable interrupts */
614 li r4,0
615 ori r4,r4,MSR_EE
616 andc r28,r28,r4
617 SYNC /* Some chip revs need this... */
618 mtmsr r28
619 SYNC
620 lwz r2,_CTR(r1)
621 lwz r0,_LINK(r1)
622 mtctr r2
623 mtlr r0
624 lwz r2,_XER(r1)
625 lwz r0,_CCR(r1)
626 mtspr XER,r2
627 mtcrf 0xFF,r0
628 REST_10GPRS(3, r1)
629 REST_10GPRS(13, r1)
630 REST_8GPRS(23, r1)
631 REST_GPR(31, r1)
632 lwz r2,_NIP(r1) /* Restore environment */
633 lwz r0,_MSR(r1)
634 mtspr SRR0,r2
635 mtspr SRR1,r0
636 lwz r0,GPR0(r1)
637 lwz r2,GPR2(r1)
638 lwz r1,GPR1(r1)
639 SYNC
640 rfi
641
642crit_return:
643 mfmsr r28 /* Disable interrupts */
644 li r4,0
645 ori r4,r4,MSR_EE
646 andc r28,r28,r4
647 SYNC /* Some chip revs need this... */
648 mtmsr r28
649 SYNC
650 lwz r2,_CTR(r1)
651 lwz r0,_LINK(r1)
652 mtctr r2
653 mtlr r0
654 lwz r2,_XER(r1)
655 lwz r0,_CCR(r1)
656 mtspr XER,r2
657 mtcrf 0xFF,r0
658 REST_10GPRS(3, r1)
659 REST_10GPRS(13, r1)
660 REST_8GPRS(23, r1)
661 REST_GPR(31, r1)
662 lwz r2,_NIP(r1) /* Restore environment */
663 lwz r0,_MSR(r1)
664 mtspr 990,r2 /* SRR2 */
665 mtspr 991,r0 /* SRR3 */
666 lwz r0,GPR0(r1)
667 lwz r2,GPR2(r1)
668 lwz r1,GPR1(r1)
669 SYNC
670 rfci
671
672/* Cache functions.
673*/
674invalidate_icache:
675 mfspr r0,L1CSR1
676 ori r0,r0,0x0002
677 mtspr L1CSR1,r0
678 isync
679 blr /* entire I cache */
680
681invalidate_dcache:
682 mfspr r0,L1CSR0
683 ori r0,r0,0x0002
684 msync
685 isync
686 mtspr L1CSR0,r0
687 isync
688 blr
689
690 .globl icache_enable
691icache_enable:
692 mflr r8
693 bl invalidate_icache
694 mtlr r8
695 isync
696 mfspr r4,L1CSR1
697 ori r4,r4,0x0001
698 oris r4,r4,0x0001
699 mtspr L1CSR1,r4
700 isync
701 blr
702
703 .globl icache_disable
704icache_disable:
705 mfspr r0,L1CSR1
706 lis r1,0xfffffffe@h
707 ori r1,r1,0xfffffffe@l
708 and r0,r0,r1
709 mtspr L1CSR1,r0
710 isync
711 blr
712
713 .globl icache_status
714icache_status:
715 mfspr r3,L1CSR1
716 srwi r3, r3, 31 /* >>31 => select bit 0 */
717 blr
718
719 .globl dcache_enable
720dcache_enable:
721 mflr r8
722 bl invalidate_dcache
723 mtlr r8
724 isync
725 mfspr r0,L1CSR0
726 ori r0,r0,0x0001
727 oris r0,r0,0x0001
728 msync
729 isync
730 mtspr L1CSR0,r0
731 isync
732 blr
733
734 .globl dcache_disable
735dcache_disable:
736 mfspr r0,L1CSR0
737 lis r1,0xfffffffe@h
738 ori r1,r1,0xfffffffe@l
739 and r0,r0,r1
740 msync
741 isync
742 mtspr L1CSR0,r0
743 isync
744 blr
745
746 .globl dcache_status
747dcache_status:
748 mfspr r3,L1CSR0
749 srwi r3, r3, 31 /* >>31 => select bit 0 */
750 blr
751
752 .globl get_pir
753get_pir:
754 mfspr r3, PIR
755 blr
756
757 .globl get_pvr
758get_pvr:
759 mfspr r3, PVR
760 blr
761
wdenka445ddf2004-06-09 00:34:46 +0000762 .globl get_svr
763get_svr:
764 mfspr r3, SVR
765 blr
766
wdenk9c53f402003-10-15 23:53:47 +0000767 .globl wr_tcr
768wr_tcr:
769 mtspr TCR, r3
770 blr
771
772/*------------------------------------------------------------------------------- */
773/* Function: in8 */
774/* Description: Input 8 bits */
775/*------------------------------------------------------------------------------- */
776 .globl in8
777in8:
778 lbz r3,0x0000(r3)
779 blr
780
781/*------------------------------------------------------------------------------- */
782/* Function: out8 */
783/* Description: Output 8 bits */
784/*------------------------------------------------------------------------------- */
785 .globl out8
786out8:
787 stb r4,0x0000(r3)
788 blr
789
790/*------------------------------------------------------------------------------- */
791/* Function: out16 */
792/* Description: Output 16 bits */
793/*------------------------------------------------------------------------------- */
794 .globl out16
795out16:
796 sth r4,0x0000(r3)
797 blr
798
799/*------------------------------------------------------------------------------- */
800/* Function: out16r */
801/* Description: Byte reverse and output 16 bits */
802/*------------------------------------------------------------------------------- */
803 .globl out16r
804out16r:
805 sthbrx r4,r0,r3
806 blr
807
808/*------------------------------------------------------------------------------- */
809/* Function: out32 */
810/* Description: Output 32 bits */
811/*------------------------------------------------------------------------------- */
812 .globl out32
813out32:
814 stw r4,0x0000(r3)
815 blr
816
817/*------------------------------------------------------------------------------- */
818/* Function: out32r */
819/* Description: Byte reverse and output 32 bits */
820/*------------------------------------------------------------------------------- */
821 .globl out32r
822out32r:
823 stwbrx r4,r0,r3
824 blr
825
826/*------------------------------------------------------------------------------- */
827/* Function: in16 */
828/* Description: Input 16 bits */
829/*------------------------------------------------------------------------------- */
830 .globl in16
831in16:
832 lhz r3,0x0000(r3)
833 blr
834
835/*------------------------------------------------------------------------------- */
836/* Function: in16r */
837/* Description: Input 16 bits and byte reverse */
838/*------------------------------------------------------------------------------- */
839 .globl in16r
840in16r:
841 lhbrx r3,r0,r3
842 blr
843
844/*------------------------------------------------------------------------------- */
845/* Function: in32 */
846/* Description: Input 32 bits */
847/*------------------------------------------------------------------------------- */
848 .globl in32
849in32:
850 lwz 3,0x0000(3)
851 blr
852
853/*------------------------------------------------------------------------------- */
854/* Function: in32r */
855/* Description: Input 32 bits and byte reverse */
856/*------------------------------------------------------------------------------- */
857 .globl in32r
858in32r:
859 lwbrx r3,r0,r3
860 blr
861
862/*------------------------------------------------------------------------------- */
863/* Function: ppcDcbf */
864/* Description: Data Cache block flush */
865/* Input: r3 = effective address */
866/* Output: none. */
867/*------------------------------------------------------------------------------- */
868 .globl ppcDcbf
869ppcDcbf:
870 dcbf r0,r3
871 blr
872
873/*------------------------------------------------------------------------------- */
874/* Function: ppcDcbi */
875/* Description: Data Cache block Invalidate */
876/* Input: r3 = effective address */
877/* Output: none. */
878/*------------------------------------------------------------------------------- */
879 .globl ppcDcbi
880ppcDcbi:
881 dcbi r0,r3
882 blr
883
wdenk13eb2212004-07-09 23:27:13 +0000884/*--------------------------------------------------------------------------
885 * Function: ppcDcbz
886 * Description: Data Cache block zero.
887 * Input: r3 = effective address
888 * Output: none.
889 *-------------------------------------------------------------------------- */
890
891 .globl ppcDcbz
892ppcDcbz:
893 dcbz r0,r3
894 blr
895
wdenk9c53f402003-10-15 23:53:47 +0000896/*------------------------------------------------------------------------------- */
897/* Function: ppcSync */
898/* Description: Processor Synchronize */
899/* Input: none. */
900/* Output: none. */
901/*------------------------------------------------------------------------------- */
902 .globl ppcSync
903ppcSync:
904 sync
905 blr
906
907/*------------------------------------------------------------------------------*/
908
909/*
910 * void relocate_code (addr_sp, gd, addr_moni)
911 *
912 * This "function" does not return, instead it continues in RAM
913 * after relocating the monitor code.
914 *
915 * r3 = dest
916 * r4 = src
917 * r5 = length in bytes
918 * r6 = cachelinesize
919 */
920 .globl relocate_code
921relocate_code:
922 mr r1, r3 /* Set new stack pointer */
923 mr r9, r4 /* Save copy of Init Data pointer */
924 mr r10, r5 /* Save copy of Destination Address */
925
926 mr r3, r5 /* Destination Address */
927 lis r4, CFG_MONITOR_BASE@h /* Source Address */
928 ori r4, r4, CFG_MONITOR_BASE@l
929 lwz r5,GOT(__init_end)
930 sub r5,r5,r4
931 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
932
933 /*
934 * Fix GOT pointer:
935 *
936 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
937 *
938 * Offset:
939 */
940 sub r15, r10, r4
941
942 /* First our own GOT */
943 add r14, r14, r15
944 /* the the one used by the C code */
945 add r30, r30, r15
946
947 /*
948 * Now relocate code
949 */
950
951 cmplw cr1,r3,r4
952 addi r0,r5,3
953 srwi. r0,r0,2
954 beq cr1,4f /* In place copy is not necessary */
955 beq 7f /* Protect against 0 count */
956 mtctr r0
957 bge cr1,2f
958
959 la r8,-4(r4)
960 la r7,-4(r3)
9611: lwzu r0,4(r8)
962 stwu r0,4(r7)
963 bdnz 1b
964 b 4f
965
9662: slwi r0,r0,2
967 add r8,r4,r0
968 add r7,r3,r0
9693: lwzu r0,-4(r8)
970 stwu r0,-4(r7)
971 bdnz 3b
972
973/*
974 * Now flush the cache: note that we must start from a cache aligned
975 * address. Otherwise we might miss one cache line.
976 */
9774: cmpwi r6,0
978 add r5,r3,r5
979 beq 7f /* Always flush prefetch queue in any case */
980 subi r0,r6,1
981 andc r3,r3,r0
982 mr r4,r3
9835: dcbst 0,r4
984 add r4,r4,r6
985 cmplw r4,r5
986 blt 5b
987 sync /* Wait for all dcbst to complete on bus */
988 mr r4,r3
9896: icbi 0,r4
990 add r4,r4,r6
991 cmplw r4,r5
992 blt 6b
9937: sync /* Wait for all icbi to complete on bus */
994 isync
995
996/*
997 * We are done. Do not return, instead branch to second part of board
998 * initialization, now running from RAM.
999 */
1000
1001 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
1002 mtlr r0
1003 blr /* NEVER RETURNS! */
1004
1005in_ram:
1006
1007 /*
1008 * Relocation Function, r14 point to got2+0x8000
1009 *
1010 * Adjust got2 pointers, no need to check for 0, this code
1011 * already puts a few entries in the table.
1012 */
1013 li r0,__got2_entries@sectoff@l
1014 la r3,GOT(_GOT2_TABLE_)
1015 lwz r11,GOT(_GOT2_TABLE_)
1016 mtctr r0
1017 sub r11,r3,r11
1018 addi r3,r3,-4
10191: lwzu r0,4(r3)
1020 add r0,r0,r11
1021 stw r0,0(r3)
1022 bdnz 1b
1023
1024 /*
1025 * Now adjust the fixups and the pointers to the fixups
1026 * in case we need to move ourselves again.
1027 */
10282: li r0,__fixup_entries@sectoff@l
1029 lwz r3,GOT(_FIXUP_TABLE_)
1030 cmpwi r0,0
1031 mtctr r0
1032 addi r3,r3,-4
1033 beq 4f
10343: lwzu r4,4(r3)
1035 lwzux r0,r4,r11
1036 add r0,r0,r11
1037 stw r10,0(r3)
1038 stw r0,0(r4)
1039 bdnz 3b
10404:
1041clear_bss:
1042 /*
1043 * Now clear BSS segment
1044 */
1045 lwz r3,GOT(__bss_start)
1046 lwz r4,GOT(_end)
1047
1048 cmplw 0, r3, r4
1049 beq 6f
1050
1051 li r0, 0
10525:
1053 stw r0, 0(r3)
1054 addi r3, r3, 4
1055 cmplw 0, r3, r4
1056 bne 5b
10576:
1058
1059 mr r3, r9 /* Init Data pointer */
1060 mr r4, r10 /* Destination Address */
1061 bl board_init_r
1062
1063 /*
1064 * Copy exception vector code to low memory
1065 *
1066 * r3: dest_addr
1067 * r7: source address, r8: end address, r9: target address
1068 */
wdenkf3da7cc2005-05-13 22:49:36 +00001069 .globl trap_init
wdenk9c53f402003-10-15 23:53:47 +00001070trap_init:
wdenkf3da7cc2005-05-13 22:49:36 +00001071 lwz r7, GOT(_start)
1072 lwz r8, GOT(_end_of_vectors)
wdenk9c53f402003-10-15 23:53:47 +00001073
1074 li r9, 0x100 /* reset vector always at 0x100 */
1075
wdenkf3da7cc2005-05-13 22:49:36 +00001076 cmplw 0, r7, r8
1077 bgelr /* return if r7>=r8 - just in case */
wdenk9c53f402003-10-15 23:53:47 +00001078
wdenkf3da7cc2005-05-13 22:49:36 +00001079 mflr r4 /* save link register */
wdenk9c53f402003-10-15 23:53:47 +000010801:
wdenkf3da7cc2005-05-13 22:49:36 +00001081 lwz r0, 0(r7)
1082 stw r0, 0(r9)
1083 addi r7, r7, 4
1084 addi r9, r9, 4
1085 cmplw 0, r7, r8
1086 bne 1b
wdenk9c53f402003-10-15 23:53:47 +00001087
1088 /*
1089 * relocate `hdlr' and `int_return' entries
1090 */
wdenkf3da7cc2005-05-13 22:49:36 +00001091 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
1092 bl trap_reloc
1093 li r7, .L_DataStorage - _start + EXC_OFF_SYS_RESET
1094 bl trap_reloc
1095 li r7, .L_InstStorage - _start + EXC_OFF_SYS_RESET
1096 bl trap_reloc
1097 li r7, .L_ExtInterrupt - _start + EXC_OFF_SYS_RESET
1098 bl trap_reloc
1099 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1100 bl trap_reloc
1101 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1102 bl trap_reloc
1103 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1104 bl trap_reloc
1105 li r7, .L_Decrementer - _start + EXC_OFF_SYS_RESET
1106 bl trap_reloc
1107 li r7, .L_IntervalTimer - _start + EXC_OFF_SYS_RESET
1108 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
wdenk9c53f402003-10-15 23:53:47 +000011092:
wdenkf3da7cc2005-05-13 22:49:36 +00001110 bl trap_reloc
1111 addi r7, r7, 0x100 /* next exception vector */
1112 cmplw 0, r7, r8
1113 blt 2b
wdenk9c53f402003-10-15 23:53:47 +00001114
wdenkf3da7cc2005-05-13 22:49:36 +00001115 lis r7,0x0
1116 mtspr IVPR, r7
wdenk9c53f402003-10-15 23:53:47 +00001117
wdenkf3da7cc2005-05-13 22:49:36 +00001118 mtlr r4 /* restore link register */
wdenk9c53f402003-10-15 23:53:47 +00001119 blr
1120
1121 /*
1122 * Function: relocate entries for one exception vector
1123 */
1124trap_reloc:
wdenkf3da7cc2005-05-13 22:49:36 +00001125 lwz r0, 0(r7) /* hdlr ... */
1126 add r0, r0, r3 /* ... += dest_addr */
1127 stw r0, 0(r7)
wdenk9c53f402003-10-15 23:53:47 +00001128
wdenkf3da7cc2005-05-13 22:49:36 +00001129 lwz r0, 4(r7) /* int_return ... */
1130 add r0, r0, r3 /* ... += dest_addr */
1131 stw r0, 4(r7)
wdenk9c53f402003-10-15 23:53:47 +00001132
1133 blr
1134
1135#ifdef CFG_INIT_RAM_LOCK
1136.globl unlock_ram_in_cache
1137unlock_ram_in_cache:
1138 /* invalidate the INIT_RAM section */
1139 lis r3, (CFG_INIT_RAM_ADDR & ~31)@h
1140 ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
1141 li r2,512
1142 mtctr r2
11431: icbi r0, r3
1144 dcbi r0, r3
1145 addi r3, r3, 32
1146 bdnz 1b
wdenkf3da7cc2005-05-13 22:49:36 +00001147 sync /* Wait for all icbi to complete on bus */
wdenk9c53f402003-10-15 23:53:47 +00001148 isync
1149 blr
1150#endif