]> git.ipfire.org Git - people/ms/u-boot.git/blame - cpu/mpc85xx/start.S
rename CFG_ macros to CONFIG_SYS
[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
6d0f6bcf 175#if defined(CONFIG_SYS_INIT_DBCR)
42d1f039
WD
176 lis r1,0xffff
177 ori r1,r1,0xffff
0ac6f8b7 178 mtspr DBSR,r1 /* Clear all status bits */
6d0f6bcf
JCPV
179 lis r0,CONFIG_SYS_INIT_DBCR@h /* DBCR0[IDM] must be set */
180 ori r0,r0,CONFIG_SYS_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
24ef76f3
AK
191 /* Align the mapping to 16MB */
192 lis r8,FSL_BOOKE_MAS2(TEXT_BASE & 0xff000000, (MAS2_I|MAS2_G))@h
193 ori r8,r8,FSL_BOOKE_MAS2(TEXT_BASE & 0xff000000, (MAS2_I|MAS2_G))@l
87163180 194
24ef76f3
AK
195 lis r9,FSL_BOOKE_MAS3(0xff000000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h
196 ori r9,r9,FSL_BOOKE_MAS3(0xff000000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l
87163180
KG
197
198 mtspr MAS0,r6
199 mtspr MAS1,r7
200 mtspr MAS2,r8
201 mtspr MAS3,r9
202 isync
203 msync
204 tlbwe
205
206 /* create a temp mapping in AS=1 to the stack */
207 lis r6,FSL_BOOKE_MAS0(1, 14, 0)@h
208 ori r6,r6,FSL_BOOKE_MAS0(1, 14, 0)@l
209
210 lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16K)@h
211 ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16K)@l
212
6d0f6bcf
JCPV
213 lis r8,FSL_BOOKE_MAS2(CONFIG_SYS_INIT_RAM_ADDR, 0)@h
214 ori r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_INIT_RAM_ADDR, 0)@l
87163180 215
6d0f6bcf
JCPV
216 lis r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h
217 ori r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l
87163180
KG
218
219 mtspr MAS0,r6
220 mtspr MAS1,r7
221 mtspr MAS2,r8
222 mtspr MAS3,r9
223 isync
224 msync
225 tlbwe
226
227 lis r6,MSR_CE|MSR_ME|MSR_DE|MSR_IS|MSR_DS@h
228 ori r6,r6,MSR_CE|MSR_ME|MSR_DE|MSR_IS|MSR_DS@l
229 lis r7,switch_as@h
230 ori r7,r7,switch_as@l
231
232 mtspr SPRN_SRR0,r7
233 mtspr SPRN_SRR1,r6
234 rfi
235
236switch_as:
3db0bef5
KG
237/* L1 DCache is used for initial RAM */
238
239 /* Allocate Initial RAM in data cache.
240 */
6d0f6bcf
JCPV
241 lis r3,CONFIG_SYS_INIT_RAM_ADDR@h
242 ori r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l
b009f3ec
KG
243 mfspr r2, L1CFG0
244 andi. r2, r2, 0x1ff
245 /* cache size * 1024 / (2 * L1 line size) */
246 slwi r2, r2, (10 - 1 - L1_CACHE_SHIFT)
3db0bef5
KG
247 mtctr r2
248 li r0,0
2491:
250 dcbz r0,r3
251 dcbtls 0,r0,r3
6d0f6bcf 252 addi r3,r3,CONFIG_SYS_CACHELINE_SIZE
3db0bef5
KG
253 bdnz 1b
254
61a21e98 255 /* Jump out the last 4K page and continue to 'normal' start */
6d0f6bcf 256#ifdef CONFIG_SYS_RAMBOOT
61a21e98 257 b _start_cont
3db0bef5
KG
258#else
259 /* Calculate absolute address in FLASH and jump there */
260 /*--------------------------------------------------------------*/
6d0f6bcf
JCPV
261 lis r3,CONFIG_SYS_MONITOR_BASE@h
262 ori r3,r3,CONFIG_SYS_MONITOR_BASE@l
3db0bef5
KG
263 addi r3,r3,_start_cont - _start + _START_OFFSET
264 mtlr r3
1e701e70 265 blr
3db0bef5 266#endif
61a21e98 267
61a21e98
AF
268 .text
269 .globl _start
270_start:
271 .long 0x27051956 /* U-BOOT Magic Number */
272 .globl version_string
273version_string:
274 .ascii U_BOOT_VERSION
275 .ascii " (", __DATE__, " - ", __TIME__, ")"
276 .ascii CONFIG_IDENT_STRING, "\0"
277
278 .align 4
279 .globl _start_cont
280_start_cont:
42d1f039 281 /* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/
6d0f6bcf
JCPV
282 lis r1,CONFIG_SYS_INIT_RAM_ADDR@h
283 ori r1,r1,CONFIG_SYS_INIT_SP_OFFSET@l
42d1f039
WD
284
285 li r0,0
286 stwu r0,-4(r1)
287 stwu r0,-4(r1) /* Terminate call chain */
288
289 stwu r1,-8(r1) /* Save back chain and move SP */
290 lis r0,RESET_VECTOR@h /* Address of reset vector */
61a21e98 291 ori r0,r0,RESET_VECTOR@l
42d1f039
WD
292 stwu r1,-8(r1) /* Save back chain and move SP */
293 stw r0,+12(r1) /* Save return addr (underflow vect) */
294
295 GET_GOT
87163180
KG
296 bl cpu_init_early_f
297
298 /* switch back to AS = 0 */
299 lis r3,(MSR_CE|MSR_ME|MSR_DE)@h
300 ori r3,r3,(MSR_CE|MSR_ME|MSR_DE)@l
301 mtmsr r3
302 isync
303
42d1f039 304 bl cpu_init_f
42d1f039 305 bl board_init_f
0ac6f8b7 306 isync
42d1f039 307
61a21e98 308 . = EXC_OFF_SYS_RESET
42d1f039
WD
309 .globl _start_of_vectors
310_start_of_vectors:
61a21e98 311
42d1f039 312/* Critical input. */
61a21e98
AF
313 CRIT_EXCEPTION(0x0100, CriticalInput, CritcalInputException)
314
315/* Machine check */
316 MCK_EXCEPTION(0x200, MachineCheck, MachineCheckException)
42d1f039
WD
317
318/* Data Storage exception. */
319 STD_EXCEPTION(0x0300, DataStorage, UnknownException)
320
321/* Instruction Storage exception. */
322 STD_EXCEPTION(0x0400, InstStorage, UnknownException)
323
324/* External Interrupt exception. */
61a21e98 325 STD_EXCEPTION(0x0500, ExtInterrupt, ExtIntException)
42d1f039
WD
326
327/* Alignment exception. */
328 . = 0x0600
329Alignment:
02032e8f 330 EXCEPTION_PROLOG(SRR0, SRR1)
42d1f039
WD
331 mfspr r4,DAR
332 stw r4,_DAR(r21)
333 mfspr r5,DSISR
334 stw r5,_DSISR(r21)
335 addi r3,r1,STACK_FRAME_OVERHEAD
336 li r20,MSR_KERNEL
337 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
338 lwz r6,GOT(transfer_to_handler)
339 mtlr r6
340 blrl
341.L_Alignment:
61a21e98
AF
342 .long AlignmentException - _start + _START_OFFSET
343 .long int_return - _start + _START_OFFSET
42d1f039
WD
344
345/* Program check exception */
346 . = 0x0700
347ProgramCheck:
02032e8f 348 EXCEPTION_PROLOG(SRR0, SRR1)
42d1f039
WD
349 addi r3,r1,STACK_FRAME_OVERHEAD
350 li r20,MSR_KERNEL
351 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
352 lwz r6,GOT(transfer_to_handler)
353 mtlr r6
354 blrl
355.L_ProgramCheck:
61a21e98
AF
356 .long ProgramCheckException - _start + _START_OFFSET
357 .long int_return - _start + _START_OFFSET
42d1f039
WD
358
359 /* No FPU on MPC85xx. This exception is not supposed to happen.
360 */
361 STD_EXCEPTION(0x0800, FPUnavailable, UnknownException)
42d1f039 362
343117bf 363 . = 0x0900
42d1f039
WD
364/*
365 * r0 - SYSCALL number
366 * r3-... arguments
367 */
368SystemCall:
61a21e98
AF
369 addis r11,r0,0 /* get functions table addr */
370 ori r11,r11,0 /* Note: this code is patched in trap_init */
371 addis r12,r0,0 /* get number of functions */
343117bf
WD
372 ori r12,r12,0
373
61a21e98 374 cmplw 0,r0,r12
343117bf
WD
375 bge 1f
376
61a21e98 377 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */
343117bf
WD
378 add r11,r11,r0
379 lwz r11,0(r11)
380
61a21e98 381 li r20,0xd00-4 /* Get stack pointer */
343117bf 382 lwz r12,0(r20)
61a21e98 383 subi r12,r12,12 /* Adjust stack pointer */
343117bf 384 li r0,0xc00+_end_back-SystemCall
61a21e98 385 cmplw 0,r0,r12 /* Check stack overflow */
343117bf
WD
386 bgt 1f
387 stw r12,0(r20)
388
389 mflr r0
390 stw r0,0(r12)
391 mfspr r0,SRR0
392 stw r0,4(r12)
393 mfspr r0,SRR1
394 stw r0,8(r12)
395
396 li r12,0xc00+_back-SystemCall
397 mtlr r12
398 mtspr SRR0,r11
399
4001: SYNC
42d1f039
WD
401 rfi
402_back:
403
343117bf
WD
404 mfmsr r11 /* Disable interrupts */
405 li r12,0
406 ori r12,r12,MSR_EE
407 andc r11,r11,r12
408 SYNC /* Some chip revs need this... */
409 mtmsr r11
42d1f039
WD
410 SYNC
411
343117bf
WD
412 li r12,0xd00-4 /* restore regs */
413 lwz r12,0(r12)
42d1f039 414
343117bf
WD
415 lwz r11,0(r12)
416 mtlr r11
417 lwz r11,4(r12)
418 mtspr SRR0,r11
419 lwz r11,8(r12)
420 mtspr SRR1,r11
42d1f039 421
343117bf
WD
422 addi r12,r12,12 /* Adjust stack pointer */
423 li r20,0xd00-4
424 stw r12,0(r20)
42d1f039
WD
425
426 SYNC
427 rfi
428_end_back:
429
343117bf
WD
430 STD_EXCEPTION(0x0a00, Decrementer, timer_interrupt)
431 STD_EXCEPTION(0x0b00, IntervalTimer, UnknownException)
432 STD_EXCEPTION(0x0c00, WatchdogTimer, UnknownException)
42d1f039 433
343117bf
WD
434 STD_EXCEPTION(0x0d00, DataTLBError, UnknownException)
435 STD_EXCEPTION(0x0e00, InstructionTLBError, UnknownException)
42d1f039 436
343117bf 437 CRIT_EXCEPTION(0x0f00, DebugBreakpoint, DebugException )
42d1f039 438
343117bf 439 .globl _end_of_vectors
42d1f039
WD
440_end_of_vectors:
441
442
61a21e98 443 . = . + (0x100 - ( . & 0xff )) /* align for debug */
42d1f039
WD
444
445/*
446 * This code finishes saving the registers to the exception frame
447 * and jumps to the appropriate handler for the exception.
448 * Register r21 is pointer into trap frame, r1 has new stack pointer.
449 */
450 .globl transfer_to_handler
451transfer_to_handler:
452 stw r22,_NIP(r21)
453 lis r22,MSR_POW@h
454 andc r23,r23,r22
455 stw r23,_MSR(r21)
456 SAVE_GPR(7, r21)
457 SAVE_4GPRS(8, r21)
458 SAVE_8GPRS(12, r21)
459 SAVE_8GPRS(24, r21)
460
461 mflr r23
462 andi. r24,r23,0x3f00 /* get vector offset */
463 stw r24,TRAP(r21)
464 li r22,0
465 stw r22,RESULT(r21)
466 mtspr SPRG2,r22 /* r1 is now kernel sp */
467
468 lwz r24,0(r23) /* virtual address of handler */
469 lwz r23,4(r23) /* where to go when done */
470 mtspr SRR0,r24
471 mtspr SRR1,r20
472 mtlr r23
473 SYNC
474 rfi /* jump to handler, enable MMU */
475
476int_return:
477 mfmsr r28 /* Disable interrupts */
478 li r4,0
479 ori r4,r4,MSR_EE
480 andc r28,r28,r4
481 SYNC /* Some chip revs need this... */
482 mtmsr r28
483 SYNC
484 lwz r2,_CTR(r1)
485 lwz r0,_LINK(r1)
486 mtctr r2
487 mtlr r0
488 lwz r2,_XER(r1)
489 lwz r0,_CCR(r1)
490 mtspr XER,r2
491 mtcrf 0xFF,r0
492 REST_10GPRS(3, r1)
493 REST_10GPRS(13, r1)
494 REST_8GPRS(23, r1)
495 REST_GPR(31, r1)
496 lwz r2,_NIP(r1) /* Restore environment */
497 lwz r0,_MSR(r1)
498 mtspr SRR0,r2
499 mtspr SRR1,r0
500 lwz r0,GPR0(r1)
501 lwz r2,GPR2(r1)
502 lwz r1,GPR1(r1)
503 SYNC
504 rfi
505
506crit_return:
507 mfmsr r28 /* Disable interrupts */
508 li r4,0
509 ori r4,r4,MSR_EE
510 andc r28,r28,r4
511 SYNC /* Some chip revs need this... */
512 mtmsr r28
513 SYNC
514 lwz r2,_CTR(r1)
515 lwz r0,_LINK(r1)
516 mtctr r2
517 mtlr r0
518 lwz r2,_XER(r1)
519 lwz r0,_CCR(r1)
520 mtspr XER,r2
521 mtcrf 0xFF,r0
522 REST_10GPRS(3, r1)
523 REST_10GPRS(13, r1)
524 REST_8GPRS(23, r1)
525 REST_GPR(31, r1)
526 lwz r2,_NIP(r1) /* Restore environment */
527 lwz r0,_MSR(r1)
61a21e98
AF
528 mtspr SPRN_CSRR0,r2
529 mtspr SPRN_CSRR1,r0
42d1f039
WD
530 lwz r0,GPR0(r1)
531 lwz r2,GPR2(r1)
532 lwz r1,GPR1(r1)
533 SYNC
534 rfci
535
61a21e98
AF
536mck_return:
537 mfmsr r28 /* Disable interrupts */
538 li r4,0
539 ori r4,r4,MSR_EE
540 andc r28,r28,r4
541 SYNC /* Some chip revs need this... */
542 mtmsr r28
543 SYNC
544 lwz r2,_CTR(r1)
545 lwz r0,_LINK(r1)
546 mtctr r2
547 mtlr r0
548 lwz r2,_XER(r1)
549 lwz r0,_CCR(r1)
550 mtspr XER,r2
551 mtcrf 0xFF,r0
552 REST_10GPRS(3, r1)
553 REST_10GPRS(13, r1)
554 REST_8GPRS(23, r1)
555 REST_GPR(31, r1)
556 lwz r2,_NIP(r1) /* Restore environment */
557 lwz r0,_MSR(r1)
558 mtspr SPRN_MCSRR0,r2
559 mtspr SPRN_MCSRR1,r0
560 lwz r0,GPR0(r1)
561 lwz r2,GPR2(r1)
562 lwz r1,GPR1(r1)
563 SYNC
564 rfmci
565
42d1f039
WD
566/* Cache functions.
567*/
568invalidate_icache:
569 mfspr r0,L1CSR1
61a21e98
AF
570 ori r0,r0,L1CSR1_ICFI
571 msync
572 isync
42d1f039
WD
573 mtspr L1CSR1,r0
574 isync
61a21e98 575 blr /* entire I cache */
42d1f039
WD
576
577invalidate_dcache:
578 mfspr r0,L1CSR0
61a21e98 579 ori r0,r0,L1CSR0_DCFI
42d1f039
WD
580 msync
581 isync
582 mtspr L1CSR0,r0
583 isync
584 blr
585
586 .globl icache_enable
587icache_enable:
588 mflr r8
589 bl invalidate_icache
590 mtlr r8
591 isync
592 mfspr r4,L1CSR1
593 ori r4,r4,0x0001
594 oris r4,r4,0x0001
595 mtspr L1CSR1,r4
596 isync
597 blr
598
599 .globl icache_disable
600icache_disable:
601 mfspr r0,L1CSR1
61a21e98
AF
602 lis r3,0
603 ori r3,r3,L1CSR1_ICE
604 andc r0,r0,r3
42d1f039
WD
605 mtspr L1CSR1,r0
606 isync
607 blr
608
609 .globl icache_status
610icache_status:
611 mfspr r3,L1CSR1
61a21e98 612 andi. r3,r3,L1CSR1_ICE
42d1f039
WD
613 blr
614
615 .globl dcache_enable
616dcache_enable:
617 mflr r8
618 bl invalidate_dcache
619 mtlr r8
620 isync
621 mfspr r0,L1CSR0
622 ori r0,r0,0x0001
623 oris r0,r0,0x0001
624 msync
625 isync
626 mtspr L1CSR0,r0
627 isync
628 blr
629
630 .globl dcache_disable
631dcache_disable:
61a21e98
AF
632 mfspr r3,L1CSR0
633 lis r4,0
634 ori r4,r4,L1CSR0_DCE
635 andc r3,r3,r4
42d1f039
WD
636 mtspr L1CSR0,r0
637 isync
638 blr
639
640 .globl dcache_status
641dcache_status:
642 mfspr r3,L1CSR0
61a21e98 643 andi. r3,r3,L1CSR0_DCE
42d1f039
WD
644 blr
645
646 .globl get_pir
647get_pir:
61a21e98 648 mfspr r3,PIR
42d1f039
WD
649 blr
650
651 .globl get_pvr
652get_pvr:
61a21e98 653 mfspr r3,PVR
42d1f039
WD
654 blr
655
97d80fc3
WD
656 .globl get_svr
657get_svr:
61a21e98 658 mfspr r3,SVR
97d80fc3
WD
659 blr
660
42d1f039
WD
661 .globl wr_tcr
662wr_tcr:
61a21e98 663 mtspr TCR,r3
42d1f039
WD
664 blr
665
666/*------------------------------------------------------------------------------- */
667/* Function: in8 */
668/* Description: Input 8 bits */
669/*------------------------------------------------------------------------------- */
670 .globl in8
671in8:
672 lbz r3,0x0000(r3)
673 blr
674
675/*------------------------------------------------------------------------------- */
676/* Function: out8 */
677/* Description: Output 8 bits */
678/*------------------------------------------------------------------------------- */
679 .globl out8
680out8:
681 stb r4,0x0000(r3)
1487adbd 682 sync
42d1f039
WD
683 blr
684
685/*------------------------------------------------------------------------------- */
686/* Function: out16 */
687/* Description: Output 16 bits */
688/*------------------------------------------------------------------------------- */
689 .globl out16
690out16:
691 sth r4,0x0000(r3)
1487adbd 692 sync
42d1f039
WD
693 blr
694
695/*------------------------------------------------------------------------------- */
696/* Function: out16r */
697/* Description: Byte reverse and output 16 bits */
698/*------------------------------------------------------------------------------- */
699 .globl out16r
700out16r:
701 sthbrx r4,r0,r3
1487adbd 702 sync
42d1f039
WD
703 blr
704
705/*------------------------------------------------------------------------------- */
706/* Function: out32 */
707/* Description: Output 32 bits */
708/*------------------------------------------------------------------------------- */
709 .globl out32
710out32:
711 stw r4,0x0000(r3)
1487adbd 712 sync
42d1f039
WD
713 blr
714
715/*------------------------------------------------------------------------------- */
716/* Function: out32r */
717/* Description: Byte reverse and output 32 bits */
718/*------------------------------------------------------------------------------- */
719 .globl out32r
720out32r:
721 stwbrx r4,r0,r3
1487adbd 722 sync
42d1f039
WD
723 blr
724
725/*------------------------------------------------------------------------------- */
726/* Function: in16 */
727/* Description: Input 16 bits */
728/*------------------------------------------------------------------------------- */
729 .globl in16
730in16:
731 lhz r3,0x0000(r3)
732 blr
733
734/*------------------------------------------------------------------------------- */
735/* Function: in16r */
736/* Description: Input 16 bits and byte reverse */
737/*------------------------------------------------------------------------------- */
738 .globl in16r
739in16r:
740 lhbrx r3,r0,r3
741 blr
742
743/*------------------------------------------------------------------------------- */
744/* Function: in32 */
745/* Description: Input 32 bits */
746/*------------------------------------------------------------------------------- */
747 .globl in32
748in32:
749 lwz 3,0x0000(3)
750 blr
751
752/*------------------------------------------------------------------------------- */
753/* Function: in32r */
754/* Description: Input 32 bits and byte reverse */
755/*------------------------------------------------------------------------------- */
756 .globl in32r
757in32r:
758 lwbrx r3,r0,r3
759 blr
760
42d1f039
WD
761/*------------------------------------------------------------------------------*/
762
763/*
764 * void relocate_code (addr_sp, gd, addr_moni)
765 *
766 * This "function" does not return, instead it continues in RAM
767 * after relocating the monitor code.
768 *
769 * r3 = dest
770 * r4 = src
771 * r5 = length in bytes
772 * r6 = cachelinesize
773 */
774 .globl relocate_code
775relocate_code:
61a21e98
AF
776 mr r1,r3 /* Set new stack pointer */
777 mr r9,r4 /* Save copy of Init Data pointer */
778 mr r10,r5 /* Save copy of Destination Address */
42d1f039 779
61a21e98 780 mr r3,r5 /* Destination Address */
6d0f6bcf
JCPV
781 lis r4,CONFIG_SYS_MONITOR_BASE@h /* Source Address */
782 ori r4,r4,CONFIG_SYS_MONITOR_BASE@l
42d1f039
WD
783 lwz r5,GOT(__init_end)
784 sub r5,r5,r4
6d0f6bcf 785 li r6,CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
42d1f039
WD
786
787 /*
788 * Fix GOT pointer:
789 *
6d0f6bcf 790 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
42d1f039
WD
791 *
792 * Offset:
793 */
61a21e98 794 sub r15,r10,r4
42d1f039
WD
795
796 /* First our own GOT */
61a21e98 797 add r14,r14,r15
42d1f039 798 /* the the one used by the C code */
61a21e98 799 add r30,r30,r15
42d1f039
WD
800
801 /*
802 * Now relocate code
803 */
804
805 cmplw cr1,r3,r4
806 addi r0,r5,3
807 srwi. r0,r0,2
808 beq cr1,4f /* In place copy is not necessary */
809 beq 7f /* Protect against 0 count */
810 mtctr r0
811 bge cr1,2f
812
813 la r8,-4(r4)
814 la r7,-4(r3)
8151: lwzu r0,4(r8)
816 stwu r0,4(r7)
817 bdnz 1b
818 b 4f
819
8202: slwi r0,r0,2
821 add r8,r4,r0
822 add r7,r3,r0
8233: lwzu r0,-4(r8)
824 stwu r0,-4(r7)
825 bdnz 3b
826
827/*
828 * Now flush the cache: note that we must start from a cache aligned
829 * address. Otherwise we might miss one cache line.
830 */
8314: cmpwi r6,0
832 add r5,r3,r5
833 beq 7f /* Always flush prefetch queue in any case */
834 subi r0,r6,1
835 andc r3,r3,r0
836 mr r4,r3
8375: dcbst 0,r4
838 add r4,r4,r6
839 cmplw r4,r5
840 blt 5b
841 sync /* Wait for all dcbst to complete on bus */
842 mr r4,r3
8436: icbi 0,r4
844 add r4,r4,r6
845 cmplw r4,r5
846 blt 6b
8477: sync /* Wait for all icbi to complete on bus */
848 isync
849
7d314992
WD
850 /*
851 * Re-point the IVPR at RAM
852 */
853 mtspr IVPR,r10
99b0d285 854
42d1f039
WD
855/*
856 * We are done. Do not return, instead branch to second part of board
857 * initialization, now running from RAM.
858 */
859
61a21e98 860 addi r0,r10,in_ram - _start + _START_OFFSET
42d1f039
WD
861 mtlr r0
862 blr /* NEVER RETURNS! */
61a21e98 863 .globl in_ram
42d1f039
WD
864in_ram:
865
866 /*
867 * Relocation Function, r14 point to got2+0x8000
868 *
869 * Adjust got2 pointers, no need to check for 0, this code
870 * already puts a few entries in the table.
871 */
872 li r0,__got2_entries@sectoff@l
873 la r3,GOT(_GOT2_TABLE_)
874 lwz r11,GOT(_GOT2_TABLE_)
875 mtctr r0
876 sub r11,r3,r11
877 addi r3,r3,-4
8781: lwzu r0,4(r3)
879 add r0,r0,r11
880 stw r0,0(r3)
881 bdnz 1b
882
883 /*
884 * Now adjust the fixups and the pointers to the fixups
885 * in case we need to move ourselves again.
886 */
8872: li r0,__fixup_entries@sectoff@l
888 lwz r3,GOT(_FIXUP_TABLE_)
889 cmpwi r0,0
890 mtctr r0
891 addi r3,r3,-4
892 beq 4f
8933: lwzu r4,4(r3)
894 lwzux r0,r4,r11
895 add r0,r0,r11
896 stw r10,0(r3)
897 stw r0,0(r4)
898 bdnz 3b
8994:
900clear_bss:
901 /*
902 * Now clear BSS segment
903 */
904 lwz r3,GOT(__bss_start)
905 lwz r4,GOT(_end)
906
61a21e98 907 cmplw 0,r3,r4
42d1f039
WD
908 beq 6f
909
61a21e98 910 li r0,0
42d1f039 9115:
61a21e98
AF
912 stw r0,0(r3)
913 addi r3,r3,4
914 cmplw 0,r3,r4
42d1f039
WD
915 bne 5b
9166:
917
61a21e98
AF
918 mr r3,r9 /* Init Data pointer */
919 mr r4,r10 /* Destination Address */
42d1f039
WD
920 bl board_init_r
921
922 /*
923 * Copy exception vector code to low memory
924 *
925 * r3: dest_addr
926 * r7: source address, r8: end address, r9: target address
927 */
343117bf 928 .globl trap_init
42d1f039 929trap_init:
61a21e98
AF
930 lwz r7,GOT(_start_of_vectors)
931 lwz r8,GOT(_end_of_vectors)
42d1f039 932
61a21e98 933 li r9,0x100 /* reset vector always at 0x100 */
42d1f039 934
61a21e98 935 cmplw 0,r7,r8
343117bf 936 bgelr /* return if r7>=r8 - just in case */
42d1f039 937
343117bf 938 mflr r4 /* save link register */
42d1f039 9391:
61a21e98
AF
940 lwz r0,0(r7)
941 stw r0,0(r9)
942 addi r7,r7,4
943 addi r9,r9,4
944 cmplw 0,r7,r8
343117bf 945 bne 1b
42d1f039
WD
946
947 /*
948 * relocate `hdlr' and `int_return' entries
949 */
61a21e98 950 li r7,.L_CriticalInput - _start + _START_OFFSET
343117bf 951 bl trap_reloc
61a21e98 952 li r7,.L_MachineCheck - _start + _START_OFFSET
343117bf 953 bl trap_reloc
61a21e98 954 li r7,.L_DataStorage - _start + _START_OFFSET
343117bf 955 bl trap_reloc
61a21e98 956 li r7,.L_InstStorage - _start + _START_OFFSET
343117bf 957 bl trap_reloc
61a21e98 958 li r7,.L_ExtInterrupt - _start + _START_OFFSET
343117bf 959 bl trap_reloc
61a21e98 960 li r7,.L_Alignment - _start + _START_OFFSET
343117bf 961 bl trap_reloc
61a21e98 962 li r7,.L_ProgramCheck - _start + _START_OFFSET
343117bf 963 bl trap_reloc
61a21e98 964 li r7,.L_FPUnavailable - _start + _START_OFFSET
343117bf 965 bl trap_reloc
61a21e98
AF
966 li r7,.L_Decrementer - _start + _START_OFFSET
967 bl trap_reloc
968 li r7,.L_IntervalTimer - _start + _START_OFFSET
969 li r8,_end_of_vectors - _start + _START_OFFSET
42d1f039 9702:
343117bf 971 bl trap_reloc
61a21e98
AF
972 addi r7,r7,0x100 /* next exception vector */
973 cmplw 0,r7,r8
343117bf
WD
974 blt 2b
975
976 lis r7,0x0
61a21e98 977 mtspr IVPR,r7
42d1f039 978
343117bf 979 mtlr r4 /* restore link register */
42d1f039
WD
980 blr
981
982 /*
983 * Function: relocate entries for one exception vector
984 */
985trap_reloc:
61a21e98
AF
986 lwz r0,0(r7) /* hdlr ... */
987 add r0,r0,r3 /* ... += dest_addr */
988 stw r0,0(r7)
42d1f039 989
61a21e98
AF
990 lwz r0,4(r7) /* int_return ... */
991 add r0,r0,r3 /* ... += dest_addr */
992 stw r0,4(r7)
42d1f039
WD
993
994 blr
995
42d1f039
WD
996.globl unlock_ram_in_cache
997unlock_ram_in_cache:
998 /* invalidate the INIT_RAM section */
6d0f6bcf
JCPV
999 lis r3,(CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
1000 ori r3,r3,(CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
b009f3ec
KG
1001 mfspr r4,L1CFG0
1002 andi. r4,r4,0x1ff
1003 slwi r4,r4,(10 - 1 - L1_CACHE_SHIFT)
61a21e98 1004 mtctr r4
2b22fa4b 10051: dcbi r0,r3
6d0f6bcf 1006 addi r3,r3,CONFIG_SYS_CACHELINE_SIZE
42d1f039 1007 bdnz 1b
2b22fa4b 1008 sync
21fae8b2
AF
1009
1010 /* Invalidate the TLB entries for the cache */
6d0f6bcf
JCPV
1011 lis r3,CONFIG_SYS_INIT_RAM_ADDR@h
1012 ori r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l
21fae8b2
AF
1013 tlbivax 0,r3
1014 addi r3,r3,0x1000
1015 tlbivax 0,r3
1016 addi r3,r3,0x1000
1017 tlbivax 0,r3
1018 addi r3,r3,0x1000
1019 tlbivax 0,r3
42d1f039
WD
1020 isync
1021 blr