blob: 885f1ab7f70bfc9fe9f3f70cf81f99cc413133d5 [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,
118 * 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 */
wdenk9c53f402003-10-15 23:53:47 +0000175 mtspr MAS4,r0
wdenk9c53f402003-10-15 23:53:47 +0000176 mtspr MAS6,r0
177 isync
178
179 /* Setup interrupt vectors */
wdenka445ddf2004-06-09 00:34:46 +0000180 lis r1,0xfff8
181 mtspr IVPR, r1
wdenk9c53f402003-10-15 23:53:47 +0000182
183 li r1,0x0100
184 mtspr IVOR0,r1 /* 0: Critical input */
185 li r1,0x0200
186 mtspr IVOR1,r1 /* 1: Machine check */
187 li r1,0x0300
188 mtspr IVOR2,r1 /* 2: Data storage */
189 li r1,0x0400
190 mtspr IVOR3,r1 /* 3: Instruction storage */
191 li r1,0x0500
192 mtspr IVOR4,r1 /* 4: External interrupt */
193 li r1,0x0600
194 mtspr IVOR5,r1 /* 5: Alignment */
195 li r1,0x0700
196 mtspr IVOR6,r1 /* 6: Program check */
197 li r1,0x0800
198 mtspr IVOR7,r1 /* 7: floating point unavailable */
199 li r1,0x0c00
200 mtspr IVOR8,r1 /* 8: System call */
201 /* 9: Auxiliary processor unavailable(unsupported) */
202 li r1,0x1000
203 mtspr IVOR10,r1 /* 10: Decrementer */
204 li r1,0x1400
205 mtspr IVOR13,r1 /* 13: Data TLB error */
206 li r1,0x1300
207 mtspr IVOR14,r1 /* 14: Instruction TLB error */
208 li r1,0x2000
209 mtspr IVOR15,r1 /* 15: Debug */
210
wdenka445ddf2004-06-09 00:34:46 +0000211 /*
212 * Invalidate MMU L1/L2
213 *
214 * Note: There is a fixup earlier for Errata CPU4 on
215 * Rev 1 parts that must precede this MMU invalidation.
wdenk9c53f402003-10-15 23:53:47 +0000216 */
wdenk9c53f402003-10-15 23:53:47 +0000217 li r2, 0x001e
218 mtspr MMUCSR0, r2
219 isync
wdenk9c53f402003-10-15 23:53:47 +0000220
221 /* After reset, CCSRBAR is located at CFG_CCSRBAR_DEFAULT, i.e.
222 * 0xff700000-0xff800000. We need add a TLB1 entry for this 1MB
223 * region before we can access any CCSR registers such as L2
224 * registers, Local Access Registers,etc. We will also re-allocate
225 * CFG_CCSRBAR_DEFAULT to CFG_CCSRBAR immediately after TLB1 setup.
226 *
227 * Please refer to board-specif directory for TLB1 entry configuration.
228 * (e.g. board/<yourboard>/init.S)
229 *
230 */
231 bl tlb1_entry
232 mr r5,r0
233 li r1,0x000f /* max 16 TLB1 entries */
234 mtctr r1
235 lwzu r4,0(r5) /* how many TLB1 entries we actually use */
236
2370: cmpwi r4,0
238 beq 1f
239 lwzu r0,4(r5)
240 lwzu r1,4(r5)
241 lwzu r2,4(r5)
242 lwzu r3,4(r5)
243 mtspr MAS0,r0
244 mtspr MAS1,r1
245 mtspr MAS2,r2
246 mtspr MAS3,r3
247 isync
248 msync
249 tlbwe
250 isync
251 addi r4,r4,-1
252 bdnz 0b
253
2541:
255#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
256 /* Special sequence needed to update CCSRBAR itself */
257 lis r4, CFG_CCSRBAR_DEFAULT@h
258 ori r4, r4, CFG_CCSRBAR_DEFAULT@l
259
260 lis r5, CFG_CCSRBAR@h
261 ori r5, r5, CFG_CCSRBAR@l
262 srwi r6,r5,12
263 stw r6, 0(r4)
264 isync
265
266 lis r5, 0xffff
267 ori r5,r5,0xf000
268 lwz r5, 0(r5)
269 isync
270
271 lis r3, CFG_CCSRBAR@h
272 lwz r5, CFG_CCSRBAR@l(r3)
273 isync
274#endif
275
276 /* invalidate all TLB0 entries */
277 li r3,4
278 li r4,0
279 tlbivax r4,r3
wdenka445ddf2004-06-09 00:34:46 +0000280 /*
281 * To avoid REV1 Errata CPU6 issues, make sure
282 * the instruction following tlbivax is not a store.
283 */
284
wdenk9c53f402003-10-15 23:53:47 +0000285
286 /* set up local access windows, defined at board/<boardname>/init.S */
287 lis r7,CFG_CCSRBAR@h
288 ori r7,r7,CFG_CCSRBAR@l
289
290 bl law_entry
291 mr r6,r0
292#if defined(CONFIG_RAM_AS_FLASH)
293 li r1,0x0006
294#else
295 li r1,0x0007 /*we have 8 LAWs, but reseve one for boot-over-rio-or-pci */
296#endif
297 mtctr r1
298 lwzu r5,0(r6) /* how many windows we actually use */
299
300#if defined(CONFIG_RAM_AS_FLASH)
301 li r2,0x0c48
302 li r1,0x0c50
303#else
304 li r2,0x0c28 /* the first pair is reserved for boot-over-rio-or-pci */
305 li r1,0x0c30
306#endif
307
3080: cmpwi r5,0
309 beq 1f
310 lwzu r4,4(r6)
311 lwzu r3,4(r6)
312 stwx r4,r7,r2
313 stwx r3,r7,r1
314 addi r5,r5,-1
315 addi r2,r2,0x0020
316 addi r1,r1,0x0020
317 bdnz 0b
318
319 /* Jump out the last 4K page and continue to 'normal' start */
3201: bl 3f
321 b _start
322
3233: li r0,0
324 mtspr SRR1,r0 /* Keep things disabled for now */
325 mflr r1
326 mtspr SRR0,r1
327 rfi
328
329/*
330 * r3 - 1st arg to board_init(): IMMP pointer
331 * r4 - 2nd arg to board_init(): boot flag
332 */
333 .text
334 .long 0x27051956 /* U-BOOT Magic Number */
335 .globl version_string
336version_string:
337 .ascii U_BOOT_VERSION
338 .ascii " (", __DATE__, " - ", __TIME__, ")"
339 .ascii CONFIG_IDENT_STRING, "\0"
340
341 . = EXC_OFF_SYS_RESET
342 .globl _start
343_start:
344 /* Clear and set up some registers. */
345 li r0,0x0000
346 lis r1,0xffff
347 mtspr DEC,r0 /* prevent dec exceptions */
348 mttbl r0 /* prevent fit & wdt exceptions */
349 mttbu r0
350 mtspr TSR,r1 /* clear all timer exception status */
351 mtspr TCR,r0 /* disable all */
352 mtspr ESR,r0 /* clear exception syndrome register */
353 mtspr MCSR,r0 /* machine check syndrome register */
354 mtxer r0 /* clear integer exception register */
355 lis r1,0x0002 /* set CE bit (Critical Exceptions) */
356 ori r1,r1,0x1200 /* set ME/DE bit */
357 mtmsr r1 /* change MSR */
358 isync
359
360 /* Enable Time Base and Select Time Base Clock */
wdenk13eb2212004-07-09 23:27:13 +0000361 lis r0,HID0_EMCP@h /* Enable machine check */
362 ori r0,r0,0x4000 /* time base is processor clock */
wdenk9c53f402003-10-15 23:53:47 +0000363 mtspr HID0,r0
wdenk9c53f402003-10-15 23:53:47 +0000364
365#if defined(CONFIG_ADDR_STREAMING)
wdenka983cc22003-10-26 22:52:58 +0000366 li r0,0x3000
367#else
368 li r0,0x1000
369#endif
wdenk9c53f402003-10-15 23:53:47 +0000370 mtspr HID1,r0
wdenk9c53f402003-10-15 23:53:47 +0000371
372 /* Enable Branch Prediction */
373#if defined(CONFIG_BTB)
374 li r0,0x201 /* BBFI = 1, BPEN = 1 */
375 mtspr BUCSR,r0
wdenk9c53f402003-10-15 23:53:47 +0000376#endif
377
378#if defined(CFG_INIT_DBCR)
379 lis r1,0xffff
380 ori r1,r1,0xffff
wdenk13eb2212004-07-09 23:27:13 +0000381 mtspr DBSR,r1 /* Clear all status bits */
wdenk9c53f402003-10-15 23:53:47 +0000382 lis r0,CFG_INIT_DBCR@h /* DBCR0[IDM] must be set */
383 ori r0,r0,CFG_INIT_DBCR@l
wdenk13eb2212004-07-09 23:27:13 +0000384 mtspr DBCR0,r0
wdenk9c53f402003-10-15 23:53:47 +0000385#endif
386
387/* L1 DCache is used for initial RAM */
388 mfspr r2, L1CSR0
389 ori r2, r2, 0x0003
390 oris r2, r2, 0x0001
wdenk9c53f402003-10-15 23:53:47 +0000391 mtspr L1CSR0, r2 /* enable/invalidate L1 Dcache */
392 isync
393
394 /* Allocate Initial RAM in data cache.
395 */
396 lis r3, CFG_INIT_RAM_ADDR@h
397 ori r3, r3, CFG_INIT_RAM_ADDR@l
398 li r2, 512 /* 512*32=16K */
399 mtctr r2
400 li r0, 0
4011:
402 dcbz r0, r3
403 dcbtls 0,r0, r3
404 addi r3, r3, 32
405 bdnz 1b
406
407#ifndef CFG_RAMBOOT
408 /* Calculate absolute address in FLASH and jump there */
409 /*--------------------------------------------------------------*/
410 lis r3, CFG_MONITOR_BASE@h
411 ori r3, r3, CFG_MONITOR_BASE@l
412 addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
413 mtlr r3
414 blr
415
416in_flash:
417#endif /* CFG_RAMBOOT */
418
419 /* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/
420 lis r1,CFG_INIT_RAM_ADDR@h
421 ori r1,r1,CFG_INIT_SP_OFFSET@l
422
423 li r0,0
424 stwu r0,-4(r1)
425 stwu r0,-4(r1) /* Terminate call chain */
426
427 stwu r1,-8(r1) /* Save back chain and move SP */
428 lis r0,RESET_VECTOR@h /* Address of reset vector */
429 ori r0,r0, RESET_VECTOR@l
430 stwu r1,-8(r1) /* Save back chain and move SP */
431 stw r0,+12(r1) /* Save return addr (underflow vect) */
432
433 GET_GOT
434 bl cpu_init_f
435 bl icache_enable
436 bl board_init_f
wdenk13eb2212004-07-09 23:27:13 +0000437 isync
wdenk9c53f402003-10-15 23:53:47 +0000438
439/* --FIXME-- machine check with MCSRRn and rfmci */
440
441 .globl _start_of_vectors
442_start_of_vectors:
443#if 0
444/* Critical input. */
445 CRIT_EXCEPTION(0x0100, CritcalInput, CritcalInputException)
446#endif
447/* Machine check --FIXME-- Should be MACH_EXCEPTION */
448 CRIT_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
449
450/* Data Storage exception. */
451 STD_EXCEPTION(0x0300, DataStorage, UnknownException)
452
453/* Instruction Storage exception. */
454 STD_EXCEPTION(0x0400, InstStorage, UnknownException)
455
456/* External Interrupt exception. */
457 STD_EXCEPTION(0x0500, ExtInterrupt, UnknownException)
458
459/* Alignment exception. */
460 . = 0x0600
461Alignment:
462 EXCEPTION_PROLOG
463 mfspr r4,DAR
464 stw r4,_DAR(r21)
465 mfspr r5,DSISR
466 stw r5,_DSISR(r21)
467 addi r3,r1,STACK_FRAME_OVERHEAD
468 li r20,MSR_KERNEL
469 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
470 lwz r6,GOT(transfer_to_handler)
471 mtlr r6
472 blrl
473.L_Alignment:
474 .long AlignmentException - _start + EXC_OFF_SYS_RESET
475 .long int_return - _start + EXC_OFF_SYS_RESET
476
477/* Program check exception */
478 . = 0x0700
479ProgramCheck:
480 EXCEPTION_PROLOG
481 addi r3,r1,STACK_FRAME_OVERHEAD
482 li r20,MSR_KERNEL
483 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
484 lwz r6,GOT(transfer_to_handler)
485 mtlr r6
486 blrl
487.L_ProgramCheck:
488 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
489 .long int_return - _start + EXC_OFF_SYS_RESET
490
491 /* No FPU on MPC85xx. This exception is not supposed to happen.
492 */
493 STD_EXCEPTION(0x0800, FPUnavailable, UnknownException)
494 STD_EXCEPTION(0x0900, Decrementer, timer_interrupt)
495 STD_EXCEPTION(0x0a00, Trap_0a, UnknownException)
496 STD_EXCEPTION(0x0b00, Trap_0b, UnknownException)
497
498 . = 0x0c00
499/*
500 * r0 - SYSCALL number
501 * r3-... arguments
502 */
503SystemCall:
504 addis r11,r0,0 /* get functions table addr */
505 ori r11,r11,0 /* Note: this code is patched in trap_init */
506 addis r12,r0,0 /* get number of functions */
507 ori r12,r12,0
508
509 cmplw 0, r0, r12
510 bge 1f
511
512 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */
513 add r11,r11,r0
514 lwz r11,0(r11)
515
516 li r20,0xd00-4 /* Get stack pointer */
517 lwz r12,0(r20)
518 subi r12,r12,12 /* Adjust stack pointer */
519 li r0,0xc00+_end_back-SystemCall
520 cmplw 0, r0, r12 /* Check stack overflow */
521 bgt 1f
522 stw r12,0(r20)
523
524 mflr r0
525 stw r0,0(r12)
526 mfspr r0,SRR0
527 stw r0,4(r12)
528 mfspr r0,SRR1
529 stw r0,8(r12)
530
531 li r12,0xc00+_back-SystemCall
532 mtlr r12
533 mtspr SRR0,r11
534
5351: SYNC
536 rfi
537_back:
538
539 mfmsr r11 /* Disable interrupts */
540 li r12,0
541 ori r12,r12,MSR_EE
542 andc r11,r11,r12
543 SYNC /* Some chip revs need this... */
544 mtmsr r11
545 SYNC
546
547 li r12,0xd00-4 /* restore regs */
548 lwz r12,0(r12)
549
550 lwz r11,0(r12)
551 mtlr r11
552 lwz r11,4(r12)
553 mtspr SRR0,r11
554 lwz r11,8(r12)
555 mtspr SRR1,r11
556
557 addi r12,r12,12 /* Adjust stack pointer */
558 li r20,0xd00-4
559 stw r12,0(r20)
560
561 SYNC
562 rfi
563_end_back:
564
565 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
566
567 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
568 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
569
570 STD_EXCEPTION(0x1000, PIT, PITException)
571
572 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
573 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
574 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
575 STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
576
577 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
578 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
579 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
580 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
581 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
582 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
583 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
584
585 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
586 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
587 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
588 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
589
590 CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
591
592 .globl _end_of_vectors
593_end_of_vectors:
594
595
596 . = 0x2100
597
598/*
599 * This code finishes saving the registers to the exception frame
600 * and jumps to the appropriate handler for the exception.
601 * Register r21 is pointer into trap frame, r1 has new stack pointer.
602 */
603 .globl transfer_to_handler
604transfer_to_handler:
605 stw r22,_NIP(r21)
606 lis r22,MSR_POW@h
607 andc r23,r23,r22
608 stw r23,_MSR(r21)
609 SAVE_GPR(7, r21)
610 SAVE_4GPRS(8, r21)
611 SAVE_8GPRS(12, r21)
612 SAVE_8GPRS(24, r21)
613
614 mflr r23
615 andi. r24,r23,0x3f00 /* get vector offset */
616 stw r24,TRAP(r21)
617 li r22,0
618 stw r22,RESULT(r21)
619 mtspr SPRG2,r22 /* r1 is now kernel sp */
620
621 lwz r24,0(r23) /* virtual address of handler */
622 lwz r23,4(r23) /* where to go when done */
623 mtspr SRR0,r24
624 mtspr SRR1,r20
625 mtlr r23
626 SYNC
627 rfi /* jump to handler, enable MMU */
628
629int_return:
630 mfmsr r28 /* Disable interrupts */
631 li r4,0
632 ori r4,r4,MSR_EE
633 andc r28,r28,r4
634 SYNC /* Some chip revs need this... */
635 mtmsr r28
636 SYNC
637 lwz r2,_CTR(r1)
638 lwz r0,_LINK(r1)
639 mtctr r2
640 mtlr r0
641 lwz r2,_XER(r1)
642 lwz r0,_CCR(r1)
643 mtspr XER,r2
644 mtcrf 0xFF,r0
645 REST_10GPRS(3, r1)
646 REST_10GPRS(13, r1)
647 REST_8GPRS(23, r1)
648 REST_GPR(31, r1)
649 lwz r2,_NIP(r1) /* Restore environment */
650 lwz r0,_MSR(r1)
651 mtspr SRR0,r2
652 mtspr SRR1,r0
653 lwz r0,GPR0(r1)
654 lwz r2,GPR2(r1)
655 lwz r1,GPR1(r1)
656 SYNC
657 rfi
658
659crit_return:
660 mfmsr r28 /* Disable interrupts */
661 li r4,0
662 ori r4,r4,MSR_EE
663 andc r28,r28,r4
664 SYNC /* Some chip revs need this... */
665 mtmsr r28
666 SYNC
667 lwz r2,_CTR(r1)
668 lwz r0,_LINK(r1)
669 mtctr r2
670 mtlr r0
671 lwz r2,_XER(r1)
672 lwz r0,_CCR(r1)
673 mtspr XER,r2
674 mtcrf 0xFF,r0
675 REST_10GPRS(3, r1)
676 REST_10GPRS(13, r1)
677 REST_8GPRS(23, r1)
678 REST_GPR(31, r1)
679 lwz r2,_NIP(r1) /* Restore environment */
680 lwz r0,_MSR(r1)
681 mtspr 990,r2 /* SRR2 */
682 mtspr 991,r0 /* SRR3 */
683 lwz r0,GPR0(r1)
684 lwz r2,GPR2(r1)
685 lwz r1,GPR1(r1)
686 SYNC
687 rfci
688
689/* Cache functions.
690*/
691invalidate_icache:
692 mfspr r0,L1CSR1
693 ori r0,r0,0x0002
694 mtspr L1CSR1,r0
695 isync
696 blr /* entire I cache */
697
698invalidate_dcache:
699 mfspr r0,L1CSR0
700 ori r0,r0,0x0002
701 msync
702 isync
703 mtspr L1CSR0,r0
704 isync
705 blr
706
707 .globl icache_enable
708icache_enable:
709 mflr r8
710 bl invalidate_icache
711 mtlr r8
712 isync
713 mfspr r4,L1CSR1
714 ori r4,r4,0x0001
715 oris r4,r4,0x0001
716 mtspr L1CSR1,r4
717 isync
718 blr
719
720 .globl icache_disable
721icache_disable:
722 mfspr r0,L1CSR1
723 lis r1,0xfffffffe@h
724 ori r1,r1,0xfffffffe@l
725 and r0,r0,r1
726 mtspr L1CSR1,r0
727 isync
728 blr
729
730 .globl icache_status
731icache_status:
732 mfspr r3,L1CSR1
733 srwi r3, r3, 31 /* >>31 => select bit 0 */
734 blr
735
736 .globl dcache_enable
737dcache_enable:
738 mflr r8
739 bl invalidate_dcache
740 mtlr r8
741 isync
742 mfspr r0,L1CSR0
743 ori r0,r0,0x0001
744 oris r0,r0,0x0001
745 msync
746 isync
747 mtspr L1CSR0,r0
748 isync
749 blr
750
751 .globl dcache_disable
752dcache_disable:
753 mfspr r0,L1CSR0
754 lis r1,0xfffffffe@h
755 ori r1,r1,0xfffffffe@l
756 and r0,r0,r1
757 msync
758 isync
759 mtspr L1CSR0,r0
760 isync
761 blr
762
763 .globl dcache_status
764dcache_status:
765 mfspr r3,L1CSR0
766 srwi r3, r3, 31 /* >>31 => select bit 0 */
767 blr
768
769 .globl get_pir
770get_pir:
771 mfspr r3, PIR
772 blr
773
774 .globl get_pvr
775get_pvr:
776 mfspr r3, PVR
777 blr
778
wdenka445ddf2004-06-09 00:34:46 +0000779 .globl get_svr
780get_svr:
781 mfspr r3, SVR
782 blr
783
wdenk9c53f402003-10-15 23:53:47 +0000784 .globl wr_tcr
785wr_tcr:
786 mtspr TCR, r3
787 blr
788
789/*------------------------------------------------------------------------------- */
790/* Function: in8 */
791/* Description: Input 8 bits */
792/*------------------------------------------------------------------------------- */
793 .globl in8
794in8:
795 lbz r3,0x0000(r3)
796 blr
797
798/*------------------------------------------------------------------------------- */
799/* Function: out8 */
800/* Description: Output 8 bits */
801/*------------------------------------------------------------------------------- */
802 .globl out8
803out8:
804 stb r4,0x0000(r3)
805 blr
806
807/*------------------------------------------------------------------------------- */
808/* Function: out16 */
809/* Description: Output 16 bits */
810/*------------------------------------------------------------------------------- */
811 .globl out16
812out16:
813 sth r4,0x0000(r3)
814 blr
815
816/*------------------------------------------------------------------------------- */
817/* Function: out16r */
818/* Description: Byte reverse and output 16 bits */
819/*------------------------------------------------------------------------------- */
820 .globl out16r
821out16r:
822 sthbrx r4,r0,r3
823 blr
824
825/*------------------------------------------------------------------------------- */
826/* Function: out32 */
827/* Description: Output 32 bits */
828/*------------------------------------------------------------------------------- */
829 .globl out32
830out32:
831 stw r4,0x0000(r3)
832 blr
833
834/*------------------------------------------------------------------------------- */
835/* Function: out32r */
836/* Description: Byte reverse and output 32 bits */
837/*------------------------------------------------------------------------------- */
838 .globl out32r
839out32r:
840 stwbrx r4,r0,r3
841 blr
842
843/*------------------------------------------------------------------------------- */
844/* Function: in16 */
845/* Description: Input 16 bits */
846/*------------------------------------------------------------------------------- */
847 .globl in16
848in16:
849 lhz r3,0x0000(r3)
850 blr
851
852/*------------------------------------------------------------------------------- */
853/* Function: in16r */
854/* Description: Input 16 bits and byte reverse */
855/*------------------------------------------------------------------------------- */
856 .globl in16r
857in16r:
858 lhbrx r3,r0,r3
859 blr
860
861/*------------------------------------------------------------------------------- */
862/* Function: in32 */
863/* Description: Input 32 bits */
864/*------------------------------------------------------------------------------- */
865 .globl in32
866in32:
867 lwz 3,0x0000(3)
868 blr
869
870/*------------------------------------------------------------------------------- */
871/* Function: in32r */
872/* Description: Input 32 bits and byte reverse */
873/*------------------------------------------------------------------------------- */
874 .globl in32r
875in32r:
876 lwbrx r3,r0,r3
877 blr
878
879/*------------------------------------------------------------------------------- */
880/* Function: ppcDcbf */
881/* Description: Data Cache block flush */
882/* Input: r3 = effective address */
883/* Output: none. */
884/*------------------------------------------------------------------------------- */
885 .globl ppcDcbf
886ppcDcbf:
887 dcbf r0,r3
888 blr
889
890/*------------------------------------------------------------------------------- */
891/* Function: ppcDcbi */
892/* Description: Data Cache block Invalidate */
893/* Input: r3 = effective address */
894/* Output: none. */
895/*------------------------------------------------------------------------------- */
896 .globl ppcDcbi
897ppcDcbi:
898 dcbi r0,r3
899 blr
900
wdenk13eb2212004-07-09 23:27:13 +0000901/*--------------------------------------------------------------------------
902 * Function: ppcDcbz
903 * Description: Data Cache block zero.
904 * Input: r3 = effective address
905 * Output: none.
906 *-------------------------------------------------------------------------- */
907
908 .globl ppcDcbz
909ppcDcbz:
910 dcbz r0,r3
911 blr
912
wdenk9c53f402003-10-15 23:53:47 +0000913/*------------------------------------------------------------------------------- */
914/* Function: ppcSync */
915/* Description: Processor Synchronize */
916/* Input: none. */
917/* Output: none. */
918/*------------------------------------------------------------------------------- */
919 .globl ppcSync
920ppcSync:
921 sync
922 blr
923
924/*------------------------------------------------------------------------------*/
925
926/*
927 * void relocate_code (addr_sp, gd, addr_moni)
928 *
929 * This "function" does not return, instead it continues in RAM
930 * after relocating the monitor code.
931 *
932 * r3 = dest
933 * r4 = src
934 * r5 = length in bytes
935 * r6 = cachelinesize
936 */
937 .globl relocate_code
938relocate_code:
939 mr r1, r3 /* Set new stack pointer */
940 mr r9, r4 /* Save copy of Init Data pointer */
941 mr r10, r5 /* Save copy of Destination Address */
942
943 mr r3, r5 /* Destination Address */
944 lis r4, CFG_MONITOR_BASE@h /* Source Address */
945 ori r4, r4, CFG_MONITOR_BASE@l
946 lwz r5,GOT(__init_end)
947 sub r5,r5,r4
948 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
949
950 /*
951 * Fix GOT pointer:
952 *
953 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
954 *
955 * Offset:
956 */
957 sub r15, r10, r4
958
959 /* First our own GOT */
960 add r14, r14, r15
961 /* the the one used by the C code */
962 add r30, r30, r15
963
964 /*
965 * Now relocate code
966 */
967
968 cmplw cr1,r3,r4
969 addi r0,r5,3
970 srwi. r0,r0,2
971 beq cr1,4f /* In place copy is not necessary */
972 beq 7f /* Protect against 0 count */
973 mtctr r0
974 bge cr1,2f
975
976 la r8,-4(r4)
977 la r7,-4(r3)
9781: lwzu r0,4(r8)
979 stwu r0,4(r7)
980 bdnz 1b
981 b 4f
982
9832: slwi r0,r0,2
984 add r8,r4,r0
985 add r7,r3,r0
9863: lwzu r0,-4(r8)
987 stwu r0,-4(r7)
988 bdnz 3b
989
990/*
991 * Now flush the cache: note that we must start from a cache aligned
992 * address. Otherwise we might miss one cache line.
993 */
9944: cmpwi r6,0
995 add r5,r3,r5
996 beq 7f /* Always flush prefetch queue in any case */
997 subi r0,r6,1
998 andc r3,r3,r0
999 mr r4,r3
10005: dcbst 0,r4
1001 add r4,r4,r6
1002 cmplw r4,r5
1003 blt 5b
1004 sync /* Wait for all dcbst to complete on bus */
1005 mr r4,r3
10066: icbi 0,r4
1007 add r4,r4,r6
1008 cmplw r4,r5
1009 blt 6b
10107: sync /* Wait for all icbi to complete on bus */
1011 isync
1012
1013/*
1014 * We are done. Do not return, instead branch to second part of board
1015 * initialization, now running from RAM.
1016 */
1017
1018 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
1019 mtlr r0
1020 blr /* NEVER RETURNS! */
1021
1022in_ram:
1023
1024 /*
1025 * Relocation Function, r14 point to got2+0x8000
1026 *
1027 * Adjust got2 pointers, no need to check for 0, this code
1028 * already puts a few entries in the table.
1029 */
1030 li r0,__got2_entries@sectoff@l
1031 la r3,GOT(_GOT2_TABLE_)
1032 lwz r11,GOT(_GOT2_TABLE_)
1033 mtctr r0
1034 sub r11,r3,r11
1035 addi r3,r3,-4
10361: lwzu r0,4(r3)
1037 add r0,r0,r11
1038 stw r0,0(r3)
1039 bdnz 1b
1040
1041 /*
1042 * Now adjust the fixups and the pointers to the fixups
1043 * in case we need to move ourselves again.
1044 */
10452: li r0,__fixup_entries@sectoff@l
1046 lwz r3,GOT(_FIXUP_TABLE_)
1047 cmpwi r0,0
1048 mtctr r0
1049 addi r3,r3,-4
1050 beq 4f
10513: lwzu r4,4(r3)
1052 lwzux r0,r4,r11
1053 add r0,r0,r11
1054 stw r10,0(r3)
1055 stw r0,0(r4)
1056 bdnz 3b
10574:
1058clear_bss:
1059 /*
1060 * Now clear BSS segment
1061 */
1062 lwz r3,GOT(__bss_start)
1063 lwz r4,GOT(_end)
1064
1065 cmplw 0, r3, r4
1066 beq 6f
1067
1068 li r0, 0
10695:
1070 stw r0, 0(r3)
1071 addi r3, r3, 4
1072 cmplw 0, r3, r4
1073 bne 5b
10746:
1075
1076 mr r3, r9 /* Init Data pointer */
1077 mr r4, r10 /* Destination Address */
1078 bl board_init_r
1079
1080 /*
1081 * Copy exception vector code to low memory
1082 *
1083 * r3: dest_addr
1084 * r7: source address, r8: end address, r9: target address
1085 */
1086 .globl trap_init
1087trap_init:
1088 lwz r7, GOT(_start)
1089 lwz r8, GOT(_end_of_vectors)
1090
1091 li r9, 0x100 /* reset vector always at 0x100 */
1092
1093 cmplw 0, r7, r8
1094 bgelr /* return if r7>=r8 - just in case */
1095
1096 mflr r4 /* save link register */
10971:
1098 lwz r0, 0(r7)
1099 stw r0, 0(r9)
1100 addi r7, r7, 4
1101 addi r9, r9, 4
1102 cmplw 0, r7, r8
1103 bne 1b
1104
1105 /*
1106 * relocate `hdlr' and `int_return' entries
1107 */
1108 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
1109 li r8, Alignment - _start + EXC_OFF_SYS_RESET
11102:
1111 bl trap_reloc
1112 addi r7, r7, 0x100 /* next exception vector */
1113 cmplw 0, r7, r8
1114 blt 2b
1115
1116 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1117 bl trap_reloc
1118
1119 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1120 bl trap_reloc
1121
1122 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1123 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
11243:
1125 bl trap_reloc
1126 addi r7, r7, 0x100 /* next exception vector */
1127 cmplw 0, r7, r8
1128 blt 3b
1129
1130 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1131 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
11324:
1133 bl trap_reloc
1134 addi r7, r7, 0x100 /* next exception vector */
1135 cmplw 0, r7, r8
1136 blt 4b
1137
1138 mtlr r4 /* restore link register */
1139 blr
1140
1141 /*
1142 * Function: relocate entries for one exception vector
1143 */
1144trap_reloc:
1145 lwz r0, 0(r7) /* hdlr ... */
1146 add r0, r0, r3 /* ... += dest_addr */
1147 stw r0, 0(r7)
1148
1149 lwz r0, 4(r7) /* int_return ... */
1150 add r0, r0, r3 /* ... += dest_addr */
1151 stw r0, 4(r7)
1152
1153 blr
1154
1155#ifdef CFG_INIT_RAM_LOCK
1156.globl unlock_ram_in_cache
1157unlock_ram_in_cache:
1158 /* invalidate the INIT_RAM section */
1159 lis r3, (CFG_INIT_RAM_ADDR & ~31)@h
1160 ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
1161 li r2,512
1162 mtctr r2
11631: icbi r0, r3
1164 dcbi r0, r3
1165 addi r3, r3, 32
1166 bdnz 1b
1167 sync /* Wait for all icbi to complete on bus */
1168 isync
1169 blr
1170#endif