]> git.ipfire.org Git - people/ms/u-boot.git/blame - cpu/mpc85xx/start.S
85xx: Added various P1012/P1013/P1021/P1022 defines
[people/ms/u-boot.git] / cpu / mpc85xx / start.S
CommitLineData
42d1f039 1/*
69bcf5bc 2 * Copyright 2004, 2007-2010 Freescale Semiconductor, Inc.
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>
561858ee 33#include <timestamp.h>
42d1f039
WD
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
61a21e98 49#define MSR_KERNEL ( MSR_ME ) /* Machine Check */
42d1f039
WD
50
51/*
52 * Set up GOT: Global Offset Table
53 *
0f8aa159 54 * Use r12 to access the GOT
42d1f039
WD
55 */
56 START_GOT
57 GOT_ENTRY(_GOT2_TABLE_)
58 GOT_ENTRY(_FIXUP_TABLE_)
59
7da53351 60#ifndef CONFIG_NAND_SPL
42d1f039
WD
61 GOT_ENTRY(_start)
62 GOT_ENTRY(_start_of_vectors)
63 GOT_ENTRY(_end_of_vectors)
64 GOT_ENTRY(transfer_to_handler)
7da53351 65#endif
42d1f039
WD
66
67 GOT_ENTRY(__init_end)
68 GOT_ENTRY(_end)
69 GOT_ENTRY(__bss_start)
70 END_GOT
71
72/*
73 * e500 Startup -- after reset only the last 4KB of the effective
74 * address space is mapped in the MMU L2 TLB1 Entry0. The .bootpg
75 * section is located at THIS LAST page and basically does three
76 * things: clear some registers, set up exception tables and
77 * add more TLB entries for 'larger spaces'(e.g. the boot rom) to
78 * continue the boot procedure.
79
80 * Once the boot rom is mapped by TLB entries we can proceed
81 * with normal startup.
82 *
83 */
84
61a21e98
AF
85 .section .bootpg,"ax"
86 .globl _start_e500
42d1f039
WD
87
88_start_e500:
97d80fc3 89
61a21e98 90/* clear registers/arrays not reset by hardware */
42d1f039 91
61a21e98
AF
92 /* L1 */
93 li r0,2
94 mtspr L1CSR0,r0 /* invalidate d-cache */
53677ef1 95 mtspr L1CSR1,r0 /* invalidate i-cache */
42d1f039
WD
96
97 mfspr r1,DBSR
98 mtspr DBSR,r1 /* Clear all valid bits */
99
61a21e98
AF
100 /*
101 * Enable L1 Caches early
102 *
103 */
42d1f039 104
82fd1f8d
KG
105#if defined(CONFIG_E500MC) && defined(CONFIG_SYS_CACHE_STASHING)
106 /* set stash id to (coreID) * 2 + 32 + L1 CT (0) */
107 li r2,(32 + 0)
108 mtspr L1CSR2,r2
109#endif
110
33f57bd5
KG
111 /* Enable/invalidate the I-Cache */
112 lis r2,(L1CSR1_ICFI|L1CSR1_ICLFR)@h
113 ori r2,r2,(L1CSR1_ICFI|L1CSR1_ICLFR)@l
114 mtspr SPRN_L1CSR1,r2
1151:
116 mfspr r3,SPRN_L1CSR1
117 and. r1,r3,r2
118 bne 1b
119
120 lis r3,(L1CSR1_CPE|L1CSR1_ICE)@h
121 ori r3,r3,(L1CSR1_CPE|L1CSR1_ICE)@l
122 mtspr SPRN_L1CSR1,r3
61a21e98 123 isync
33f57bd5
KG
1242:
125 mfspr r3,SPRN_L1CSR1
126 andi. r1,r3,L1CSR1_ICE@l
127 beq 2b
128
129 /* Enable/invalidate the D-Cache */
130 lis r2,(L1CSR0_DCFI|L1CSR0_DCLFR)@h
131 ori r2,r2,(L1CSR0_DCFI|L1CSR0_DCLFR)@l
132 mtspr SPRN_L1CSR0,r2
1331:
134 mfspr r3,SPRN_L1CSR0
135 and. r1,r3,r2
136 bne 1b
137
138 lis r3,(L1CSR0_CPE|L1CSR0_DCE)@h
139 ori r3,r3,(L1CSR0_CPE|L1CSR0_DCE)@l
140 mtspr SPRN_L1CSR0,r3
42d1f039 141 isync
33f57bd5
KG
1422:
143 mfspr r3,SPRN_L1CSR0
144 andi. r1,r3,L1CSR0_DCE@l
145 beq 2b
42d1f039
WD
146
147 /* Setup interrupt vectors */
343117bf 148 lis r1,TEXT_BASE@h
61a21e98 149 mtspr IVPR,r1
42d1f039 150
343117bf 151 li r1,0x0100
42d1f039 152 mtspr IVOR0,r1 /* 0: Critical input */
343117bf 153 li r1,0x0200
42d1f039 154 mtspr IVOR1,r1 /* 1: Machine check */
343117bf 155 li r1,0x0300
42d1f039 156 mtspr IVOR2,r1 /* 2: Data storage */
343117bf 157 li r1,0x0400
42d1f039
WD
158 mtspr IVOR3,r1 /* 3: Instruction storage */
159 li r1,0x0500
160 mtspr IVOR4,r1 /* 4: External interrupt */
161 li r1,0x0600
162 mtspr IVOR5,r1 /* 5: Alignment */
163 li r1,0x0700
164 mtspr IVOR6,r1 /* 6: Program check */
165 li r1,0x0800
166 mtspr IVOR7,r1 /* 7: floating point unavailable */
343117bf 167 li r1,0x0900
42d1f039
WD
168 mtspr IVOR8,r1 /* 8: System call */
169 /* 9: Auxiliary processor unavailable(unsupported) */
343117bf 170 li r1,0x0a00
42d1f039 171 mtspr IVOR10,r1 /* 10: Decrementer */
343117bf
WD
172 li r1,0x0b00
173 mtspr IVOR11,r1 /* 11: Interval timer */
174 li r1,0x0c00
3e0bc447
WD
175 mtspr IVOR12,r1 /* 12: Watchdog timer */
176 li r1,0x0d00
42d1f039 177 mtspr IVOR13,r1 /* 13: Data TLB error */
343117bf 178 li r1,0x0e00
42d1f039 179 mtspr IVOR14,r1 /* 14: Instruction TLB error */
343117bf 180 li r1,0x0f00
42d1f039
WD
181 mtspr IVOR15,r1 /* 15: Debug */
182
42d1f039 183 /* Clear and set up some registers. */
87163180 184 li r0,0x0000
42d1f039
WD
185 lis r1,0xffff
186 mtspr DEC,r0 /* prevent dec exceptions */
187 mttbl r0 /* prevent fit & wdt exceptions */
188 mttbu r0
189 mtspr TSR,r1 /* clear all timer exception status */
190 mtspr TCR,r0 /* disable all */
191 mtspr ESR,r0 /* clear exception syndrome register */
192 mtspr MCSR,r0 /* machine check syndrome register */
193 mtxer r0 /* clear integer exception register */
42d1f039 194
dcc87dd5
SW
195#ifdef CONFIG_SYS_BOOK3E_HV
196 mtspr MAS8,r0 /* make sure MAS8 is clear */
197#endif
198
42d1f039 199 /* Enable Time Base and Select Time Base Clock */
0ac6f8b7 200 lis r0,HID0_EMCP@h /* Enable machine check */
d9b94f28 201#if defined(CONFIG_ENABLE_36BIT_PHYS)
87163180 202 ori r0,r0,HID0_ENMAS7@l /* Enable MAS7 */
d9b94f28 203#endif
1b3e4044 204#ifndef CONFIG_E500MC
87163180 205 ori r0,r0,HID0_TBEN@l /* Enable Timebase */
1b3e4044 206#endif
42d1f039 207 mtspr HID0,r0
42d1f039 208
0f060c3b 209#ifndef CONFIG_E500MC
61a21e98 210 li r0,(HID1_ASTME|HID1_ABE)@l /* Addr streaming & broadcast */
42d1f039 211 mtspr HID1,r0
0f060c3b 212#endif
42d1f039
WD
213
214 /* Enable Branch Prediction */
215#if defined(CONFIG_BTB)
69bcf5bc
KG
216 lis r0,BUCSR_ENABLE@h
217 ori r0,r0,BUCSR_ENABLE@l
218 mtspr SPRN_BUCSR,r0
42d1f039
WD
219#endif
220
6d0f6bcf 221#if defined(CONFIG_SYS_INIT_DBCR)
42d1f039
WD
222 lis r1,0xffff
223 ori r1,r1,0xffff
0ac6f8b7 224 mtspr DBSR,r1 /* Clear all status bits */
6d0f6bcf
JCPV
225 lis r0,CONFIG_SYS_INIT_DBCR@h /* DBCR0[IDM] must be set */
226 ori r0,r0,CONFIG_SYS_INIT_DBCR@l
0ac6f8b7 227 mtspr DBCR0,r0
42d1f039
WD
228#endif
229
22b6dbc1
HW
230#ifdef CONFIG_MPC8569
231#define CONFIG_SYS_LBC_ADDR (CONFIG_SYS_CCSRBAR_DEFAULT + 0x5000)
232#define CONFIG_SYS_LBCR_ADDR (CONFIG_SYS_LBC_ADDR + 0xd0)
233
234 /* MPC8569 Rev.0 silcon needs to set bit 13 of LBCR to allow elBC to
235 * use address space which is more than 12bits, and it must be done in
236 * the 4K boot page. So we set this bit here.
237 */
238
239 /* create a temp mapping TLB0[0] for LBCR */
240 lis r6,FSL_BOOKE_MAS0(0, 0, 0)@h
241 ori r6,r6,FSL_BOOKE_MAS0(0, 0, 0)@l
242
243 lis r7,FSL_BOOKE_MAS1(1, 0, 0, 0, BOOKE_PAGESZ_4K)@h
244 ori r7,r7,FSL_BOOKE_MAS1(1, 0, 0, 0, BOOKE_PAGESZ_4K)@l
245
246 lis r8,FSL_BOOKE_MAS2(CONFIG_SYS_LBC_ADDR, MAS2_I|MAS2_G)@h
247 ori r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_LBC_ADDR, MAS2_I|MAS2_G)@l
248
249 lis r9,FSL_BOOKE_MAS3(CONFIG_SYS_LBC_ADDR, 0,
250 (MAS3_SX|MAS3_SW|MAS3_SR))@h
251 ori r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_LBC_ADDR, 0,
252 (MAS3_SX|MAS3_SW|MAS3_SR))@l
253
254 mtspr MAS0,r6
255 mtspr MAS1,r7
256 mtspr MAS2,r8
257 mtspr MAS3,r9
258 isync
259 msync
260 tlbwe
261
262 /* Set LBCR register */
263 lis r4,CONFIG_SYS_LBCR_ADDR@h
264 ori r4,r4,CONFIG_SYS_LBCR_ADDR@l
265
266 lis r5,CONFIG_SYS_LBC_LBCR@h
267 ori r5,r5,CONFIG_SYS_LBC_LBCR@l
268 stw r5,0(r4)
269 isync
270
271 /* invalidate this temp TLB */
272 lis r4,CONFIG_SYS_LBC_ADDR@h
273 ori r4,r4,CONFIG_SYS_LBC_ADDR@l
274 tlbivax 0,r4
275 isync
276
277#endif /* CONFIG_MPC8569 */
278
87163180
KG
279 lis r6,FSL_BOOKE_MAS0(1, 15, 0)@h
280 ori r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l
281
7da53351
MH
282#ifndef CONFIG_SYS_RAMBOOT
283 /* create a temp mapping in AS=1 to the 4M boot window */
f51f07eb
DL
284 lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_4M)@h
285 ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_4M)@l
87163180 286
f51f07eb
DL
287 lis r8,FSL_BOOKE_MAS2(TEXT_BASE & 0xffc00000, (MAS2_I|MAS2_G))@h
288 ori r8,r8,FSL_BOOKE_MAS2(TEXT_BASE & 0xffc00000, (MAS2_I|MAS2_G))@l
87163180 289
f51f07eb
DL
290 /* The 85xx has the default boot window 0xff800000 - 0xffffffff */
291 lis r9,FSL_BOOKE_MAS3(0xffc00000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h
292 ori r9,r9,FSL_BOOKE_MAS3(0xffc00000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l
7da53351
MH
293#else
294 /*
295 * create a temp mapping in AS=1 to the 1M TEXT_BASE space, the main
296 * image has been relocated to TEXT_BASE on the second stage.
297 */
298 lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_1M)@h
299 ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_1M)@l
300
301 lis r8,FSL_BOOKE_MAS2(TEXT_BASE, (MAS2_I|MAS2_G))@h
302 ori r8,r8,FSL_BOOKE_MAS2(TEXT_BASE, (MAS2_I|MAS2_G))@l
303
304 lis r9,FSL_BOOKE_MAS3(TEXT_BASE, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h
305 ori r9,r9,FSL_BOOKE_MAS3(TEXT_BASE, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l
306#endif
87163180
KG
307
308 mtspr MAS0,r6
309 mtspr MAS1,r7
310 mtspr MAS2,r8
311 mtspr MAS3,r9
312 isync
313 msync
314 tlbwe
315
316 /* create a temp mapping in AS=1 to the stack */
317 lis r6,FSL_BOOKE_MAS0(1, 14, 0)@h
318 ori r6,r6,FSL_BOOKE_MAS0(1, 14, 0)@l
319
320 lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16K)@h
321 ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16K)@l
322
6d0f6bcf
JCPV
323 lis r8,FSL_BOOKE_MAS2(CONFIG_SYS_INIT_RAM_ADDR, 0)@h
324 ori r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_INIT_RAM_ADDR, 0)@l
87163180 325
6d0f6bcf
JCPV
326 lis r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h
327 ori r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l
87163180
KG
328
329 mtspr MAS0,r6
330 mtspr MAS1,r7
331 mtspr MAS2,r8
332 mtspr MAS3,r9
333 isync
334 msync
335 tlbwe
336
1b72dbec
SW
337 lis r6,MSR_IS|MSR_DS@h
338 ori r6,r6,MSR_IS|MSR_DS@l
87163180
KG
339 lis r7,switch_as@h
340 ori r7,r7,switch_as@l
341
342 mtspr SPRN_SRR0,r7
343 mtspr SPRN_SRR1,r6
344 rfi
345
346switch_as:
3db0bef5
KG
347/* L1 DCache is used for initial RAM */
348
349 /* Allocate Initial RAM in data cache.
350 */
6d0f6bcf
JCPV
351 lis r3,CONFIG_SYS_INIT_RAM_ADDR@h
352 ori r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l
b009f3ec
KG
353 mfspr r2, L1CFG0
354 andi. r2, r2, 0x1ff
355 /* cache size * 1024 / (2 * L1 line size) */
356 slwi r2, r2, (10 - 1 - L1_CACHE_SHIFT)
3db0bef5
KG
357 mtctr r2
358 li r0,0
3591:
360 dcbz r0,r3
361 dcbtls 0,r0,r3
6d0f6bcf 362 addi r3,r3,CONFIG_SYS_CACHELINE_SIZE
3db0bef5
KG
363 bdnz 1b
364
61a21e98 365 /* Jump out the last 4K page and continue to 'normal' start */
6d0f6bcf 366#ifdef CONFIG_SYS_RAMBOOT
61a21e98 367 b _start_cont
3db0bef5
KG
368#else
369 /* Calculate absolute address in FLASH and jump there */
370 /*--------------------------------------------------------------*/
6d0f6bcf
JCPV
371 lis r3,CONFIG_SYS_MONITOR_BASE@h
372 ori r3,r3,CONFIG_SYS_MONITOR_BASE@l
3db0bef5
KG
373 addi r3,r3,_start_cont - _start + _START_OFFSET
374 mtlr r3
1e701e70 375 blr
3db0bef5 376#endif
61a21e98 377
61a21e98
AF
378 .text
379 .globl _start
380_start:
381 .long 0x27051956 /* U-BOOT Magic Number */
382 .globl version_string
383version_string:
384 .ascii U_BOOT_VERSION
561858ee 385 .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")"
61a21e98
AF
386 .ascii CONFIG_IDENT_STRING, "\0"
387
388 .align 4
389 .globl _start_cont
390_start_cont:
42d1f039 391 /* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/
6d0f6bcf
JCPV
392 lis r1,CONFIG_SYS_INIT_RAM_ADDR@h
393 ori r1,r1,CONFIG_SYS_INIT_SP_OFFSET@l
42d1f039
WD
394
395 li r0,0
396 stwu r0,-4(r1)
397 stwu r0,-4(r1) /* Terminate call chain */
398
399 stwu r1,-8(r1) /* Save back chain and move SP */
400 lis r0,RESET_VECTOR@h /* Address of reset vector */
61a21e98 401 ori r0,r0,RESET_VECTOR@l
42d1f039
WD
402 stwu r1,-8(r1) /* Save back chain and move SP */
403 stw r0,+12(r1) /* Save return addr (underflow vect) */
404
405 GET_GOT
87163180
KG
406 bl cpu_init_early_f
407
408 /* switch back to AS = 0 */
409 lis r3,(MSR_CE|MSR_ME|MSR_DE)@h
410 ori r3,r3,(MSR_CE|MSR_ME|MSR_DE)@l
411 mtmsr r3
412 isync
413
42d1f039 414 bl cpu_init_f
42d1f039 415 bl board_init_f
0ac6f8b7 416 isync
42d1f039 417
7da53351 418#ifndef CONFIG_NAND_SPL
61a21e98 419 . = EXC_OFF_SYS_RESET
42d1f039
WD
420 .globl _start_of_vectors
421_start_of_vectors:
61a21e98 422
42d1f039 423/* Critical input. */
61a21e98
AF
424 CRIT_EXCEPTION(0x0100, CriticalInput, CritcalInputException)
425
426/* Machine check */
427 MCK_EXCEPTION(0x200, MachineCheck, MachineCheckException)
42d1f039
WD
428
429/* Data Storage exception. */
430 STD_EXCEPTION(0x0300, DataStorage, UnknownException)
431
432/* Instruction Storage exception. */
433 STD_EXCEPTION(0x0400, InstStorage, UnknownException)
434
435/* External Interrupt exception. */
61a21e98 436 STD_EXCEPTION(0x0500, ExtInterrupt, ExtIntException)
42d1f039
WD
437
438/* Alignment exception. */
439 . = 0x0600
440Alignment:
02032e8f 441 EXCEPTION_PROLOG(SRR0, SRR1)
42d1f039
WD
442 mfspr r4,DAR
443 stw r4,_DAR(r21)
444 mfspr r5,DSISR
445 stw r5,_DSISR(r21)
446 addi r3,r1,STACK_FRAME_OVERHEAD
fc4e1887 447 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
42d1f039
WD
448
449/* Program check exception */
450 . = 0x0700
451ProgramCheck:
02032e8f 452 EXCEPTION_PROLOG(SRR0, SRR1)
42d1f039 453 addi r3,r1,STACK_FRAME_OVERHEAD
fc4e1887
JT
454 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
455 MSR_KERNEL, COPY_EE)
42d1f039
WD
456
457 /* No FPU on MPC85xx. This exception is not supposed to happen.
458 */
459 STD_EXCEPTION(0x0800, FPUnavailable, UnknownException)
42d1f039 460
343117bf 461 . = 0x0900
42d1f039
WD
462/*
463 * r0 - SYSCALL number
464 * r3-... arguments
465 */
466SystemCall:
61a21e98
AF
467 addis r11,r0,0 /* get functions table addr */
468 ori r11,r11,0 /* Note: this code is patched in trap_init */
469 addis r12,r0,0 /* get number of functions */
343117bf
WD
470 ori r12,r12,0
471
61a21e98 472 cmplw 0,r0,r12
343117bf
WD
473 bge 1f
474
61a21e98 475 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */
343117bf
WD
476 add r11,r11,r0
477 lwz r11,0(r11)
478
61a21e98 479 li r20,0xd00-4 /* Get stack pointer */
343117bf 480 lwz r12,0(r20)
61a21e98 481 subi r12,r12,12 /* Adjust stack pointer */
343117bf 482 li r0,0xc00+_end_back-SystemCall
61a21e98 483 cmplw 0,r0,r12 /* Check stack overflow */
343117bf
WD
484 bgt 1f
485 stw r12,0(r20)
486
487 mflr r0
488 stw r0,0(r12)
489 mfspr r0,SRR0
490 stw r0,4(r12)
491 mfspr r0,SRR1
492 stw r0,8(r12)
493
494 li r12,0xc00+_back-SystemCall
495 mtlr r12
496 mtspr SRR0,r11
497
4981: SYNC
42d1f039
WD
499 rfi
500_back:
501
343117bf
WD
502 mfmsr r11 /* Disable interrupts */
503 li r12,0
504 ori r12,r12,MSR_EE
505 andc r11,r11,r12
506 SYNC /* Some chip revs need this... */
507 mtmsr r11
42d1f039
WD
508 SYNC
509
343117bf
WD
510 li r12,0xd00-4 /* restore regs */
511 lwz r12,0(r12)
42d1f039 512
343117bf
WD
513 lwz r11,0(r12)
514 mtlr r11
515 lwz r11,4(r12)
516 mtspr SRR0,r11
517 lwz r11,8(r12)
518 mtspr SRR1,r11
42d1f039 519
343117bf
WD
520 addi r12,r12,12 /* Adjust stack pointer */
521 li r20,0xd00-4
522 stw r12,0(r20)
42d1f039
WD
523
524 SYNC
525 rfi
526_end_back:
527
343117bf
WD
528 STD_EXCEPTION(0x0a00, Decrementer, timer_interrupt)
529 STD_EXCEPTION(0x0b00, IntervalTimer, UnknownException)
530 STD_EXCEPTION(0x0c00, WatchdogTimer, UnknownException)
42d1f039 531
343117bf
WD
532 STD_EXCEPTION(0x0d00, DataTLBError, UnknownException)
533 STD_EXCEPTION(0x0e00, InstructionTLBError, UnknownException)
42d1f039 534
343117bf 535 CRIT_EXCEPTION(0x0f00, DebugBreakpoint, DebugException )
42d1f039 536
343117bf 537 .globl _end_of_vectors
42d1f039
WD
538_end_of_vectors:
539
540
61a21e98 541 . = . + (0x100 - ( . & 0xff )) /* align for debug */
42d1f039
WD
542
543/*
544 * This code finishes saving the registers to the exception frame
545 * and jumps to the appropriate handler for the exception.
546 * Register r21 is pointer into trap frame, r1 has new stack pointer.
547 */
548 .globl transfer_to_handler
549transfer_to_handler:
550 stw r22,_NIP(r21)
551 lis r22,MSR_POW@h
552 andc r23,r23,r22
553 stw r23,_MSR(r21)
554 SAVE_GPR(7, r21)
555 SAVE_4GPRS(8, r21)
556 SAVE_8GPRS(12, r21)
557 SAVE_8GPRS(24, r21)
558
559 mflr r23
560 andi. r24,r23,0x3f00 /* get vector offset */
561 stw r24,TRAP(r21)
562 li r22,0
563 stw r22,RESULT(r21)
564 mtspr SPRG2,r22 /* r1 is now kernel sp */
565
566 lwz r24,0(r23) /* virtual address of handler */
567 lwz r23,4(r23) /* where to go when done */
568 mtspr SRR0,r24
569 mtspr SRR1,r20
570 mtlr r23
571 SYNC
572 rfi /* jump to handler, enable MMU */
573
574int_return:
575 mfmsr r28 /* Disable interrupts */
576 li r4,0
577 ori r4,r4,MSR_EE
578 andc r28,r28,r4
579 SYNC /* Some chip revs need this... */
580 mtmsr r28
581 SYNC
582 lwz r2,_CTR(r1)
583 lwz r0,_LINK(r1)
584 mtctr r2
585 mtlr r0
586 lwz r2,_XER(r1)
587 lwz r0,_CCR(r1)
588 mtspr XER,r2
589 mtcrf 0xFF,r0
590 REST_10GPRS(3, r1)
591 REST_10GPRS(13, r1)
592 REST_8GPRS(23, r1)
593 REST_GPR(31, r1)
594 lwz r2,_NIP(r1) /* Restore environment */
595 lwz r0,_MSR(r1)
596 mtspr SRR0,r2
597 mtspr SRR1,r0
598 lwz r0,GPR0(r1)
599 lwz r2,GPR2(r1)
600 lwz r1,GPR1(r1)
601 SYNC
602 rfi
603
604crit_return:
605 mfmsr r28 /* Disable interrupts */
606 li r4,0
607 ori r4,r4,MSR_EE
608 andc r28,r28,r4
609 SYNC /* Some chip revs need this... */
610 mtmsr r28
611 SYNC
612 lwz r2,_CTR(r1)
613 lwz r0,_LINK(r1)
614 mtctr r2
615 mtlr r0
616 lwz r2,_XER(r1)
617 lwz r0,_CCR(r1)
618 mtspr XER,r2
619 mtcrf 0xFF,r0
620 REST_10GPRS(3, r1)
621 REST_10GPRS(13, r1)
622 REST_8GPRS(23, r1)
623 REST_GPR(31, r1)
624 lwz r2,_NIP(r1) /* Restore environment */
625 lwz r0,_MSR(r1)
61a21e98
AF
626 mtspr SPRN_CSRR0,r2
627 mtspr SPRN_CSRR1,r0
42d1f039
WD
628 lwz r0,GPR0(r1)
629 lwz r2,GPR2(r1)
630 lwz r1,GPR1(r1)
631 SYNC
632 rfci
633
61a21e98
AF
634mck_return:
635 mfmsr r28 /* Disable interrupts */
636 li r4,0
637 ori r4,r4,MSR_EE
638 andc r28,r28,r4
639 SYNC /* Some chip revs need this... */
640 mtmsr r28
641 SYNC
642 lwz r2,_CTR(r1)
643 lwz r0,_LINK(r1)
644 mtctr r2
645 mtlr r0
646 lwz r2,_XER(r1)
647 lwz r0,_CCR(r1)
648 mtspr XER,r2
649 mtcrf 0xFF,r0
650 REST_10GPRS(3, r1)
651 REST_10GPRS(13, r1)
652 REST_8GPRS(23, r1)
653 REST_GPR(31, r1)
654 lwz r2,_NIP(r1) /* Restore environment */
655 lwz r0,_MSR(r1)
656 mtspr SPRN_MCSRR0,r2
657 mtspr SPRN_MCSRR1,r0
658 lwz r0,GPR0(r1)
659 lwz r2,GPR2(r1)
660 lwz r1,GPR1(r1)
661 SYNC
662 rfmci
663
42d1f039
WD
664/* Cache functions.
665*/
54e091d3 666.globl invalidate_icache
42d1f039
WD
667invalidate_icache:
668 mfspr r0,L1CSR1
61a21e98
AF
669 ori r0,r0,L1CSR1_ICFI
670 msync
671 isync
42d1f039
WD
672 mtspr L1CSR1,r0
673 isync
61a21e98 674 blr /* entire I cache */
42d1f039 675
54e091d3 676.globl invalidate_dcache
42d1f039
WD
677invalidate_dcache:
678 mfspr r0,L1CSR0
61a21e98 679 ori r0,r0,L1CSR0_DCFI
42d1f039
WD
680 msync
681 isync
682 mtspr L1CSR0,r0
683 isync
684 blr
685
686 .globl icache_enable
687icache_enable:
688 mflr r8
689 bl invalidate_icache
690 mtlr r8
691 isync
692 mfspr r4,L1CSR1
693 ori r4,r4,0x0001
694 oris r4,r4,0x0001
695 mtspr L1CSR1,r4
696 isync
697 blr
698
699 .globl icache_disable
700icache_disable:
701 mfspr r0,L1CSR1
61a21e98
AF
702 lis r3,0
703 ori r3,r3,L1CSR1_ICE
704 andc r0,r0,r3
42d1f039
WD
705 mtspr L1CSR1,r0
706 isync
707 blr
708
709 .globl icache_status
710icache_status:
711 mfspr r3,L1CSR1
61a21e98 712 andi. r3,r3,L1CSR1_ICE
42d1f039
WD
713 blr
714
715 .globl dcache_enable
716dcache_enable:
717 mflr r8
718 bl invalidate_dcache
719 mtlr r8
720 isync
721 mfspr r0,L1CSR0
722 ori r0,r0,0x0001
723 oris r0,r0,0x0001
724 msync
725 isync
726 mtspr L1CSR0,r0
727 isync
728 blr
729
730 .globl dcache_disable
731dcache_disable:
61a21e98
AF
732 mfspr r3,L1CSR0
733 lis r4,0
734 ori r4,r4,L1CSR0_DCE
735 andc r3,r3,r4
42d1f039
WD
736 mtspr L1CSR0,r0
737 isync
738 blr
739
740 .globl dcache_status
741dcache_status:
742 mfspr r3,L1CSR0
61a21e98 743 andi. r3,r3,L1CSR0_DCE
42d1f039
WD
744 blr
745
746 .globl get_pir
747get_pir:
61a21e98 748 mfspr r3,PIR
42d1f039
WD
749 blr
750
751 .globl get_pvr
752get_pvr:
61a21e98 753 mfspr r3,PVR
42d1f039
WD
754 blr
755
97d80fc3
WD
756 .globl get_svr
757get_svr:
61a21e98 758 mfspr r3,SVR
97d80fc3
WD
759 blr
760
42d1f039
WD
761 .globl wr_tcr
762wr_tcr:
61a21e98 763 mtspr TCR,r3
42d1f039
WD
764 blr
765
766/*------------------------------------------------------------------------------- */
767/* Function: in8 */
768/* Description: Input 8 bits */
769/*------------------------------------------------------------------------------- */
770 .globl in8
771in8:
772 lbz r3,0x0000(r3)
773 blr
774
775/*------------------------------------------------------------------------------- */
776/* Function: out8 */
777/* Description: Output 8 bits */
778/*------------------------------------------------------------------------------- */
779 .globl out8
780out8:
781 stb r4,0x0000(r3)
1487adbd 782 sync
42d1f039
WD
783 blr
784
785/*------------------------------------------------------------------------------- */
786/* Function: out16 */
787/* Description: Output 16 bits */
788/*------------------------------------------------------------------------------- */
789 .globl out16
790out16:
791 sth r4,0x0000(r3)
1487adbd 792 sync
42d1f039
WD
793 blr
794
795/*------------------------------------------------------------------------------- */
796/* Function: out16r */
797/* Description: Byte reverse and output 16 bits */
798/*------------------------------------------------------------------------------- */
799 .globl out16r
800out16r:
801 sthbrx r4,r0,r3
1487adbd 802 sync
42d1f039
WD
803 blr
804
805/*------------------------------------------------------------------------------- */
806/* Function: out32 */
807/* Description: Output 32 bits */
808/*------------------------------------------------------------------------------- */
809 .globl out32
810out32:
811 stw r4,0x0000(r3)
1487adbd 812 sync
42d1f039
WD
813 blr
814
815/*------------------------------------------------------------------------------- */
816/* Function: out32r */
817/* Description: Byte reverse and output 32 bits */
818/*------------------------------------------------------------------------------- */
819 .globl out32r
820out32r:
821 stwbrx r4,r0,r3
1487adbd 822 sync
42d1f039
WD
823 blr
824
825/*------------------------------------------------------------------------------- */
826/* Function: in16 */
827/* Description: Input 16 bits */
828/*------------------------------------------------------------------------------- */
829 .globl in16
830in16:
831 lhz r3,0x0000(r3)
832 blr
833
834/*------------------------------------------------------------------------------- */
835/* Function: in16r */
836/* Description: Input 16 bits and byte reverse */
837/*------------------------------------------------------------------------------- */
838 .globl in16r
839in16r:
840 lhbrx r3,r0,r3
841 blr
842
843/*------------------------------------------------------------------------------- */
844/* Function: in32 */
845/* Description: Input 32 bits */
846/*------------------------------------------------------------------------------- */
847 .globl in32
848in32:
849 lwz 3,0x0000(3)
850 blr
851
852/*------------------------------------------------------------------------------- */
853/* Function: in32r */
854/* Description: Input 32 bits and byte reverse */
855/*------------------------------------------------------------------------------- */
856 .globl in32r
857in32r:
858 lwbrx r3,r0,r3
859 blr
7da53351 860#endif /* !CONFIG_NAND_SPL */
42d1f039 861
42d1f039
WD
862/*------------------------------------------------------------------------------*/
863
d30f9043
KG
864/*
865 * void write_tlb(mas0, mas1, mas2, mas3, mas7)
866 */
867 .globl write_tlb
868write_tlb:
869 mtspr MAS0,r3
870 mtspr MAS1,r4
871 mtspr MAS2,r5
872 mtspr MAS3,r6
873#ifdef CONFIG_ENABLE_36BIT_PHYS
874 mtspr MAS7,r7
875#endif
876 li r3,0
877#ifdef CONFIG_SYS_BOOK3E_HV
878 mtspr MAS8,r3
879#endif
880 isync
881 tlbwe
882 msync
883 isync
884 blr
885
42d1f039
WD
886/*
887 * void relocate_code (addr_sp, gd, addr_moni)
888 *
889 * This "function" does not return, instead it continues in RAM
890 * after relocating the monitor code.
891 *
892 * r3 = dest
893 * r4 = src
894 * r5 = length in bytes
895 * r6 = cachelinesize
896 */
897 .globl relocate_code
898relocate_code:
61a21e98
AF
899 mr r1,r3 /* Set new stack pointer */
900 mr r9,r4 /* Save copy of Init Data pointer */
901 mr r10,r5 /* Save copy of Destination Address */
42d1f039 902
0f8aa159 903 GET_GOT
61a21e98 904 mr r3,r5 /* Destination Address */
6d0f6bcf
JCPV
905 lis r4,CONFIG_SYS_MONITOR_BASE@h /* Source Address */
906 ori r4,r4,CONFIG_SYS_MONITOR_BASE@l
42d1f039
WD
907 lwz r5,GOT(__init_end)
908 sub r5,r5,r4
6d0f6bcf 909 li r6,CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
42d1f039
WD
910
911 /*
912 * Fix GOT pointer:
913 *
6d0f6bcf 914 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
42d1f039
WD
915 *
916 * Offset:
917 */
61a21e98 918 sub r15,r10,r4
42d1f039
WD
919
920 /* First our own GOT */
0f8aa159 921 add r12,r12,r15
42d1f039 922 /* the the one used by the C code */
61a21e98 923 add r30,r30,r15
42d1f039
WD
924
925 /*
926 * Now relocate code
927 */
928
929 cmplw cr1,r3,r4
930 addi r0,r5,3
931 srwi. r0,r0,2
932 beq cr1,4f /* In place copy is not necessary */
933 beq 7f /* Protect against 0 count */
934 mtctr r0
935 bge cr1,2f
936
937 la r8,-4(r4)
938 la r7,-4(r3)
9391: lwzu r0,4(r8)
940 stwu r0,4(r7)
941 bdnz 1b
942 b 4f
943
9442: slwi r0,r0,2
945 add r8,r4,r0
946 add r7,r3,r0
9473: lwzu r0,-4(r8)
948 stwu r0,-4(r7)
949 bdnz 3b
950
951/*
952 * Now flush the cache: note that we must start from a cache aligned
953 * address. Otherwise we might miss one cache line.
954 */
9554: cmpwi r6,0
956 add r5,r3,r5
957 beq 7f /* Always flush prefetch queue in any case */
958 subi r0,r6,1
959 andc r3,r3,r0
960 mr r4,r3
9615: dcbst 0,r4
962 add r4,r4,r6
963 cmplw r4,r5
964 blt 5b
965 sync /* Wait for all dcbst to complete on bus */
966 mr r4,r3
9676: icbi 0,r4
968 add r4,r4,r6
969 cmplw r4,r5
970 blt 6b
9717: sync /* Wait for all icbi to complete on bus */
972 isync
973
7d314992
WD
974 /*
975 * Re-point the IVPR at RAM
976 */
977 mtspr IVPR,r10
99b0d285 978
42d1f039
WD
979/*
980 * We are done. Do not return, instead branch to second part of board
981 * initialization, now running from RAM.
982 */
983
61a21e98 984 addi r0,r10,in_ram - _start + _START_OFFSET
42d1f039
WD
985 mtlr r0
986 blr /* NEVER RETURNS! */
61a21e98 987 .globl in_ram
42d1f039
WD
988in_ram:
989
990 /*
0f8aa159 991 * Relocation Function, r12 point to got2+0x8000
42d1f039
WD
992 *
993 * Adjust got2 pointers, no need to check for 0, this code
994 * already puts a few entries in the table.
995 */
996 li r0,__got2_entries@sectoff@l
997 la r3,GOT(_GOT2_TABLE_)
998 lwz r11,GOT(_GOT2_TABLE_)
999 mtctr r0
1000 sub r11,r3,r11
1001 addi r3,r3,-4
10021: lwzu r0,4(r3)
afc3ba0f
JT
1003 cmpwi r0,0
1004 beq- 2f
42d1f039
WD
1005 add r0,r0,r11
1006 stw r0,0(r3)
afc3ba0f 10072: bdnz 1b
42d1f039
WD
1008
1009 /*
1010 * Now adjust the fixups and the pointers to the fixups
1011 * in case we need to move ourselves again.
1012 */
afc3ba0f 1013 li r0,__fixup_entries@sectoff@l
42d1f039
WD
1014 lwz r3,GOT(_FIXUP_TABLE_)
1015 cmpwi r0,0
1016 mtctr r0
1017 addi r3,r3,-4
1018 beq 4f
10193: lwzu r4,4(r3)
1020 lwzux r0,r4,r11
1021 add r0,r0,r11
1022 stw r10,0(r3)
1023 stw r0,0(r4)
1024 bdnz 3b
10254:
1026clear_bss:
1027 /*
1028 * Now clear BSS segment
1029 */
1030 lwz r3,GOT(__bss_start)
1031 lwz r4,GOT(_end)
1032
61a21e98 1033 cmplw 0,r3,r4
42d1f039
WD
1034 beq 6f
1035
61a21e98 1036 li r0,0
42d1f039 10375:
61a21e98
AF
1038 stw r0,0(r3)
1039 addi r3,r3,4
1040 cmplw 0,r3,r4
42d1f039
WD
1041 bne 5b
10426:
1043
61a21e98
AF
1044 mr r3,r9 /* Init Data pointer */
1045 mr r4,r10 /* Destination Address */
42d1f039
WD
1046 bl board_init_r
1047
7da53351 1048#ifndef CONFIG_NAND_SPL
42d1f039
WD
1049 /*
1050 * Copy exception vector code to low memory
1051 *
1052 * r3: dest_addr
1053 * r7: source address, r8: end address, r9: target address
1054 */
343117bf 1055 .globl trap_init
42d1f039 1056trap_init:
0f8aa159
JT
1057 mflr r4 /* save link register */
1058 GET_GOT
61a21e98
AF
1059 lwz r7,GOT(_start_of_vectors)
1060 lwz r8,GOT(_end_of_vectors)
42d1f039 1061
61a21e98 1062 li r9,0x100 /* reset vector always at 0x100 */
42d1f039 1063
61a21e98 1064 cmplw 0,r7,r8
343117bf 1065 bgelr /* return if r7>=r8 - just in case */
42d1f039 10661:
61a21e98
AF
1067 lwz r0,0(r7)
1068 stw r0,0(r9)
1069 addi r7,r7,4
1070 addi r9,r9,4
1071 cmplw 0,r7,r8
343117bf 1072 bne 1b
42d1f039
WD
1073
1074 /*
1075 * relocate `hdlr' and `int_return' entries
1076 */
61a21e98 1077 li r7,.L_CriticalInput - _start + _START_OFFSET
343117bf 1078 bl trap_reloc
61a21e98 1079 li r7,.L_MachineCheck - _start + _START_OFFSET
343117bf 1080 bl trap_reloc
61a21e98 1081 li r7,.L_DataStorage - _start + _START_OFFSET
343117bf 1082 bl trap_reloc
61a21e98 1083 li r7,.L_InstStorage - _start + _START_OFFSET
343117bf 1084 bl trap_reloc
61a21e98 1085 li r7,.L_ExtInterrupt - _start + _START_OFFSET
343117bf 1086 bl trap_reloc
61a21e98 1087 li r7,.L_Alignment - _start + _START_OFFSET
343117bf 1088 bl trap_reloc
61a21e98 1089 li r7,.L_ProgramCheck - _start + _START_OFFSET
343117bf 1090 bl trap_reloc
61a21e98 1091 li r7,.L_FPUnavailable - _start + _START_OFFSET
343117bf 1092 bl trap_reloc
61a21e98
AF
1093 li r7,.L_Decrementer - _start + _START_OFFSET
1094 bl trap_reloc
1095 li r7,.L_IntervalTimer - _start + _START_OFFSET
1096 li r8,_end_of_vectors - _start + _START_OFFSET
42d1f039 10972:
343117bf 1098 bl trap_reloc
61a21e98
AF
1099 addi r7,r7,0x100 /* next exception vector */
1100 cmplw 0,r7,r8
343117bf
WD
1101 blt 2b
1102
1103 lis r7,0x0
61a21e98 1104 mtspr IVPR,r7
42d1f039 1105
343117bf 1106 mtlr r4 /* restore link register */
42d1f039
WD
1107 blr
1108
42d1f039
WD
1109.globl unlock_ram_in_cache
1110unlock_ram_in_cache:
1111 /* invalidate the INIT_RAM section */
a38a5b6e
KG
1112 lis r3,(CONFIG_SYS_INIT_RAM_ADDR & ~(CONFIG_SYS_CACHELINE_SIZE-1))@h
1113 ori r3,r3,(CONFIG_SYS_INIT_RAM_ADDR & ~(CONFIG_SYS_CACHELINE_SIZE-1))@l
b009f3ec
KG
1114 mfspr r4,L1CFG0
1115 andi. r4,r4,0x1ff
1116 slwi r4,r4,(10 - 1 - L1_CACHE_SHIFT)
61a21e98 1117 mtctr r4
2b22fa4b 11181: dcbi r0,r3
6d0f6bcf 1119 addi r3,r3,CONFIG_SYS_CACHELINE_SIZE
42d1f039 1120 bdnz 1b
2b22fa4b 1121 sync
21fae8b2
AF
1122
1123 /* Invalidate the TLB entries for the cache */
6d0f6bcf
JCPV
1124 lis r3,CONFIG_SYS_INIT_RAM_ADDR@h
1125 ori r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l
21fae8b2
AF
1126 tlbivax 0,r3
1127 addi r3,r3,0x1000
1128 tlbivax 0,r3
1129 addi r3,r3,0x1000
1130 tlbivax 0,r3
1131 addi r3,r3,0x1000
1132 tlbivax 0,r3
42d1f039
WD
1133 isync
1134 blr
54e091d3
KG
1135
1136.globl flush_dcache
1137flush_dcache:
1138 mfspr r3,SPRN_L1CFG0
1139
1140 rlwinm r5,r3,9,3 /* Extract cache block size */
1141 twlgti r5,1 /* Only 32 and 64 byte cache blocks
1142 * are currently defined.
1143 */
1144 li r4,32
1145 subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) -
1146 * log2(number of ways)
1147 */
1148 slw r5,r4,r5 /* r5 = cache block size */
1149
1150 rlwinm r7,r3,0,0xff /* Extract number of KiB in the cache */
1151 mulli r7,r7,13 /* An 8-way cache will require 13
1152 * loads per set.
1153 */
1154 slw r7,r7,r6
1155
1156 /* save off HID0 and set DCFA */
1157 mfspr r8,SPRN_HID0
1158 ori r9,r8,HID0_DCFA@l
1159 mtspr SPRN_HID0,r9
1160 isync
1161
1162 lis r4,0
1163 mtctr r7
1164
11651: lwz r3,0(r4) /* Load... */
1166 add r4,r4,r5
1167 bdnz 1b
1168
1169 msync
1170 lis r4,0
1171 mtctr r7
1172
11731: dcbf 0,r4 /* ...and flush. */
1174 add r4,r4,r5
1175 bdnz 1b
1176
1177 /* restore HID0 */
1178 mtspr SPRN_HID0,r8
1179 isync
1180
1181 blr
26f4cdba
KG
1182
1183.globl setup_ivors
1184setup_ivors:
1185
1186#include "fixed_ivor.S"
1187 blr
7da53351 1188#endif /* !CONFIG_NAND_SPL */