]> git.ipfire.org Git - people/ms/u-boot.git/blame - cpu/mpc85xx/start.S
Big white-space cleanup.
[people/ms/u-boot.git] / cpu / mpc85xx / start.S
CommitLineData
42d1f039 1/*
61a21e98 2 * Copyright 2004, 2007 Freescale Semiconductor.
42d1f039 3 * Copyright (C) 2003 Motorola,Inc.
42d1f039
WD
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24/* U-Boot Startup Code for Motorola 85xx PowerPC based Embedded Boards
25 *
26 * The processor starts at 0xfffffffc and the code is first executed in the
27 * last 4K page(0xfffff000-0xffffffff) in flash/rom.
28 *
29 */
30
31#include <config.h>
32#include <mpc85xx.h>
33#include <version.h>
34
35#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
36
37#include <ppc_asm.tmpl>
38#include <ppc_defs.h>
39
40#include <asm/cache.h>
41#include <asm/mmu.h>
42
43#ifndef CONFIG_IDENT_STRING
44#define CONFIG_IDENT_STRING ""
45#endif
46
47#undef MSR_KERNEL
61a21e98 48#define MSR_KERNEL ( MSR_ME ) /* Machine Check */
42d1f039
WD
49
50/*
51 * Set up GOT: Global Offset Table
52 *
53 * Use r14 to access the GOT
54 */
55 START_GOT
56 GOT_ENTRY(_GOT2_TABLE_)
57 GOT_ENTRY(_FIXUP_TABLE_)
58
59 GOT_ENTRY(_start)
60 GOT_ENTRY(_start_of_vectors)
61 GOT_ENTRY(_end_of_vectors)
62 GOT_ENTRY(transfer_to_handler)
63
64 GOT_ENTRY(__init_end)
65 GOT_ENTRY(_end)
66 GOT_ENTRY(__bss_start)
67 END_GOT
68
69/*
70 * e500 Startup -- after reset only the last 4KB of the effective
71 * address space is mapped in the MMU L2 TLB1 Entry0. The .bootpg
72 * section is located at THIS LAST page and basically does three
73 * things: clear some registers, set up exception tables and
74 * add more TLB entries for 'larger spaces'(e.g. the boot rom) to
75 * continue the boot procedure.
76
77 * Once the boot rom is mapped by TLB entries we can proceed
78 * with normal startup.
79 *
80 */
81
61a21e98
AF
82 .section .bootpg,"ax"
83 .globl _start_e500
42d1f039
WD
84
85_start_e500:
97d80fc3 86
61a21e98 87/* clear registers/arrays not reset by hardware */
42d1f039 88
61a21e98
AF
89 /* L1 */
90 li r0,2
91 mtspr L1CSR0,r0 /* invalidate d-cache */
53677ef1 92 mtspr L1CSR1,r0 /* invalidate i-cache */
42d1f039
WD
93
94 mfspr r1,DBSR
95 mtspr DBSR,r1 /* Clear all valid bits */
96
61a21e98
AF
97 /*
98 * Enable L1 Caches early
99 *
100 */
42d1f039 101
61a21e98
AF
102 lis r2,L1CSR0_CPE@H /* enable parity */
103 ori r2,r2,L1CSR0_DCE
104 mtspr L1CSR0,r2 /* enable L1 Dcache */
105 isync
106 mtspr L1CSR1,r2 /* enable L1 Icache */
42d1f039 107 isync
61a21e98 108 msync
42d1f039
WD
109
110 /* Setup interrupt vectors */
343117bf 111 lis r1,TEXT_BASE@h
61a21e98 112 mtspr IVPR,r1
42d1f039 113
343117bf 114 li r1,0x0100
42d1f039 115 mtspr IVOR0,r1 /* 0: Critical input */
343117bf 116 li r1,0x0200
42d1f039 117 mtspr IVOR1,r1 /* 1: Machine check */
343117bf 118 li r1,0x0300
42d1f039 119 mtspr IVOR2,r1 /* 2: Data storage */
343117bf 120 li r1,0x0400
42d1f039
WD
121 mtspr IVOR3,r1 /* 3: Instruction storage */
122 li r1,0x0500
123 mtspr IVOR4,r1 /* 4: External interrupt */
124 li r1,0x0600
125 mtspr IVOR5,r1 /* 5: Alignment */
126 li r1,0x0700
127 mtspr IVOR6,r1 /* 6: Program check */
128 li r1,0x0800
129 mtspr IVOR7,r1 /* 7: floating point unavailable */
343117bf 130 li r1,0x0900
42d1f039
WD
131 mtspr IVOR8,r1 /* 8: System call */
132 /* 9: Auxiliary processor unavailable(unsupported) */
343117bf 133 li r1,0x0a00
42d1f039 134 mtspr IVOR10,r1 /* 10: Decrementer */
343117bf
WD
135 li r1,0x0b00
136 mtspr IVOR11,r1 /* 11: Interval timer */
137 li r1,0x0c00
3e0bc447
WD
138 mtspr IVOR12,r1 /* 12: Watchdog timer */
139 li r1,0x0d00
42d1f039 140 mtspr IVOR13,r1 /* 13: Data TLB error */
343117bf 141 li r1,0x0e00
42d1f039 142 mtspr IVOR14,r1 /* 14: Instruction TLB error */
343117bf 143 li r1,0x0f00
42d1f039
WD
144 mtspr IVOR15,r1 /* 15: Debug */
145
42d1f039 146 /* Clear and set up some registers. */
87163180 147 li r0,0x0000
42d1f039
WD
148 lis r1,0xffff
149 mtspr DEC,r0 /* prevent dec exceptions */
150 mttbl r0 /* prevent fit & wdt exceptions */
151 mttbu r0
152 mtspr TSR,r1 /* clear all timer exception status */
153 mtspr TCR,r0 /* disable all */
154 mtspr ESR,r0 /* clear exception syndrome register */
155 mtspr MCSR,r0 /* machine check syndrome register */
156 mtxer r0 /* clear integer exception register */
42d1f039
WD
157
158 /* Enable Time Base and Select Time Base Clock */
0ac6f8b7 159 lis r0,HID0_EMCP@h /* Enable machine check */
d9b94f28 160#if defined(CONFIG_ENABLE_36BIT_PHYS)
87163180 161 ori r0,r0,HID0_ENMAS7@l /* Enable MAS7 */
d9b94f28 162#endif
87163180 163 ori r0,r0,HID0_TBEN@l /* Enable Timebase */
42d1f039 164 mtspr HID0,r0
42d1f039 165
61a21e98 166 li r0,(HID1_ASTME|HID1_ABE)@l /* Addr streaming & broadcast */
42d1f039 167 mtspr HID1,r0
42d1f039
WD
168
169 /* Enable Branch Prediction */
170#if defined(CONFIG_BTB)
171 li r0,0x201 /* BBFI = 1, BPEN = 1 */
172 mtspr BUCSR,r0
42d1f039
WD
173#endif
174
175#if defined(CFG_INIT_DBCR)
176 lis r1,0xffff
177 ori r1,r1,0xffff
0ac6f8b7 178 mtspr DBSR,r1 /* Clear all status bits */
42d1f039
WD
179 lis r0,CFG_INIT_DBCR@h /* DBCR0[IDM] must be set */
180 ori r0,r0,CFG_INIT_DBCR@l
0ac6f8b7 181 mtspr DBCR0,r0
42d1f039
WD
182#endif
183
87163180
KG
184 /* create a temp mapping in AS=1 to the boot window */
185 lis r6,FSL_BOOKE_MAS0(1, 15, 0)@h
186 ori r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l
187
188 lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16M)@h
189 ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16M)@l
190
191 lis r8,FSL_BOOKE_MAS2(TEXT_BASE, (MAS2_I|MAS2_G))@h
192 ori r8,r8,FSL_BOOKE_MAS2(TEXT_BASE, (MAS2_I|MAS2_G))@l
193
194 lis r9,FSL_BOOKE_MAS3(0xff800000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h
195 ori r9,r9,FSL_BOOKE_MAS3(0xff800000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l
196
197 mtspr MAS0,r6
198 mtspr MAS1,r7
199 mtspr MAS2,r8
200 mtspr MAS3,r9
201 isync
202 msync
203 tlbwe
204
205 /* create a temp mapping in AS=1 to the stack */
206 lis r6,FSL_BOOKE_MAS0(1, 14, 0)@h
207 ori r6,r6,FSL_BOOKE_MAS0(1, 14, 0)@l
208
209 lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16K)@h
210 ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16K)@l
211
212 lis r8,FSL_BOOKE_MAS2(CFG_INIT_RAM_ADDR, 0)@h
213 ori r8,r8,FSL_BOOKE_MAS2(CFG_INIT_RAM_ADDR, 0)@l
214
215 lis r9,FSL_BOOKE_MAS3(CFG_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h
216 ori r9,r9,FSL_BOOKE_MAS3(CFG_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l
217
218 mtspr MAS0,r6
219 mtspr MAS1,r7
220 mtspr MAS2,r8
221 mtspr MAS3,r9
222 isync
223 msync
224 tlbwe
225
226 lis r6,MSR_CE|MSR_ME|MSR_DE|MSR_IS|MSR_DS@h
227 ori r6,r6,MSR_CE|MSR_ME|MSR_DE|MSR_IS|MSR_DS@l
228 lis r7,switch_as@h
229 ori r7,r7,switch_as@l
230
231 mtspr SPRN_SRR0,r7
232 mtspr SPRN_SRR1,r6
233 rfi
234
235switch_as:
3db0bef5
KG
236/* L1 DCache is used for initial RAM */
237
238 /* Allocate Initial RAM in data cache.
239 */
240 lis r3,CFG_INIT_RAM_ADDR@h
241 ori r3,r3,CFG_INIT_RAM_ADDR@l
b009f3ec
KG
242 mfspr r2, L1CFG0
243 andi. r2, r2, 0x1ff
244 /* cache size * 1024 / (2 * L1 line size) */
245 slwi r2, r2, (10 - 1 - L1_CACHE_SHIFT)
3db0bef5
KG
246 mtctr r2
247 li r0,0
2481:
249 dcbz r0,r3
250 dcbtls 0,r0,r3
e1ce3cb6 251 addi r3,r3,CFG_CACHELINE_SIZE
3db0bef5
KG
252 bdnz 1b
253
61a21e98 254 /* Jump out the last 4K page and continue to 'normal' start */
3db0bef5 255#ifdef CFG_RAMBOOT
61a21e98 256 b _start_cont
3db0bef5
KG
257#else
258 /* Calculate absolute address in FLASH and jump there */
259 /*--------------------------------------------------------------*/
260 lis r3,CFG_MONITOR_BASE@h
261 ori r3,r3,CFG_MONITOR_BASE@l
262 addi r3,r3,_start_cont - _start + _START_OFFSET
263 mtlr r3
1e701e70 264 blr
3db0bef5 265#endif
61a21e98 266
61a21e98
AF
267 .text
268 .globl _start
269_start:
270 .long 0x27051956 /* U-BOOT Magic Number */
271 .globl version_string
272version_string:
273 .ascii U_BOOT_VERSION
274 .ascii " (", __DATE__, " - ", __TIME__, ")"
275 .ascii CONFIG_IDENT_STRING, "\0"
276
277 .align 4
278 .globl _start_cont
279_start_cont:
42d1f039
WD
280 /* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/
281 lis r1,CFG_INIT_RAM_ADDR@h
282 ori r1,r1,CFG_INIT_SP_OFFSET@l
283
284 li r0,0
285 stwu r0,-4(r1)
286 stwu r0,-4(r1) /* Terminate call chain */
287
288 stwu r1,-8(r1) /* Save back chain and move SP */
289 lis r0,RESET_VECTOR@h /* Address of reset vector */
61a21e98 290 ori r0,r0,RESET_VECTOR@l
42d1f039
WD
291 stwu r1,-8(r1) /* Save back chain and move SP */
292 stw r0,+12(r1) /* Save return addr (underflow vect) */
293
294 GET_GOT
87163180
KG
295 bl cpu_init_early_f
296
297 /* switch back to AS = 0 */
298 lis r3,(MSR_CE|MSR_ME|MSR_DE)@h
299 ori r3,r3,(MSR_CE|MSR_ME|MSR_DE)@l
300 mtmsr r3
301 isync
302
42d1f039 303 bl cpu_init_f
42d1f039 304 bl board_init_f
0ac6f8b7 305 isync
42d1f039 306
61a21e98 307 . = EXC_OFF_SYS_RESET
42d1f039
WD
308 .globl _start_of_vectors
309_start_of_vectors:
61a21e98 310
42d1f039 311/* Critical input. */
61a21e98
AF
312 CRIT_EXCEPTION(0x0100, CriticalInput, CritcalInputException)
313
314/* Machine check */
315 MCK_EXCEPTION(0x200, MachineCheck, MachineCheckException)
42d1f039
WD
316
317/* Data Storage exception. */
318 STD_EXCEPTION(0x0300, DataStorage, UnknownException)
319
320/* Instruction Storage exception. */
321 STD_EXCEPTION(0x0400, InstStorage, UnknownException)
322
323/* External Interrupt exception. */
61a21e98 324 STD_EXCEPTION(0x0500, ExtInterrupt, ExtIntException)
42d1f039
WD
325
326/* Alignment exception. */
327 . = 0x0600
328Alignment:
02032e8f 329 EXCEPTION_PROLOG(SRR0, SRR1)
42d1f039
WD
330 mfspr r4,DAR
331 stw r4,_DAR(r21)
332 mfspr r5,DSISR
333 stw r5,_DSISR(r21)
334 addi r3,r1,STACK_FRAME_OVERHEAD
335 li r20,MSR_KERNEL
336 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
337 lwz r6,GOT(transfer_to_handler)
338 mtlr r6
339 blrl
340.L_Alignment:
61a21e98
AF
341 .long AlignmentException - _start + _START_OFFSET
342 .long int_return - _start + _START_OFFSET
42d1f039
WD
343
344/* Program check exception */
345 . = 0x0700
346ProgramCheck:
02032e8f 347 EXCEPTION_PROLOG(SRR0, SRR1)
42d1f039
WD
348 addi r3,r1,STACK_FRAME_OVERHEAD
349 li r20,MSR_KERNEL
350 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
351 lwz r6,GOT(transfer_to_handler)
352 mtlr r6
353 blrl
354.L_ProgramCheck:
61a21e98
AF
355 .long ProgramCheckException - _start + _START_OFFSET
356 .long int_return - _start + _START_OFFSET
42d1f039
WD
357
358 /* No FPU on MPC85xx. This exception is not supposed to happen.
359 */
360 STD_EXCEPTION(0x0800, FPUnavailable, UnknownException)
42d1f039 361
343117bf 362 . = 0x0900
42d1f039
WD
363/*
364 * r0 - SYSCALL number
365 * r3-... arguments
366 */
367SystemCall:
61a21e98
AF
368 addis r11,r0,0 /* get functions table addr */
369 ori r11,r11,0 /* Note: this code is patched in trap_init */
370 addis r12,r0,0 /* get number of functions */
343117bf
WD
371 ori r12,r12,0
372
61a21e98 373 cmplw 0,r0,r12
343117bf
WD
374 bge 1f
375
61a21e98 376 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */
343117bf
WD
377 add r11,r11,r0
378 lwz r11,0(r11)
379
61a21e98 380 li r20,0xd00-4 /* Get stack pointer */
343117bf 381 lwz r12,0(r20)
61a21e98 382 subi r12,r12,12 /* Adjust stack pointer */
343117bf 383 li r0,0xc00+_end_back-SystemCall
61a21e98 384 cmplw 0,r0,r12 /* Check stack overflow */
343117bf
WD
385 bgt 1f
386 stw r12,0(r20)
387
388 mflr r0
389 stw r0,0(r12)
390 mfspr r0,SRR0
391 stw r0,4(r12)
392 mfspr r0,SRR1
393 stw r0,8(r12)
394
395 li r12,0xc00+_back-SystemCall
396 mtlr r12
397 mtspr SRR0,r11
398
3991: SYNC
42d1f039
WD
400 rfi
401_back:
402
343117bf
WD
403 mfmsr r11 /* Disable interrupts */
404 li r12,0
405 ori r12,r12,MSR_EE
406 andc r11,r11,r12
407 SYNC /* Some chip revs need this... */
408 mtmsr r11
42d1f039
WD
409 SYNC
410
343117bf
WD
411 li r12,0xd00-4 /* restore regs */
412 lwz r12,0(r12)
42d1f039 413
343117bf
WD
414 lwz r11,0(r12)
415 mtlr r11
416 lwz r11,4(r12)
417 mtspr SRR0,r11
418 lwz r11,8(r12)
419 mtspr SRR1,r11
42d1f039 420
343117bf
WD
421 addi r12,r12,12 /* Adjust stack pointer */
422 li r20,0xd00-4
423 stw r12,0(r20)
42d1f039
WD
424
425 SYNC
426 rfi
427_end_back:
428
343117bf
WD
429 STD_EXCEPTION(0x0a00, Decrementer, timer_interrupt)
430 STD_EXCEPTION(0x0b00, IntervalTimer, UnknownException)
431 STD_EXCEPTION(0x0c00, WatchdogTimer, UnknownException)
42d1f039 432
343117bf
WD
433 STD_EXCEPTION(0x0d00, DataTLBError, UnknownException)
434 STD_EXCEPTION(0x0e00, InstructionTLBError, UnknownException)
42d1f039 435
343117bf 436 CRIT_EXCEPTION(0x0f00, DebugBreakpoint, DebugException )
42d1f039 437
343117bf 438 .globl _end_of_vectors
42d1f039
WD
439_end_of_vectors:
440
441
61a21e98 442 . = . + (0x100 - ( . & 0xff )) /* align for debug */
42d1f039
WD
443
444/*
445 * This code finishes saving the registers to the exception frame
446 * and jumps to the appropriate handler for the exception.
447 * Register r21 is pointer into trap frame, r1 has new stack pointer.
448 */
449 .globl transfer_to_handler
450transfer_to_handler:
451 stw r22,_NIP(r21)
452 lis r22,MSR_POW@h
453 andc r23,r23,r22
454 stw r23,_MSR(r21)
455 SAVE_GPR(7, r21)
456 SAVE_4GPRS(8, r21)
457 SAVE_8GPRS(12, r21)
458 SAVE_8GPRS(24, r21)
459
460 mflr r23
461 andi. r24,r23,0x3f00 /* get vector offset */
462 stw r24,TRAP(r21)
463 li r22,0
464 stw r22,RESULT(r21)
465 mtspr SPRG2,r22 /* r1 is now kernel sp */
466
467 lwz r24,0(r23) /* virtual address of handler */
468 lwz r23,4(r23) /* where to go when done */
469 mtspr SRR0,r24
470 mtspr SRR1,r20
471 mtlr r23
472 SYNC
473 rfi /* jump to handler, enable MMU */
474
475int_return:
476 mfmsr r28 /* Disable interrupts */
477 li r4,0
478 ori r4,r4,MSR_EE
479 andc r28,r28,r4
480 SYNC /* Some chip revs need this... */
481 mtmsr r28
482 SYNC
483 lwz r2,_CTR(r1)
484 lwz r0,_LINK(r1)
485 mtctr r2
486 mtlr r0
487 lwz r2,_XER(r1)
488 lwz r0,_CCR(r1)
489 mtspr XER,r2
490 mtcrf 0xFF,r0
491 REST_10GPRS(3, r1)
492 REST_10GPRS(13, r1)
493 REST_8GPRS(23, r1)
494 REST_GPR(31, r1)
495 lwz r2,_NIP(r1) /* Restore environment */
496 lwz r0,_MSR(r1)
497 mtspr SRR0,r2
498 mtspr SRR1,r0
499 lwz r0,GPR0(r1)
500 lwz r2,GPR2(r1)
501 lwz r1,GPR1(r1)
502 SYNC
503 rfi
504
505crit_return:
506 mfmsr r28 /* Disable interrupts */
507 li r4,0
508 ori r4,r4,MSR_EE
509 andc r28,r28,r4
510 SYNC /* Some chip revs need this... */
511 mtmsr r28
512 SYNC
513 lwz r2,_CTR(r1)
514 lwz r0,_LINK(r1)
515 mtctr r2
516 mtlr r0
517 lwz r2,_XER(r1)
518 lwz r0,_CCR(r1)
519 mtspr XER,r2
520 mtcrf 0xFF,r0
521 REST_10GPRS(3, r1)
522 REST_10GPRS(13, r1)
523 REST_8GPRS(23, r1)
524 REST_GPR(31, r1)
525 lwz r2,_NIP(r1) /* Restore environment */
526 lwz r0,_MSR(r1)
61a21e98
AF
527 mtspr SPRN_CSRR0,r2
528 mtspr SPRN_CSRR1,r0
42d1f039
WD
529 lwz r0,GPR0(r1)
530 lwz r2,GPR2(r1)
531 lwz r1,GPR1(r1)
532 SYNC
533 rfci
534
61a21e98
AF
535mck_return:
536 mfmsr r28 /* Disable interrupts */
537 li r4,0
538 ori r4,r4,MSR_EE
539 andc r28,r28,r4
540 SYNC /* Some chip revs need this... */
541 mtmsr r28
542 SYNC
543 lwz r2,_CTR(r1)
544 lwz r0,_LINK(r1)
545 mtctr r2
546 mtlr r0
547 lwz r2,_XER(r1)
548 lwz r0,_CCR(r1)
549 mtspr XER,r2
550 mtcrf 0xFF,r0
551 REST_10GPRS(3, r1)
552 REST_10GPRS(13, r1)
553 REST_8GPRS(23, r1)
554 REST_GPR(31, r1)
555 lwz r2,_NIP(r1) /* Restore environment */
556 lwz r0,_MSR(r1)
557 mtspr SPRN_MCSRR0,r2
558 mtspr SPRN_MCSRR1,r0
559 lwz r0,GPR0(r1)
560 lwz r2,GPR2(r1)
561 lwz r1,GPR1(r1)
562 SYNC
563 rfmci
564
42d1f039
WD
565/* Cache functions.
566*/
567invalidate_icache:
568 mfspr r0,L1CSR1
61a21e98
AF
569 ori r0,r0,L1CSR1_ICFI
570 msync
571 isync
42d1f039
WD
572 mtspr L1CSR1,r0
573 isync
61a21e98 574 blr /* entire I cache */
42d1f039
WD
575
576invalidate_dcache:
577 mfspr r0,L1CSR0
61a21e98 578 ori r0,r0,L1CSR0_DCFI
42d1f039
WD
579 msync
580 isync
581 mtspr L1CSR0,r0
582 isync
583 blr
584
585 .globl icache_enable
586icache_enable:
587 mflr r8
588 bl invalidate_icache
589 mtlr r8
590 isync
591 mfspr r4,L1CSR1
592 ori r4,r4,0x0001
593 oris r4,r4,0x0001
594 mtspr L1CSR1,r4
595 isync
596 blr
597
598 .globl icache_disable
599icache_disable:
600 mfspr r0,L1CSR1
61a21e98
AF
601 lis r3,0
602 ori r3,r3,L1CSR1_ICE
603 andc r0,r0,r3
42d1f039
WD
604 mtspr L1CSR1,r0
605 isync
606 blr
607
608 .globl icache_status
609icache_status:
610 mfspr r3,L1CSR1
61a21e98 611 andi. r3,r3,L1CSR1_ICE
42d1f039
WD
612 blr
613
614 .globl dcache_enable
615dcache_enable:
616 mflr r8
617 bl invalidate_dcache
618 mtlr r8
619 isync
620 mfspr r0,L1CSR0
621 ori r0,r0,0x0001
622 oris r0,r0,0x0001
623 msync
624 isync
625 mtspr L1CSR0,r0
626 isync
627 blr
628
629 .globl dcache_disable
630dcache_disable:
61a21e98
AF
631 mfspr r3,L1CSR0
632 lis r4,0
633 ori r4,r4,L1CSR0_DCE
634 andc r3,r3,r4
42d1f039
WD
635 mtspr L1CSR0,r0
636 isync
637 blr
638
639 .globl dcache_status
640dcache_status:
641 mfspr r3,L1CSR0
61a21e98 642 andi. r3,r3,L1CSR0_DCE
42d1f039
WD
643 blr
644
645 .globl get_pir
646get_pir:
61a21e98 647 mfspr r3,PIR
42d1f039
WD
648 blr
649
650 .globl get_pvr
651get_pvr:
61a21e98 652 mfspr r3,PVR
42d1f039
WD
653 blr
654
97d80fc3
WD
655 .globl get_svr
656get_svr:
61a21e98 657 mfspr r3,SVR
97d80fc3
WD
658 blr
659
42d1f039
WD
660 .globl wr_tcr
661wr_tcr:
61a21e98 662 mtspr TCR,r3
42d1f039
WD
663 blr
664
665/*------------------------------------------------------------------------------- */
666/* Function: in8 */
667/* Description: Input 8 bits */
668/*------------------------------------------------------------------------------- */
669 .globl in8
670in8:
671 lbz r3,0x0000(r3)
672 blr
673
674/*------------------------------------------------------------------------------- */
675/* Function: out8 */
676/* Description: Output 8 bits */
677/*------------------------------------------------------------------------------- */
678 .globl out8
679out8:
680 stb r4,0x0000(r3)
1487adbd 681 sync
42d1f039
WD
682 blr
683
684/*------------------------------------------------------------------------------- */
685/* Function: out16 */
686/* Description: Output 16 bits */
687/*------------------------------------------------------------------------------- */
688 .globl out16
689out16:
690 sth r4,0x0000(r3)
1487adbd 691 sync
42d1f039
WD
692 blr
693
694/*------------------------------------------------------------------------------- */
695/* Function: out16r */
696/* Description: Byte reverse and output 16 bits */
697/*------------------------------------------------------------------------------- */
698 .globl out16r
699out16r:
700 sthbrx r4,r0,r3
1487adbd 701 sync
42d1f039
WD
702 blr
703
704/*------------------------------------------------------------------------------- */
705/* Function: out32 */
706/* Description: Output 32 bits */
707/*------------------------------------------------------------------------------- */
708 .globl out32
709out32:
710 stw r4,0x0000(r3)
1487adbd 711 sync
42d1f039
WD
712 blr
713
714/*------------------------------------------------------------------------------- */
715/* Function: out32r */
716/* Description: Byte reverse and output 32 bits */
717/*------------------------------------------------------------------------------- */
718 .globl out32r
719out32r:
720 stwbrx r4,r0,r3
1487adbd 721 sync
42d1f039
WD
722 blr
723
724/*------------------------------------------------------------------------------- */
725/* Function: in16 */
726/* Description: Input 16 bits */
727/*------------------------------------------------------------------------------- */
728 .globl in16
729in16:
730 lhz r3,0x0000(r3)
731 blr
732
733/*------------------------------------------------------------------------------- */
734/* Function: in16r */
735/* Description: Input 16 bits and byte reverse */
736/*------------------------------------------------------------------------------- */
737 .globl in16r
738in16r:
739 lhbrx r3,r0,r3
740 blr
741
742/*------------------------------------------------------------------------------- */
743/* Function: in32 */
744/* Description: Input 32 bits */
745/*------------------------------------------------------------------------------- */
746 .globl in32
747in32:
748 lwz 3,0x0000(3)
749 blr
750
751/*------------------------------------------------------------------------------- */
752/* Function: in32r */
753/* Description: Input 32 bits and byte reverse */
754/*------------------------------------------------------------------------------- */
755 .globl in32r
756in32r:
757 lwbrx r3,r0,r3
758 blr
759
42d1f039
WD
760/*------------------------------------------------------------------------------*/
761
762/*
763 * void relocate_code (addr_sp, gd, addr_moni)
764 *
765 * This "function" does not return, instead it continues in RAM
766 * after relocating the monitor code.
767 *
768 * r3 = dest
769 * r4 = src
770 * r5 = length in bytes
771 * r6 = cachelinesize
772 */
773 .globl relocate_code
774relocate_code:
61a21e98
AF
775 mr r1,r3 /* Set new stack pointer */
776 mr r9,r4 /* Save copy of Init Data pointer */
777 mr r10,r5 /* Save copy of Destination Address */
42d1f039 778
61a21e98
AF
779 mr r3,r5 /* Destination Address */
780 lis r4,CFG_MONITOR_BASE@h /* Source Address */
781 ori r4,r4,CFG_MONITOR_BASE@l
42d1f039
WD
782 lwz r5,GOT(__init_end)
783 sub r5,r5,r4
61a21e98 784 li r6,CFG_CACHELINE_SIZE /* Cache Line Size */
42d1f039
WD
785
786 /*
787 * Fix GOT pointer:
788 *
789 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
790 *
791 * Offset:
792 */
61a21e98 793 sub r15,r10,r4
42d1f039
WD
794
795 /* First our own GOT */
61a21e98 796 add r14,r14,r15
42d1f039 797 /* the the one used by the C code */
61a21e98 798 add r30,r30,r15
42d1f039
WD
799
800 /*
801 * Now relocate code
802 */
803
804 cmplw cr1,r3,r4
805 addi r0,r5,3
806 srwi. r0,r0,2
807 beq cr1,4f /* In place copy is not necessary */
808 beq 7f /* Protect against 0 count */
809 mtctr r0
810 bge cr1,2f
811
812 la r8,-4(r4)
813 la r7,-4(r3)
8141: lwzu r0,4(r8)
815 stwu r0,4(r7)
816 bdnz 1b
817 b 4f
818
8192: slwi r0,r0,2
820 add r8,r4,r0
821 add r7,r3,r0
8223: lwzu r0,-4(r8)
823 stwu r0,-4(r7)
824 bdnz 3b
825
826/*
827 * Now flush the cache: note that we must start from a cache aligned
828 * address. Otherwise we might miss one cache line.
829 */
8304: cmpwi r6,0
831 add r5,r3,r5
832 beq 7f /* Always flush prefetch queue in any case */
833 subi r0,r6,1
834 andc r3,r3,r0
835 mr r4,r3
8365: dcbst 0,r4
837 add r4,r4,r6
838 cmplw r4,r5
839 blt 5b
840 sync /* Wait for all dcbst to complete on bus */
841 mr r4,r3
8426: icbi 0,r4
843 add r4,r4,r6
844 cmplw r4,r5
845 blt 6b
8467: sync /* Wait for all icbi to complete on bus */
847 isync
848
7d314992
WD
849 /*
850 * Re-point the IVPR at RAM
851 */
852 mtspr IVPR,r10
99b0d285 853
42d1f039
WD
854/*
855 * We are done. Do not return, instead branch to second part of board
856 * initialization, now running from RAM.
857 */
858
61a21e98 859 addi r0,r10,in_ram - _start + _START_OFFSET
42d1f039
WD
860 mtlr r0
861 blr /* NEVER RETURNS! */
61a21e98 862 .globl in_ram
42d1f039
WD
863in_ram:
864
865 /*
866 * Relocation Function, r14 point to got2+0x8000
867 *
868 * Adjust got2 pointers, no need to check for 0, this code
869 * already puts a few entries in the table.
870 */
871 li r0,__got2_entries@sectoff@l
872 la r3,GOT(_GOT2_TABLE_)
873 lwz r11,GOT(_GOT2_TABLE_)
874 mtctr r0
875 sub r11,r3,r11
876 addi r3,r3,-4
8771: lwzu r0,4(r3)
878 add r0,r0,r11
879 stw r0,0(r3)
880 bdnz 1b
881
882 /*
883 * Now adjust the fixups and the pointers to the fixups
884 * in case we need to move ourselves again.
885 */
8862: li r0,__fixup_entries@sectoff@l
887 lwz r3,GOT(_FIXUP_TABLE_)
888 cmpwi r0,0
889 mtctr r0
890 addi r3,r3,-4
891 beq 4f
8923: lwzu r4,4(r3)
893 lwzux r0,r4,r11
894 add r0,r0,r11
895 stw r10,0(r3)
896 stw r0,0(r4)
897 bdnz 3b
8984:
899clear_bss:
900 /*
901 * Now clear BSS segment
902 */
903 lwz r3,GOT(__bss_start)
904 lwz r4,GOT(_end)
905
61a21e98 906 cmplw 0,r3,r4
42d1f039
WD
907 beq 6f
908
61a21e98 909 li r0,0
42d1f039 9105:
61a21e98
AF
911 stw r0,0(r3)
912 addi r3,r3,4
913 cmplw 0,r3,r4
42d1f039
WD
914 bne 5b
9156:
916
61a21e98
AF
917 mr r3,r9 /* Init Data pointer */
918 mr r4,r10 /* Destination Address */
42d1f039
WD
919 bl board_init_r
920
921 /*
922 * Copy exception vector code to low memory
923 *
924 * r3: dest_addr
925 * r7: source address, r8: end address, r9: target address
926 */
343117bf 927 .globl trap_init
42d1f039 928trap_init:
61a21e98
AF
929 lwz r7,GOT(_start_of_vectors)
930 lwz r8,GOT(_end_of_vectors)
42d1f039 931
61a21e98 932 li r9,0x100 /* reset vector always at 0x100 */
42d1f039 933
61a21e98 934 cmplw 0,r7,r8
343117bf 935 bgelr /* return if r7>=r8 - just in case */
42d1f039 936
343117bf 937 mflr r4 /* save link register */
42d1f039 9381:
61a21e98
AF
939 lwz r0,0(r7)
940 stw r0,0(r9)
941 addi r7,r7,4
942 addi r9,r9,4
943 cmplw 0,r7,r8
343117bf 944 bne 1b
42d1f039
WD
945
946 /*
947 * relocate `hdlr' and `int_return' entries
948 */
61a21e98 949 li r7,.L_CriticalInput - _start + _START_OFFSET
343117bf 950 bl trap_reloc
61a21e98 951 li r7,.L_MachineCheck - _start + _START_OFFSET
343117bf 952 bl trap_reloc
61a21e98 953 li r7,.L_DataStorage - _start + _START_OFFSET
343117bf 954 bl trap_reloc
61a21e98 955 li r7,.L_InstStorage - _start + _START_OFFSET
343117bf 956 bl trap_reloc
61a21e98 957 li r7,.L_ExtInterrupt - _start + _START_OFFSET
343117bf 958 bl trap_reloc
61a21e98 959 li r7,.L_Alignment - _start + _START_OFFSET
343117bf 960 bl trap_reloc
61a21e98 961 li r7,.L_ProgramCheck - _start + _START_OFFSET
343117bf 962 bl trap_reloc
61a21e98 963 li r7,.L_FPUnavailable - _start + _START_OFFSET
343117bf 964 bl trap_reloc
61a21e98
AF
965 li r7,.L_Decrementer - _start + _START_OFFSET
966 bl trap_reloc
967 li r7,.L_IntervalTimer - _start + _START_OFFSET
968 li r8,_end_of_vectors - _start + _START_OFFSET
42d1f039 9692:
343117bf 970 bl trap_reloc
61a21e98
AF
971 addi r7,r7,0x100 /* next exception vector */
972 cmplw 0,r7,r8
343117bf
WD
973 blt 2b
974
975 lis r7,0x0
61a21e98 976 mtspr IVPR,r7
42d1f039 977
343117bf 978 mtlr r4 /* restore link register */
42d1f039
WD
979 blr
980
981 /*
982 * Function: relocate entries for one exception vector
983 */
984trap_reloc:
61a21e98
AF
985 lwz r0,0(r7) /* hdlr ... */
986 add r0,r0,r3 /* ... += dest_addr */
987 stw r0,0(r7)
42d1f039 988
61a21e98
AF
989 lwz r0,4(r7) /* int_return ... */
990 add r0,r0,r3 /* ... += dest_addr */
991 stw r0,4(r7)
42d1f039
WD
992
993 blr
994
42d1f039
WD
995.globl unlock_ram_in_cache
996unlock_ram_in_cache:
997 /* invalidate the INIT_RAM section */
61a21e98
AF
998 lis r3,(CFG_INIT_RAM_ADDR & ~31)@h
999 ori r3,r3,(CFG_INIT_RAM_ADDR & ~31)@l
b009f3ec
KG
1000 mfspr r4,L1CFG0
1001 andi. r4,r4,0x1ff
1002 slwi r4,r4,(10 - 1 - L1_CACHE_SHIFT)
61a21e98 1003 mtctr r4
2b22fa4b 10041: dcbi r0,r3
e1ce3cb6 1005 addi r3,r3,CFG_CACHELINE_SIZE
42d1f039 1006 bdnz 1b
2b22fa4b 1007 sync
21fae8b2
AF
1008
1009 /* Invalidate the TLB entries for the cache */
1010 lis r3,CFG_INIT_RAM_ADDR@h
1011 ori r3,r3,CFG_INIT_RAM_ADDR@l
1012 tlbivax 0,r3
1013 addi r3,r3,0x1000
1014 tlbivax 0,r3
1015 addi r3,r3,0x1000
1016 tlbivax 0,r3
1017 addi r3,r3,0x1000
1018 tlbivax 0,r3
42d1f039
WD
1019 isync
1020 blr