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