]> git.ipfire.org Git - people/ms/u-boot.git/blame - cpu/mpc824x/start.S
Add support for arbitrary bitmaps for TRAB's VFD command;
[people/ms/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
76 GOT_ENTRY(_end)
77 GOT_ENTRY(.bss)
78#if defined(CONFIG_FADS)
79 GOT_ENTRY(environment)
80#endif
81 END_GOT
82
83/*
84 * r3 - 1st arg to board_init(): IMMP pointer
85 * r4 - 2nd arg to board_init(): boot flag
86 */
87 .text
88 .long 0x27051956 /* U-Boot Magic Number */
89 .globl version_string
90version_string:
91 .ascii U_BOOT_VERSION
92 .ascii " (", __DATE__, " - ", __TIME__, ")"
93 .ascii CONFIG_IDENT_STRING, "\0"
94
95 . = EXC_OFF_SYS_RESET
96 .globl _start
97_start:
98 li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH */
99 b boot_cold
100
101 . = EXC_OFF_SYS_RESET + 0x10
102
103 .globl _start_warm
104_start_warm:
105 li r21, BOOTFLAG_WARM /* Software reboot */
106 b boot_warm
107
108boot_cold:
109boot_warm:
110
111 /* Initialize machine status; enable machine check interrupt */
112 /*----------------------------------------------------------------------*/
113 li r3, MSR_KERNEL /* Set FP, ME, RI flags */
114 mtmsr r3
115 mtspr SRR1, r3 /* Make SRR1 match MSR */
116
117 addis r0,0,0x0000 /* lets make sure that r0 is really 0 */
118 mtspr HID0, r0 /* disable I and D caches */
119
120 mfspr r3, ICR /* clear Interrupt Cause Register */
121
122 mfmsr r3 /* turn off address translation */
123 addis r4,0,0xffff
124 ori r4,r4,0xffcf
125 and r3,r3,r4
126 mtmsr r3
127 isync
128 sync /* the MMU should be off... */
129
130
131in_flash:
132#if defined(CONFIG_BMW)
133 bl early_init_f /* Must be ASM: no stack yet! */
134#endif
135 /*
136 * Setup BATs - cannot be done in C since we don't have a stack yet
137 */
138 bl setup_bats
139
140 /* Enable MMU.
141 */
142 mfmsr r3
143 ori r3, r3, (MSR_IR | MSR_DR)
144 mtmsr r3
145#if !defined(CONFIG_BMW)
146 /* Enable and invalidate data cache.
147 */
148 mfspr r3, HID0
149 mr r2, r3
150 ori r3, r3, HID0_DCE | HID0_DCI
151 ori r2, r2, HID0_DCE
152 sync
153 mtspr HID0, r3
154 mtspr HID0, r2
155 sync
156
157 /* Allocate Initial RAM in data cache.
158 */
159 lis r3, CFG_INIT_RAM_ADDR@h
160 ori r3, r3, CFG_INIT_RAM_ADDR@l
161 li r2, 128
162 mtctr r2
1631:
164 dcbz r0, r3
165 addi r3, r3, 32
166 bdnz 1b
167
168 /* Lock way0 in data cache.
169 */
170 mfspr r3, 1011
171 lis r2, 0xffff
172 ori r2, r2, 0xff1f
173 and r3, r3, r2
174 ori r3, r3, 0x0080
175 sync
176 mtspr 1011, r3
177#endif /* !CONFIG_BMW */
178 /*
179 * Thisk the stack pointer *somewhere* sensible. Doesnt
180 * matter much where as we'll move it when we relocate
181 */
182 lis r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h
183 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l
184
185 li r0, 0 /* Make room for stack frame header and */
186 stwu r0, -4(r1) /* clear final stack frame so that */
187 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
188
189 /* let the C-code set up the rest */
190 /* */
191 /* Be careful to keep code relocatable ! */
192 /*----------------------------------------------------------------------*/
193
194 GET_GOT /* initialize GOT access */
195
196 /* r3: IMMR */
197 bl cpu_init_f /* run low-level CPU init code (from Flash) */
198
199 mr r3, r21
200 /* r3: BOOTFLAG */
201 bl board_init_f /* run 1st part of board init code (from Flash) */
202
203
204
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 */
545#ifdef DEBUG
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
552 lis r5, CFG_MONITOR_LEN@h /* Length in Bytes */
553 ori r5, r5, CFG_MONITOR_LEN@l
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 */
668 lwz r3,GOT(.bss)
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
686 /* Problems accessing "end" in C, so do it here */
687 .globl get_endaddr
688get_endaddr:
689 lwz r3,GOT(_end)
690 blr
691
692 /*
693 * Copy exception vector code to low memory
694 *
695 * r3: dest_addr
696 * r7: source address, r8: end address, r9: target address
697 */
698 .globl trap_init
699trap_init:
700 lwz r7, GOT(_start)
701 lwz r8, GOT(_end_of_vectors)
702
703 rlwinm r9, r7, 0, 18, 31 /* _start & 0x3FFF */
704
705 cmplw 0, r7, r8
706 bgelr /* return if r7>=r8 - just in case */
707
708 mflr r4 /* save link register */
7091:
710 lwz r0, 0(r7)
711 stw r0, 0(r9)
712 addi r7, r7, 4
713 addi r9, r9, 4
714 cmplw 0, r7, r8
715 bne 1b
716
717 /*
718 * relocate `hdlr' and `int_return' entries
719 */
720 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
721 li r8, Alignment - _start + EXC_OFF_SYS_RESET
7222:
723 bl trap_reloc
724 addi r7, r7, 0x100 /* next exception vector */
725 cmplw 0, r7, r8
726 blt 2b
727
728 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
729 bl trap_reloc
730
731 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
732 bl trap_reloc
733
734 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
735 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
7363:
737 bl trap_reloc
738 addi r7, r7, 0x100 /* next exception vector */
739 cmplw 0, r7, r8
740 blt 3b
741
742 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
743 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
7444:
745 bl trap_reloc
746 addi r7, r7, 0x100 /* next exception vector */
747 cmplw 0, r7, r8
748 blt 4b
749
750 mtlr r4 /* restore link register */
751 blr
752
753 /*
754 * Function: relocate entries for one exception vector
755 */
756trap_reloc:
757 lwz r0, 0(r7) /* hdlr ... */
758 add r0, r0, r3 /* ... += dest_addr */
759 stw r0, 0(r7)
760
761 lwz r0, 4(r7) /* int_return ... */
762 add r0, r0, r3 /* ... += dest_addr */
763 stw r0, 4(r7)
764
765 blr
766
767 /* Setup the BAT registers.
768 */
769setup_bats:
770 lis r4, CFG_IBAT0L@h
771 ori r4, r4, CFG_IBAT0L@l
772 lis r3, CFG_IBAT0U@h
773 ori r3, r3, CFG_IBAT0U@l
774 mtspr IBAT0L, r4
775 mtspr IBAT0U, r3
776 isync
777
778 lis r4, CFG_DBAT0L@h
779 ori r4, r4, CFG_DBAT0L@l
780 lis r3, CFG_DBAT0U@h
781 ori r3, r3, CFG_DBAT0U@l
782 mtspr DBAT0L, r4
783 mtspr DBAT0U, r3
784 isync
785
786 lis r4, CFG_IBAT1L@h
787 ori r4, r4, CFG_IBAT1L@l
788 lis r3, CFG_IBAT1U@h
789 ori r3, r3, CFG_IBAT1U@l
790 mtspr IBAT1L, r4
791 mtspr IBAT1U, r3
792 isync
793
794 lis r4, CFG_DBAT1L@h
795 ori r4, r4, CFG_DBAT1L@l
796 lis r3, CFG_DBAT1U@h
797 ori r3, r3, CFG_DBAT1U@l
798 mtspr DBAT1L, r4
799 mtspr DBAT1U, r3
800 isync
801
802 lis r4, CFG_IBAT2L@h
803 ori r4, r4, CFG_IBAT2L@l
804 lis r3, CFG_IBAT2U@h
805 ori r3, r3, CFG_IBAT2U@l
806 mtspr IBAT2L, r4
807 mtspr IBAT2U, r3
808 isync
809
810 lis r4, CFG_DBAT2L@h
811 ori r4, r4, CFG_DBAT2L@l
812 lis r3, CFG_DBAT2U@h
813 ori r3, r3, CFG_DBAT2U@l
814 mtspr DBAT2L, r4
815 mtspr DBAT2U, r3
816 isync
817
818 lis r4, CFG_IBAT3L@h
819 ori r4, r4, CFG_IBAT3L@l
820 lis r3, CFG_IBAT3U@h
821 ori r3, r3, CFG_IBAT3U@l
822 mtspr IBAT3L, r4
823 mtspr IBAT3U, r3
824 isync
825
826 lis r4, CFG_DBAT3L@h
827 ori r4, r4, CFG_DBAT3L@l
828 lis r3, CFG_DBAT3U@h
829 ori r3, r3, CFG_DBAT3U@l
830 mtspr DBAT3L, r4
831 mtspr DBAT3U, r3
832 isync
833
834 /* Invalidate TLBs.
835 * -> for (val = 0; val < 0x20000; val+=0x1000)
836 * -> tlbie(val);
837 */
838 lis r3, 0
839 lis r5, 2
840
8411:
842 tlbie r3
843 addi r3, r3, 0x1000
844 cmp 0, 0, r3, r5
845 blt 1b
846
847 blr
848
849