]> git.ipfire.org Git - u-boot.git/blame - cpu/mpc824x/start.S
* Code cleanup:
[u-boot.git] / cpu / mpc824x / start.S
CommitLineData
c609719b
WD
1/*
2 * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
3 * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
4 * Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de>
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 PowerPC based Embedded Boards
26 *
27 *
28 * The processor starts at 0x00000100 and the code is executed
29 * from flash. The code is organized to be at an other address
30 * in memory, but as long we don't jump around before relocating.
31 * board_init lies at a quite high address and when the cpu has
32 * jumped there, everything is ok.
33 * This works because the cpu gives the FLASH (CS0) the whole
34 * address space at startup, and board_init lies as a echo of
35 * the flash somewhere up there in the memorymap.
36 *
37 * board_init will change CS0 to be positioned at the correct
38 * address and (s)dram will be positioned at address 0
39 */
40#include <config.h>
41#include <mpc824x.h>
42#include <version.h>
43
44#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
45
46#include <ppc_asm.tmpl>
47#include <ppc_defs.h>
48
49#include <asm/cache.h>
50#include <asm/mmu.h>
51
52#ifndef CONFIG_IDENT_STRING
53#define CONFIG_IDENT_STRING ""
54#endif
55
56/* We don't want the MMU yet.
57*/
58#undef MSR_KERNEL
59/* FP, Machine Check and Recoverable Interr. */
60#define MSR_KERNEL ( MSR_FP | MSR_ME | MSR_RI )
61
62/*
63 * Set up GOT: Global Offset Table
64 *
65 * Use r14 to access the GOT
66 */
67 START_GOT
68 GOT_ENTRY(_GOT2_TABLE_)
69 GOT_ENTRY(_FIXUP_TABLE_)
70
71 GOT_ENTRY(_start)
72 GOT_ENTRY(_start_of_vectors)
73 GOT_ENTRY(_end_of_vectors)
74 GOT_ENTRY(transfer_to_handler)
75
3b57fe0a 76 GOT_ENTRY(__init_end)
c609719b 77 GOT_ENTRY(_end)
5d232d0e 78 GOT_ENTRY(__bss_start)
c609719b
WD
79#if defined(CONFIG_FADS)
80 GOT_ENTRY(environment)
81#endif
82 END_GOT
83
84/*
85 * r3 - 1st arg to board_init(): IMMP pointer
86 * r4 - 2nd arg to board_init(): boot flag
87 */
88 .text
89 .long 0x27051956 /* U-Boot Magic Number */
90 .globl version_string
91version_string:
92 .ascii U_BOOT_VERSION
93 .ascii " (", __DATE__, " - ", __TIME__, ")"
94 .ascii CONFIG_IDENT_STRING, "\0"
95
96 . = EXC_OFF_SYS_RESET
97 .globl _start
98_start:
99 li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH */
100 b boot_cold
101
102 . = EXC_OFF_SYS_RESET + 0x10
103
104 .globl _start_warm
105_start_warm:
106 li r21, BOOTFLAG_WARM /* Software reboot */
107 b boot_warm
108
109boot_cold:
110boot_warm:
111
112 /* Initialize machine status; enable machine check interrupt */
113 /*----------------------------------------------------------------------*/
114 li r3, MSR_KERNEL /* Set FP, ME, RI flags */
115 mtmsr r3
116 mtspr SRR1, r3 /* Make SRR1 match MSR */
117
118 addis r0,0,0x0000 /* lets make sure that r0 is really 0 */
119 mtspr HID0, r0 /* disable I and D caches */
120
121 mfspr r3, ICR /* clear Interrupt Cause Register */
122
123 mfmsr r3 /* turn off address translation */
124 addis r4,0,0xffff
125 ori r4,r4,0xffcf
126 and r3,r3,r4
127 mtmsr r3
128 isync
129 sync /* the MMU should be off... */
130
131
132in_flash:
133#if defined(CONFIG_BMW)
134 bl early_init_f /* Must be ASM: no stack yet! */
135#endif
136 /*
137 * Setup BATs - cannot be done in C since we don't have a stack yet
138 */
139 bl setup_bats
140
141 /* Enable MMU.
142 */
143 mfmsr r3
144 ori r3, r3, (MSR_IR | MSR_DR)
145 mtmsr r3
146#if !defined(CONFIG_BMW)
147 /* Enable and invalidate data cache.
148 */
149 mfspr r3, HID0
150 mr r2, r3
151 ori r3, r3, HID0_DCE | HID0_DCI
152 ori r2, r2, HID0_DCE
153 sync
154 mtspr HID0, r3
155 mtspr HID0, r2
156 sync
157
158 /* Allocate Initial RAM in data cache.
159 */
160 lis r3, CFG_INIT_RAM_ADDR@h
161 ori r3, r3, CFG_INIT_RAM_ADDR@l
162 li r2, 128
163 mtctr r2
1641:
165 dcbz r0, r3
166 addi r3, r3, 32
167 bdnz 1b
168
169 /* Lock way0 in data cache.
170 */
171 mfspr r3, 1011
172 lis r2, 0xffff
173 ori r2, r2, 0xff1f
174 and r3, r3, r2
175 ori r3, r3, 0x0080
176 sync
177 mtspr 1011, r3
178#endif /* !CONFIG_BMW */
179 /*
180 * Thisk the stack pointer *somewhere* sensible. Doesnt
181 * matter much where as we'll move it when we relocate
182 */
183 lis r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h
184 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l
185
186 li r0, 0 /* Make room for stack frame header and */
187 stwu r0, -4(r1) /* clear final stack frame so that */
188 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
189
190 /* let the C-code set up the rest */
191 /* */
192 /* Be careful to keep code relocatable ! */
193 /*----------------------------------------------------------------------*/
194
195 GET_GOT /* initialize GOT access */
196
197 /* r3: IMMR */
198 bl cpu_init_f /* run low-level CPU init code (from Flash) */
199
200 mr r3, r21
201 /* r3: BOOTFLAG */
202 bl board_init_f /* run 1st part of board init code (from Flash) */
203
204
c609719b
WD
205 .globl _start_of_vectors
206_start_of_vectors:
207
208/* Machine check */
209 STD_EXCEPTION(EXC_OFF_MACH_CHCK, MachineCheck, MachineCheckException)
210
211/* Data Storage exception. "Never" generated on the 860. */
212 STD_EXCEPTION(EXC_OFF_DATA_STOR, DataStorage, UnknownException)
213
214/* Instruction Storage exception. "Never" generated on the 860. */
215 STD_EXCEPTION(EXC_OFF_INS_STOR, InstStorage, UnknownException)
216
217/* External Interrupt exception. */
218 STD_EXCEPTION(EXC_OFF_EXTERNAL, ExtInterrupt, external_interrupt)
219
220/* Alignment exception. */
221 . = EXC_OFF_ALIGN
222Alignment:
223 EXCEPTION_PROLOG
224 mfspr r4,DAR
225 stw r4,_DAR(r21)
226 mfspr r5,DSISR
227 stw r5,_DSISR(r21)
228 addi r3,r1,STACK_FRAME_OVERHEAD
229 li r20,MSR_KERNEL
230 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
231 lwz r6,GOT(transfer_to_handler)
232 mtlr r6
233 blrl
234.L_Alignment:
235 .long AlignmentException - _start + EXC_OFF_SYS_RESET
236 .long int_return - _start + EXC_OFF_SYS_RESET
237
238/* Program check exception */
239 . = EXC_OFF_PROGRAM
240ProgramCheck:
241 EXCEPTION_PROLOG
242 addi r3,r1,STACK_FRAME_OVERHEAD
243 li r20,MSR_KERNEL
244 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
245 lwz r6,GOT(transfer_to_handler)
246 mtlr r6
247 blrl
248.L_ProgramCheck:
249 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
250 .long int_return - _start + EXC_OFF_SYS_RESET
251
252 /* No FPU on MPC8xx. This exception is not supposed to happen.
253 */
254 STD_EXCEPTION(EXC_OFF_FPUNAVAIL, FPUnavailable, UnknownException)
255
256 /* I guess we could implement decrementer, and may have
257 * to someday for timekeeping.
258 */
259 STD_EXCEPTION(EXC_OFF_DECR, Decrementer, timer_interrupt)
260 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
261 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
262
263 . = 0xc00
264/*
265 * r0 - SYSCALL number
266 * r3-... arguments
267 */
268SystemCall:
269 addis r11,r0,0 /* get functions table addr */
270 ori r11,r11,0 /* Note: this code is patched in trap_init */
271 addis r12,r0,0 /* get number of functions */
272 ori r12,r12,0
273
274 cmplw 0, r0, r12
275 bge 1f
276
277 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */
278 add r11,r11,r0
279 lwz r11,0(r11)
280
7c7a23bd
WD
281 li r20,0xd00-4 /* Get stack pointer */
282 lwz r12,0(r20)
283 subi r12,r12,12 /* Adjust stack pointer */
284 li r0,0xc00+_end_back-SystemCall
285 cmplw 0, r0, r12 /* Check stack overflow */
286 bgt 1f
287 stw r12,0(r20)
288
c609719b
WD
289 mflr r0
290 stw r0,0(r12)
291 mfspr r0,SRR0
292 stw r0,4(r12)
293 mfspr r0,SRR1
294 stw r0,8(r12)
295
296 li r12,0xc00+_back-SystemCall
297 mtlr r12
298 mtspr SRR0,r11
299
3001: SYNC
301 rfi
302
303_back:
304
305 mfmsr r11 /* Disable interrupts */
306 li r12,0
307 ori r12,r12,MSR_EE
308 andc r11,r11,r12
309 SYNC /* Some chip revs need this... */
310 mtmsr r11
311 SYNC
312
7c7a23bd
WD
313 li r12,0xd00-4 /* restore regs */
314 lwz r12,0(r12)
315
c609719b
WD
316 lwz r11,0(r12)
317 mtlr r11
318 lwz r11,4(r12)
319 mtspr SRR0,r11
320 lwz r11,8(r12)
321 mtspr SRR1,r11
322
7c7a23bd
WD
323 addi r12,r12,12 /* Adjust stack pointer */
324 li r20,0xd00-4
325 stw r12,0(r20)
326
c609719b
WD
327 SYNC
328 rfi
7c7a23bd 329_end_back:
c609719b
WD
330
331 STD_EXCEPTION(EXC_OFF_TRACE, SingleStep, UnknownException)
332
333 STD_EXCEPTION(EXC_OFF_FPUNASSIST, Trap_0e, UnknownException)
334 STD_EXCEPTION(EXC_OFF_PMI, Trap_0f, UnknownException)
335
336 STD_EXCEPTION(EXC_OFF_ITME, InstructionTransMiss, UnknownException)
337 STD_EXCEPTION(EXC_OFF_DLTME, DataLoadTransMiss, UnknownException)
338 STD_EXCEPTION(EXC_OFF_DSTME, DataStoreTransMiss, UnknownException)
43d9616c 339 STD_EXCEPTION(EXC_OFF_IABE, InstructionBreakpoint, DebugException)
c609719b
WD
340 STD_EXCEPTION(EXC_OFF_SMIE, SysManageInt, UnknownException)
341 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
342 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
343 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
344 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
345 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
346 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
347 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
348 STD_EXCEPTION(0x1c00, ReservedC, UnknownException)
349 STD_EXCEPTION(0x1d00, ReservedD, UnknownException)
350 STD_EXCEPTION(0x1e00, ReservedE, UnknownException)
351 STD_EXCEPTION(0x1f00, ReservedF, UnknownException)
352
353 STD_EXCEPTION(EXC_OFF_RMTE, RunModeTrace, UnknownException)
354
355 .globl _end_of_vectors
356_end_of_vectors:
357
358
359 . = 0x3000
360
361/*
362 * This code finishes saving the registers to the exception frame
363 * and jumps to the appropriate handler for the exception.
364 * Register r21 is pointer into trap frame, r1 has new stack pointer.
365 */
366 .globl transfer_to_handler
367transfer_to_handler:
368 stw r22,_NIP(r21)
369 lis r22,MSR_POW@h
370 andc r23,r23,r22
371 stw r23,_MSR(r21)
372 SAVE_GPR(7, r21)
373 SAVE_4GPRS(8, r21)
374 SAVE_8GPRS(12, r21)
375 SAVE_8GPRS(24, r21)
376#if 0
377 andi. r23,r23,MSR_PR
378 mfspr r23,SPRG3 /* if from user, fix up tss.regs */
379 beq 2f
380 addi r24,r1,STACK_FRAME_OVERHEAD
381 stw r24,PT_REGS(r23)
3822: addi r2,r23,-TSS /* set r2 to current */
383 tovirt(r2,r2,r23)
384#endif
385 mflr r23
386 andi. r24,r23,0x3f00 /* get vector offset */
387 stw r24,TRAP(r21)
388 li r22,0
389 stw r22,RESULT(r21)
390 mtspr SPRG2,r22 /* r1 is now kernel sp */
391#if 0
392 addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
393 cmplw 0,r1,r2
394 cmplw 1,r1,r24
395 crand 1,1,4
396 bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
397#endif
398 lwz r24,0(r23) /* virtual address of handler */
399 lwz r23,4(r23) /* where to go when done */
400 mtspr SRR0,r24
401 ori r20,r20,0x30 /* enable IR, DR */
402 mtspr SRR1,r20
403 mtlr r23
404 SYNC
405 rfi /* jump to handler, enable MMU */
406
407int_return:
408 mfmsr r28 /* Disable interrupts */
409 li r4,0
410 ori r4,r4,MSR_EE
411 andc r28,r28,r4
412 SYNC /* Some chip revs need this... */
413 mtmsr r28
414 SYNC
415 lwz r2,_CTR(r1)
416 lwz r0,_LINK(r1)
417 mtctr r2
418 mtlr r0
419 lwz r2,_XER(r1)
420 lwz r0,_CCR(r1)
421 mtspr XER,r2
422 mtcrf 0xFF,r0
423 REST_10GPRS(3, r1)
424 REST_10GPRS(13, r1)
425 REST_8GPRS(23, r1)
426 REST_GPR(31, r1)
427 lwz r2,_NIP(r1) /* Restore environment */
428 lwz r0,_MSR(r1)
429 mtspr SRR0,r2
430 mtspr SRR1,r0
431 lwz r0,GPR0(r1)
432 lwz r2,GPR2(r1)
433 lwz r1,GPR1(r1)
434 SYNC
435 rfi
436
437/* Cache functions.
438*/
439 .globl icache_enable
440icache_enable:
441 mfspr r5,HID0 /* turn on the I cache. */
442 ori r5,r5,0x8800 /* Instruction cache only! */
443 addis r6,0,0xFFFF
444 ori r6,r6,0xF7FF
445 and r6,r5,r6 /* clear the invalidate bit */
446 sync
447 mtspr HID0,r5
448 mtspr HID0,r6
449 isync
450 sync
451 blr
452
453 .globl icache_disable
454icache_disable:
455 mfspr r5,HID0
456 addis r6,0,0xFFFF
457 ori r6,r6,0x7FFF
458 and r5,r5,r6
459 sync
460 mtspr HID0,r5
461 isync
462 sync
463 blr
464
465 .globl icache_status
466icache_status:
467 mfspr r3, HID0
468 srwi r3, r3, 15 /* >>15 & 1=> select bit 16 */
469 andi. r3, r3, 1
470 blr
471
472 .globl dcache_enable
473dcache_enable:
474 mfspr r5,HID0 /* turn on the D cache. */
475 ori r5,r5,0x4400 /* Data cache only! */
476 mfspr r4, PVR /* read PVR */
477 srawi r3, r4, 16 /* shift off the least 16 bits */
478 cmpi 0, 0, r3, 0xC /* Check for Max pvr */
479 bne NotMax
480 ori r5,r5,0x0040 /* setting the DCFA bit, for Max rev 1 errata */
481NotMax:
482 addis r6,0,0xFFFF
483 ori r6,r6,0xFBFF
484 and r6,r5,r6 /* clear the invalidate bit */
485 sync
486 mtspr HID0,r5
487 mtspr HID0,r6
488 isync
489 sync
490 blr
491
492 .globl dcache_disable
493dcache_disable:
494 mfspr r5,HID0
495 addis r6,0,0xFFFF
496 ori r6,r6,0xBFFF
497 and r5,r5,r6
498 sync
499 mtspr HID0,r5
500 isync
501 sync
502 blr
503
504 .globl dcache_status
505dcache_status:
506 mfspr r3, HID0
507 srwi r3, r3, 14 /* >>14 & 1=> select bit 17 */
508 andi. r3, r3, 1
509 blr
510
511 .globl dc_read
512dc_read:
513/*TODO : who uses this, what should it do?
514*/
515 blr
516
517
518 .globl get_pvr
519get_pvr:
520 mfspr r3, PVR
521 blr
522
523
524/*------------------------------------------------------------------------------*/
525
526/*
527 * void relocate_code (addr_sp, gd, addr_moni)
528 *
529 * This "function" does not return, instead it continues in RAM
530 * after relocating the monitor code.
531 *
532 * r3 = dest
533 * r4 = src
534 * r5 = length in bytes
535 * r6 = cachelinesize
536 */
537 .globl relocate_code
538relocate_code:
539
540 mr r1, r3 /* Set new stack pointer */
541 mr r9, r4 /* Save copy of Global Data pointer */
542 mr r10, r5 /* Save copy of Destination Address */
543
544 mr r3, r5 /* Destination Address */
7a8e9bed 545#ifdef CFG_RAMBOOT
c609719b
WD
546 lis r4, CFG_SDRAM_BASE@h /* Source Address */
547 ori r4, r4, CFG_SDRAM_BASE@l
548#else
549 lis r4, CFG_MONITOR_BASE@h /* Source Address */
550 ori r4, r4, CFG_MONITOR_BASE@l
551#endif
3b57fe0a
WD
552 lwz r5, GOT(__init_end)
553 sub r5, r5, r4
c609719b
WD
554 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
555
556 /*
557 * Fix GOT pointer:
558 *
559 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
560 *
561 * Offset:
562 */
563 sub r15, r10, r4
564
565 /* First our own GOT */
566 add r14, r14, r15
567 /* the the one used by the C code */
568 add r30, r30, r15
569
570 /*
571 * Now relocate code
572 */
573
574 cmplw cr1,r3,r4
575 addi r0,r5,3
576 srwi. r0,r0,2
577 beq cr1,4f /* In place copy is not necessary */
578 beq 7f /* Protect against 0 count */
579 mtctr r0
580 bge cr1,2f
581
582 la r8,-4(r4)
583 la r7,-4(r3)
5841: lwzu r0,4(r8)
585 stwu r0,4(r7)
586 bdnz 1b
587 b 4f
588
5892: slwi r0,r0,2
590 add r8,r4,r0
591 add r7,r3,r0
5923: lwzu r0,-4(r8)
593 stwu r0,-4(r7)
594 bdnz 3b
595
596/*
597 * Now flush the cache: note that we must start from a cache aligned
598 * address. Otherwise we might miss one cache line.
599 */
6004: cmpwi r6,0
601 add r5,r3,r5
602 beq 7f /* Always flush prefetch queue in any case */
603 subi r0,r6,1
604 andc r3,r3,r0
605 mr r4,r3
6065: dcbst 0,r4
607 add r4,r4,r6
608 cmplw r4,r5
609 blt 5b
610 sync /* Wait for all dcbst to complete on bus */
611 mr r4,r3
6126: icbi 0,r4
613 add r4,r4,r6
614 cmplw r4,r5
615 blt 6b
6167: sync /* Wait for all icbi to complete on bus */
617 isync
618
619/*
620 * We are done. Do not return, instead branch to second part of board
621 * initialization, now running from RAM.
622 */
623
624 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
625 mtlr r0
626 blr
627
628in_ram:
629
630 /*
631 * Relocation Function, r14 point to got2+0x8000
632 *
633 * Adjust got2 pointers, no need to check for 0, this code
634 * already puts a few entries in the table.
635 */
636 li r0,__got2_entries@sectoff@l
637 la r3,GOT(_GOT2_TABLE_)
638 lwz r11,GOT(_GOT2_TABLE_)
639 mtctr r0
640 sub r11,r3,r11
641 addi r3,r3,-4
6421: lwzu r0,4(r3)
643 add r0,r0,r11
644 stw r0,0(r3)
645 bdnz 1b
646
647 /*
648 * Now adjust the fixups and the pointers to the fixups
649 * in case we need to move ourselves again.
650 */
6512: li r0,__fixup_entries@sectoff@l
652 lwz r3,GOT(_FIXUP_TABLE_)
653 cmpwi r0,0
654 mtctr r0
655 addi r3,r3,-4
656 beq 4f
6573: lwzu r4,4(r3)
658 lwzux r0,r4,r11
659 add r0,r0,r11
660 stw r10,0(r3)
661 stw r0,0(r4)
662 bdnz 3b
6634:
664clear_bss:
665 /*
666 * Now clear BSS segment
667 */
5d232d0e 668 lwz r3,GOT(__bss_start)
c609719b
WD
669 lwz r4,GOT(_end)
670
671 cmplw 0, r3, r4
672 beq 6f
673
674 li r0, 0
6755:
676 stw r0, 0(r3)
677 addi r3, r3, 4
678 cmplw 0, r3, r4
679 blt 5b
6806:
681
682 mr r3, r9 /* Global Data pointer */
683 mr r4, r10 /* Destination Address */
684 bl board_init_r
685
c609719b
WD
686 /*
687 * Copy exception vector code to low memory
688 *
689 * r3: dest_addr
690 * r7: source address, r8: end address, r9: target address
691 */
692 .globl trap_init
693trap_init:
694 lwz r7, GOT(_start)
695 lwz r8, GOT(_end_of_vectors)
696
682011ff 697 li r9, 0x100 /* reset vector always at 0x100 */
c609719b
WD
698
699 cmplw 0, r7, r8
700 bgelr /* return if r7>=r8 - just in case */
701
702 mflr r4 /* save link register */
7031:
704 lwz r0, 0(r7)
705 stw r0, 0(r9)
706 addi r7, r7, 4
707 addi r9, r9, 4
708 cmplw 0, r7, r8
709 bne 1b
710
711 /*
712 * relocate `hdlr' and `int_return' entries
713 */
714 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
715 li r8, Alignment - _start + EXC_OFF_SYS_RESET
7162:
717 bl trap_reloc
718 addi r7, r7, 0x100 /* next exception vector */
719 cmplw 0, r7, r8
720 blt 2b
721
722 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
723 bl trap_reloc
724
725 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
726 bl trap_reloc
727
728 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
729 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
7303:
731 bl trap_reloc
732 addi r7, r7, 0x100 /* next exception vector */
733 cmplw 0, r7, r8
734 blt 3b
735
736 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
737 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
7384:
739 bl trap_reloc
740 addi r7, r7, 0x100 /* next exception vector */
741 cmplw 0, r7, r8
742 blt 4b
743
744 mtlr r4 /* restore link register */
745 blr
746
747 /*
748 * Function: relocate entries for one exception vector
749 */
750trap_reloc:
751 lwz r0, 0(r7) /* hdlr ... */
752 add r0, r0, r3 /* ... += dest_addr */
753 stw r0, 0(r7)
754
755 lwz r0, 4(r7) /* int_return ... */
756 add r0, r0, r3 /* ... += dest_addr */
757 stw r0, 4(r7)
758
759 blr
760
761 /* Setup the BAT registers.
762 */
763setup_bats:
764 lis r4, CFG_IBAT0L@h
765 ori r4, r4, CFG_IBAT0L@l
766 lis r3, CFG_IBAT0U@h
767 ori r3, r3, CFG_IBAT0U@l
768 mtspr IBAT0L, r4
769 mtspr IBAT0U, r3
770 isync
771
772 lis r4, CFG_DBAT0L@h
773 ori r4, r4, CFG_DBAT0L@l
774 lis r3, CFG_DBAT0U@h
775 ori r3, r3, CFG_DBAT0U@l
776 mtspr DBAT0L, r4
777 mtspr DBAT0U, r3
778 isync
779
780 lis r4, CFG_IBAT1L@h
781 ori r4, r4, CFG_IBAT1L@l
782 lis r3, CFG_IBAT1U@h
783 ori r3, r3, CFG_IBAT1U@l
784 mtspr IBAT1L, r4
785 mtspr IBAT1U, r3
786 isync
787
788 lis r4, CFG_DBAT1L@h
789 ori r4, r4, CFG_DBAT1L@l
790 lis r3, CFG_DBAT1U@h
791 ori r3, r3, CFG_DBAT1U@l
792 mtspr DBAT1L, r4
793 mtspr DBAT1U, r3
794 isync
795
796 lis r4, CFG_IBAT2L@h
797 ori r4, r4, CFG_IBAT2L@l
798 lis r3, CFG_IBAT2U@h
799 ori r3, r3, CFG_IBAT2U@l
800 mtspr IBAT2L, r4
801 mtspr IBAT2U, r3
802 isync
803
804 lis r4, CFG_DBAT2L@h
805 ori r4, r4, CFG_DBAT2L@l
806 lis r3, CFG_DBAT2U@h
807 ori r3, r3, CFG_DBAT2U@l
808 mtspr DBAT2L, r4
809 mtspr DBAT2U, r3
810 isync
811
812 lis r4, CFG_IBAT3L@h
813 ori r4, r4, CFG_IBAT3L@l
814 lis r3, CFG_IBAT3U@h
815 ori r3, r3, CFG_IBAT3U@l
816 mtspr IBAT3L, r4
817 mtspr IBAT3U, r3
818 isync
819
820 lis r4, CFG_DBAT3L@h
821 ori r4, r4, CFG_DBAT3L@l
822 lis r3, CFG_DBAT3U@h
823 ori r3, r3, CFG_DBAT3U@l
824 mtspr DBAT3L, r4
825 mtspr DBAT3U, r3
826 isync
827
828 /* Invalidate TLBs.
829 * -> for (val = 0; val < 0x20000; val+=0x1000)
830 * -> tlbie(val);
831 */
832 lis r3, 0
833 lis r5, 2
834
8351:
836 tlbie r3
837 addi r3, r3, 0x1000
838 cmp 0, 0, r3, r5
839 blt 1b
840
841 blr