]> git.ipfire.org Git - thirdparty/u-boot.git/blame - arch/powerpc/cpu/mpc86xx/start.S
Add GPL-2.0+ SPDX-License-Identifier to source files
[thirdparty/u-boot.git] / arch / powerpc / cpu / mpc86xx / start.S
CommitLineData
debb7354 1/*
1605cc9e 2 * Copyright 2004, 2007, 2011 Freescale Semiconductor.
debb7354
JL
3 * Srikanth Srinivasan <srikanth.srinivaan@freescale.com>
4 *
1a459660 5 * SPDX-License-Identifier: GPL-2.0+
debb7354
JL
6 */
7
8/* U-Boot - Startup Code for 86xx PowerPC based Embedded Boards
9 *
10 *
11 * The processor starts at 0xfff00100 and the code is executed
12 * from flash. The code is organized to be at an other address
13 * in memory, but as long we don't jump around before relocating.
14 * board_init lies at a quite high address and when the cpu has
15 * jumped there, everything is ok.
16 */
25ddd1fb 17#include <asm-offsets.h>
debb7354
JL
18#include <config.h>
19#include <mpc86xx.h>
20#include <version.h>
21
22#include <ppc_asm.tmpl>
23#include <ppc_defs.h>
24
25#include <asm/cache.h>
26#include <asm/mmu.h>
d98b0523 27#include <asm/u-boot.h>
debb7354 28
cfc7a7f5
JL
29/*
30 * Need MSR_DR | MSR_IR enabled to access I/O (printf) in exceptions
31 */
debb7354
JL
32
33/*
34 * Set up GOT: Global Offset Table
35 *
0f8aa159 36 * Use r12 to access the GOT
debb7354
JL
37 */
38 START_GOT
39 GOT_ENTRY(_GOT2_TABLE_)
40 GOT_ENTRY(_FIXUP_TABLE_)
41
42 GOT_ENTRY(_start)
43 GOT_ENTRY(_start_of_vectors)
44 GOT_ENTRY(_end_of_vectors)
45 GOT_ENTRY(transfer_to_handler)
46
47 GOT_ENTRY(__init_end)
3929fb0a 48 GOT_ENTRY(__bss_end)
debb7354
JL
49 GOT_ENTRY(__bss_start)
50 END_GOT
51
52/*
53 * r3 - 1st arg to board_init(): IMMP pointer
54 * r4 - 2nd arg to board_init(): boot flag
55 */
56 .text
ffff3ae5 57 .long 0x27051956 /* U-Boot Magic Number */
debb7354
JL
58 .globl version_string
59version_string:
09c2e90c 60 .ascii U_BOOT_VERSION_STRING, "\0"
debb7354
JL
61
62 . = EXC_OFF_SYS_RESET
63 .globl _start
64_start:
debb7354 65 b boot_cold
debb7354
JL
66
67 /* the boot code is located below the exception table */
68
69 .globl _start_of_vectors
70_start_of_vectors:
71
72/* Machine check */
73 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
74
75/* Data Storage exception. */
76 STD_EXCEPTION(0x300, DataStorage, UnknownException)
77
78/* Instruction Storage exception. */
79 STD_EXCEPTION(0x400, InstStorage, UnknownException)
80
81/* External Interrupt exception. */
82 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
83
84/* Alignment exception. */
85 . = 0x600
86Alignment:
02032e8f 87 EXCEPTION_PROLOG(SRR0, SRR1)
debb7354
JL
88 mfspr r4,DAR
89 stw r4,_DAR(r21)
90 mfspr r5,DSISR
91 stw r5,_DSISR(r21)
92 addi r3,r1,STACK_FRAME_OVERHEAD
fc4e1887 93 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
debb7354
JL
94
95/* Program check exception */
96 . = 0x700
97ProgramCheck:
02032e8f 98 EXCEPTION_PROLOG(SRR0, SRR1)
debb7354 99 addi r3,r1,STACK_FRAME_OVERHEAD
fc4e1887
JT
100 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
101 MSR_KERNEL, COPY_EE)
debb7354
JL
102
103 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
104
105 /* I guess we could implement decrementer, and may have
106 * to someday for timekeeping.
107 */
108 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
109 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
110 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
111 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
112 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
113 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
114 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
115 STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException)
116 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
117 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
118 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
119 STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
120 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
121 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
122 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
123 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
124 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
125 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
126 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
127 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
128 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
129 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
130 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
131
132 .globl _end_of_vectors
133_end_of_vectors:
134
135 . = 0x2000
136
137boot_cold:
1266df88
BB
138 /*
139 * NOTE: Only Cpu 0 will ever come here. Other cores go to an
140 * address specified by the BPTR
141 */
cfc7a7f5 1421:
6d0f6bcf 143#ifdef CONFIG_SYS_RAMBOOT
debb7354 144 /* disable everything */
cfc7a7f5 145 li r0, 0
debb7354
JL
146 mtspr HID0, r0
147 sync
148 mtmsr 0
cfc7a7f5
JL
149#endif
150
dc2adad8 151 /* Invalidate BATs */
debb7354
JL
152 bl invalidate_bats
153 sync
dc2adad8
DL
154 /* Invalidate all of TLB before MMU turn on */
155 bl clear_tlbs
156 sync
ffff3ae5 157
6d0f6bcf 158#ifdef CONFIG_SYS_L2
debb7354 159 /* init the L2 cache */
cfc7a7f5 160 lis r3, L2_INIT@h
debb7354 161 ori r3, r3, L2_INIT@l
ffff3ae5 162 mtspr l2cr, r3
debb7354
JL
163 /* invalidate the L2 cache */
164 bl l2cache_invalidate
165 sync
166#endif
ffff3ae5 167
debb7354
JL
168 /*
169 * Calculate absolute address in FLASH and jump there
170 *------------------------------------------------------*/
bf9a8c34
BB
171 lis r3, CONFIG_SYS_MONITOR_BASE_EARLY@h
172 ori r3, r3, CONFIG_SYS_MONITOR_BASE_EARLY@l
debb7354
JL
173 addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
174 mtlr r3
175 blr
176
177in_flash:
178 /* let the C-code set up the rest */
179 /* */
180 /* Be careful to keep code relocatable ! */
181 /*------------------------------------------------------*/
182 /* perform low-level init */
183
184 /* enable extended addressing */
185 bl enable_ext_addr
ffff3ae5 186
debb7354 187 /* setup the bats */
1a41f7ce 188 bl early_bats
ffff3ae5 189
debb7354
JL
190 /*
191 * Cache must be enabled here for stack-in-cache trick.
192 * This means we need to enable the BATS.
193 * Cache should be turned on after BATs, since by default
194 * everything is write-through.
195 */
196
197 /* enable address translation */
c1e1cf69
BB
198 mfmsr r5
199 ori r5, r5, (MSR_IR | MSR_DR)
200 lis r3,addr_trans_enabled@h
201 ori r3, r3, addr_trans_enabled@l
202 mtspr SPRN_SRR0,r3
203 mtspr SPRN_SRR1,r5
204 rfi
debb7354 205
c1e1cf69 206addr_trans_enabled:
debb7354
JL
207 /* enable and invalidate the data cache */
208/* bl l1dcache_enable */
47a6989c 209 bl dcache_enable
debb7354
JL
210 sync
211
212#if 1
213 bl icache_enable
214#endif
ffff3ae5 215
6d0f6bcf 216#ifdef CONFIG_SYS_INIT_RAM_LOCK
debb7354
JL
217 bl lock_ram_in_cache
218 sync
219#endif
220
3111d32c
BB
221#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
222 bl setup_ccsrbar
223#endif
224
debb7354
JL
225 /* set up the stack pointer in our newly created
226 * cache-ram (r1) */
6d0f6bcf
JCPV
227 lis r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@h
228 ori r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@l
debb7354 229
47a6989c 230 li r0, 0 /* Make room for stack frame header and */
debb7354
JL
231 stwu r0, -4(r1) /* clear final stack frame so that */
232 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
233
234 GET_GOT /* initialize GOT access */
8c4734e9 235
47a6989c 236 /* run low-level CPU init code (from Flash) */
debb7354
JL
237 bl cpu_init_f
238 sync
239
47a6989c 240#ifdef RUN_DIAG
debb7354 241
47a6989c 242 /* Load PX_AUX register address in r4 */
c759a01a 243 lis r4, PIXIS_BASE@h
47a6989c
WD
244 ori r4, r4, 0x6
245 /* Load contents of PX_AUX in r3 bits 24 to 31*/
246 lbz r3, 0(r4)
debb7354 247
47a6989c
WD
248 /* Mask and obtain the bit in r3 */
249 rlwinm. r3, r3, 0, 24, 24
250 /* If not zero, jump and continue with u-boot */
251 bne diag_done
debb7354 252
47a6989c
WD
253 /* Load back contents of PX_AUX in r3 bits 24 to 31 */
254 lbz r3, 0(r4)
255 /* Set the MSB of the register value */
256 ori r3, r3, 0x80
257 /* Write value in r3 back to PX_AUX */
258 stb r3, 0(r4)
debb7354 259
47a6989c 260 /* Get the address to jump to in r3*/
6d0f6bcf
JCPV
261 lis r3, CONFIG_SYS_DIAG_ADDR@h
262 ori r3, r3, CONFIG_SYS_DIAG_ADDR@l
debb7354 263
47a6989c
WD
264 /* Load the LR with the branch address */
265 mtlr r3
debb7354 266
47a6989c
WD
267 /* Branch to diagnostic */
268 blr
ffff3ae5
JL
269
270diag_done:
271#endif
debb7354 272
47a6989c 273/* bl l2cache_enable */
debb7354 274
47a6989c 275 /* run 1st part of board init code (from Flash) */
debb7354
JL
276 bl board_init_f
277 sync
278
52ebd9c1 279 /* NOTREACHED - board_init_f() does not return */
debb7354
JL
280
281 .globl invalidate_bats
282invalidate_bats:
ffff3ae5 283
cfc7a7f5 284 li r0, 0
debb7354
JL
285 /* invalidate BATs */
286 mtspr IBAT0U, r0
287 mtspr IBAT1U, r0
288 mtspr IBAT2U, r0
289 mtspr IBAT3U, r0
47a6989c
WD
290 mtspr IBAT4U, r0
291 mtspr IBAT5U, r0
292 mtspr IBAT6U, r0
293 mtspr IBAT7U, r0
debb7354
JL
294
295 isync
296 mtspr DBAT0U, r0
297 mtspr DBAT1U, r0
298 mtspr DBAT2U, r0
299 mtspr DBAT3U, r0
47a6989c
WD
300 mtspr DBAT4U, r0
301 mtspr DBAT5U, r0
302 mtspr DBAT6U, r0
303 mtspr DBAT7U, r0
debb7354
JL
304
305 isync
306 sync
307 blr
ffff3ae5 308
1605cc9e
BB
309#define CONFIG_BAT_PAIR(n) \
310 lis r4, CONFIG_SYS_IBAT##n##L@h; \
311 ori r4, r4, CONFIG_SYS_IBAT##n##L@l; \
312 lis r3, CONFIG_SYS_IBAT##n##U@h; \
313 ori r3, r3, CONFIG_SYS_IBAT##n##U@l; \
314 mtspr IBAT##n##L, r4; \
315 mtspr IBAT##n##U, r3; \
316 lis r4, CONFIG_SYS_DBAT##n##L@h; \
317 ori r4, r4, CONFIG_SYS_DBAT##n##L@l; \
318 lis r3, CONFIG_SYS_DBAT##n##U@h; \
319 ori r3, r3, CONFIG_SYS_DBAT##n##U@l; \
320 mtspr DBAT##n##L, r4; \
321 mtspr DBAT##n##U, r3;
322
323/*
324 * setup_bats:
325 *
326 * Set up the final BAT registers now that setup is done.
327 *
328 * Assumes that:
329 * 1) Address translation is enabled upon entry
330 * 2) The boot rom is still accessible via 1:1 translation
331 */
332 .globl setup_bats
333setup_bats:
334 mflr r5
335 sync
336
337 /*
338 * When we disable address translation, we will get 1:1 (VA==PA)
339 * translation. The only place we know for sure is safe for that is
340 * the bootrom where we originally started out. Pop back into there.
341 */
342 lis r4, CONFIG_SYS_MONITOR_BASE_EARLY@h
343 ori r4, r4, CONFIG_SYS_MONITOR_BASE_EARLY@l
344 addi r4, r4, trans_disabled - _start + EXC_OFF_SYS_RESET
345
346 /* disable address translation */
347 mfmsr r3
348 rlwinm r3, r3, 0, 28, 25
349 mtspr SRR0, r4
350 mtspr SRR1, r3
351 rfi
352
353trans_disabled:
354#if defined(CONFIG_SYS_DBAT0U) && defined(CONFIG_SYS_DBAT0L) \
355 && defined(CONFIG_SYS_IBAT0U) && defined(CONFIG_SYS_IBAT0L)
356 CONFIG_BAT_PAIR(0)
357#endif
358 CONFIG_BAT_PAIR(1)
359 CONFIG_BAT_PAIR(2)
360 CONFIG_BAT_PAIR(3)
361 CONFIG_BAT_PAIR(4)
362 CONFIG_BAT_PAIR(5)
363 CONFIG_BAT_PAIR(6)
364 CONFIG_BAT_PAIR(7)
365
366 sync
367 isync
368
369 /* Turn translation back on and return */
370 mfmsr r3
371 ori r3, r3, (MSR_IR | MSR_DR)
372 mtspr SPRN_SRR0,r5
373 mtspr SPRN_SRR1,r3
374 rfi
375
1a41f7ce
BB
376/*
377 * early_bats:
378 *
379 * Set up bats needed early on - this is usually the BAT for the
104992fc 380 * stack-in-cache, the Flash, and CCSR space
1a41f7ce
BB
381 */
382 .globl early_bats
383early_bats:
104992fc
BB
384 /* IBAT 3 */
385 lis r4, CONFIG_SYS_IBAT3L@h
386 ori r4, r4, CONFIG_SYS_IBAT3L@l
387 lis r3, CONFIG_SYS_IBAT3U@h
388 ori r3, r3, CONFIG_SYS_IBAT3U@l
389 mtspr IBAT3L, r4
390 mtspr IBAT3U, r3
391 isync
392
393 /* DBAT 3 */
394 lis r4, CONFIG_SYS_DBAT3L@h
395 ori r4, r4, CONFIG_SYS_DBAT3L@l
396 lis r3, CONFIG_SYS_DBAT3U@h
397 ori r3, r3, CONFIG_SYS_DBAT3U@l
398 mtspr DBAT3L, r4
399 mtspr DBAT3U, r3
400 isync
401
1a41f7ce 402 /* IBAT 5 */
6d0f6bcf
JCPV
403 lis r4, CONFIG_SYS_IBAT5L@h
404 ori r4, r4, CONFIG_SYS_IBAT5L@l
405 lis r3, CONFIG_SYS_IBAT5U@h
406 ori r3, r3, CONFIG_SYS_IBAT5U@l
1a41f7ce
BB
407 mtspr IBAT5L, r4
408 mtspr IBAT5U, r3
debb7354
JL
409 isync
410
1a41f7ce 411 /* DBAT 5 */
6d0f6bcf
JCPV
412 lis r4, CONFIG_SYS_DBAT5L@h
413 ori r4, r4, CONFIG_SYS_DBAT5L@l
414 lis r3, CONFIG_SYS_DBAT5U@h
415 ori r3, r3, CONFIG_SYS_DBAT5U@l
1a41f7ce
BB
416 mtspr DBAT5L, r4
417 mtspr DBAT5U, r3
418 isync
419
420 /* IBAT 6 */
bf9a8c34
BB
421 lis r4, CONFIG_SYS_IBAT6L_EARLY@h
422 ori r4, r4, CONFIG_SYS_IBAT6L_EARLY@l
423 lis r3, CONFIG_SYS_IBAT6U_EARLY@h
424 ori r3, r3, CONFIG_SYS_IBAT6U_EARLY@l
1a41f7ce
BB
425 mtspr IBAT6L, r4
426 mtspr IBAT6U, r3
debb7354
JL
427 isync
428
1a41f7ce 429 /* DBAT 6 */
bf9a8c34
BB
430 lis r4, CONFIG_SYS_DBAT6L_EARLY@h
431 ori r4, r4, CONFIG_SYS_DBAT6L_EARLY@l
432 lis r3, CONFIG_SYS_DBAT6U_EARLY@h
433 ori r3, r3, CONFIG_SYS_DBAT6U_EARLY@l
1a41f7ce
BB
434 mtspr DBAT6L, r4
435 mtspr DBAT6U, r3
436 isync
3111d32c
BB
437
438#if(CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
439 /* IBAT 7 */
440 lis r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@h
441 ori r4, r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@l
442 lis r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@h
443 ori r3, r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@l
444 mtspr IBAT7L, r4
445 mtspr IBAT7U, r3
446 isync
447
448 /* DBAT 7 */
449 lis r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@h
450 ori r4, r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@l
451 lis r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@h
452 ori r3, r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@l
453 mtspr DBAT7L, r4
454 mtspr DBAT7U, r3
455 isync
456#endif
1a41f7ce
BB
457 blr
458
459 .globl clear_tlbs
460clear_tlbs:
461 addis r3, 0, 0x0000
462 addis r5, 0, 0x4
463 isync
debb7354 464tlblp:
1a41f7ce 465 tlbie r3
debb7354 466 sync
1a41f7ce
BB
467 addi r3, r3, 0x1000
468 cmp 0, 0, r3, r5
debb7354 469 blt tlblp
debb7354
JL
470 blr
471
debb7354
JL
472 .globl disable_addr_trans
473disable_addr_trans:
474 /* disable address translation */
475 mflr r4
476 mfmsr r3
477 andi. r0, r3, (MSR_IR | MSR_DR)
478 beqlr
479 andc r3, r3, r0
480 mtspr SRR0, r4
481 mtspr SRR1, r3
482 rfi
483
484/*
485 * This code finishes saving the registers to the exception frame
486 * and jumps to the appropriate handler for the exception.
487 * Register r21 is pointer into trap frame, r1 has new stack pointer.
488 */
489 .globl transfer_to_handler
490transfer_to_handler:
491 stw r22,_NIP(r21)
492 lis r22,MSR_POW@h
493 andc r23,r23,r22
494 stw r23,_MSR(r21)
495 SAVE_GPR(7, r21)
496 SAVE_4GPRS(8, r21)
497 SAVE_8GPRS(12, r21)
498 SAVE_8GPRS(24, r21)
499 mflr r23
500 andi. r24,r23,0x3f00 /* get vector offset */
501 stw r24,TRAP(r21)
502 li r22,0
503 stw r22,RESULT(r21)
504 mtspr SPRG2,r22 /* r1 is now kernel sp */
505 lwz r24,0(r23) /* virtual address of handler */
506 lwz r23,4(r23) /* where to go when done */
507 mtspr SRR0,r24
508 mtspr SRR1,r20
509 mtlr r23
510 SYNC
511 rfi /* jump to handler, enable MMU */
512
513int_return:
514 mfmsr r28 /* Disable interrupts */
515 li r4,0
516 ori r4,r4,MSR_EE
517 andc r28,r28,r4
518 SYNC /* Some chip revs need this... */
519 mtmsr r28
520 SYNC
521 lwz r2,_CTR(r1)
522 lwz r0,_LINK(r1)
523 mtctr r2
524 mtlr r0
525 lwz r2,_XER(r1)
526 lwz r0,_CCR(r1)
527 mtspr XER,r2
528 mtcrf 0xFF,r0
529 REST_10GPRS(3, r1)
530 REST_10GPRS(13, r1)
531 REST_8GPRS(23, r1)
532 REST_GPR(31, r1)
533 lwz r2,_NIP(r1) /* Restore environment */
534 lwz r0,_MSR(r1)
535 mtspr SRR0,r2
536 mtspr SRR1,r0
537 lwz r0,GPR0(r1)
538 lwz r2,GPR2(r1)
539 lwz r1,GPR1(r1)
540 SYNC
541 rfi
542
543 .globl dc_read
544dc_read:
545 blr
546
547 .globl get_pvr
548get_pvr:
549 mfspr r3, PVR
550 blr
551
552 .globl get_svr
553get_svr:
554 mfspr r3, SVR
555 blr
556
557
ffff3ae5 558/*
47a6989c
WD
559 * Function: in8
560 * Description: Input 8 bits
ffff3ae5 561 */
debb7354
JL
562 .globl in8
563in8:
564 lbz r3,0x0000(r3)
565 blr
566
ffff3ae5 567/*
47a6989c
WD
568 * Function: out8
569 * Description: Output 8 bits
ffff3ae5 570 */
debb7354
JL
571 .globl out8
572out8:
573 stb r4,0x0000(r3)
574 blr
575
ffff3ae5 576/*
47a6989c
WD
577 * Function: out16
578 * Description: Output 16 bits
ffff3ae5 579 */
debb7354
JL
580 .globl out16
581out16:
582 sth r4,0x0000(r3)
583 blr
584
ffff3ae5 585/*
47a6989c
WD
586 * Function: out16r
587 * Description: Byte reverse and output 16 bits
ffff3ae5 588 */
debb7354
JL
589 .globl out16r
590out16r:
591 sthbrx r4,r0,r3
592 blr
593
ffff3ae5 594/*
47a6989c
WD
595 * Function: out32
596 * Description: Output 32 bits
ffff3ae5 597 */
debb7354
JL
598 .globl out32
599out32:
600 stw r4,0x0000(r3)
601 blr
602
ffff3ae5 603/*
47a6989c
WD
604 * Function: out32r
605 * Description: Byte reverse and output 32 bits
ffff3ae5 606 */
debb7354
JL
607 .globl out32r
608out32r:
609 stwbrx r4,r0,r3
610 blr
611
ffff3ae5 612/*
47a6989c
WD
613 * Function: in16
614 * Description: Input 16 bits
ffff3ae5 615 */
debb7354
JL
616 .globl in16
617in16:
618 lhz r3,0x0000(r3)
619 blr
620
ffff3ae5 621/*
47a6989c
WD
622 * Function: in16r
623 * Description: Input 16 bits and byte reverse
ffff3ae5 624 */
debb7354
JL
625 .globl in16r
626in16r:
627 lhbrx r3,r0,r3
628 blr
629
ffff3ae5 630/*
47a6989c
WD
631 * Function: in32
632 * Description: Input 32 bits
ffff3ae5 633 */
debb7354
JL
634 .globl in32
635in32:
636 lwz 3,0x0000(3)
637 blr
638
ffff3ae5 639/*
47a6989c
WD
640 * Function: in32r
641 * Description: Input 32 bits and byte reverse
ffff3ae5 642 */
debb7354
JL
643 .globl in32r
644in32r:
645 lwbrx r3,r0,r3
646 blr
647
debb7354
JL
648/*
649 * void relocate_code (addr_sp, gd, addr_moni)
650 *
651 * This "function" does not return, instead it continues in RAM
652 * after relocating the monitor code.
653 *
654 * r3 = dest
655 * r4 = src
656 * r5 = length in bytes
657 * r6 = cachelinesize
658 */
659 .globl relocate_code
660relocate_code:
661
47a6989c 662 mr r1, r3 /* Set new stack pointer */
debb7354
JL
663 mr r9, r4 /* Save copy of Global Data pointer */
664 mr r10, r5 /* Save copy of Destination Address */
67256678 665
0f8aa159 666 GET_GOT
debb7354 667 mr r3, r5 /* Destination Address */
6d0f6bcf
JCPV
668 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
669 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
debb7354
JL
670 lwz r5, GOT(__init_end)
671 sub r5, r5, r4
6d0f6bcf 672 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
debb7354
JL
673
674 /*
675 * Fix GOT pointer:
676 *
6d0f6bcf 677 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
debb7354
JL
678 *
679 * Offset:
680 */
681 sub r15, r10, r4
682
683 /* First our own GOT */
0f8aa159 684 add r12, r12, r15
debb7354
JL
685 /* then the one used by the C code */
686 add r30, r30, r15
687
688 /*
689 * Now relocate code
690 */
debb7354
JL
691 cmplw cr1,r3,r4
692 addi r0,r5,3
693 srwi. r0,r0,2
694 beq cr1,4f /* In place copy is not necessary */
695 beq 7f /* Protect against 0 count */
696 mtctr r0
697 bge cr1,2f
698
699 la r8,-4(r4)
700 la r7,-4(r3)
7011: lwzu r0,4(r8)
702 stwu r0,4(r7)
703 bdnz 1b
704 b 4f
705
7062: slwi r0,r0,2
707 add r8,r4,r0
708 add r7,r3,r0
7093: lwzu r0,-4(r8)
710 stwu r0,-4(r7)
711 bdnz 3b
debb7354
JL
712/*
713 * Now flush the cache: note that we must start from a cache aligned
714 * address. Otherwise we might miss one cache line.
715 */
7164: cmpwi r6,0
717 add r5,r3,r5
718 beq 7f /* Always flush prefetch queue in any case */
719 subi r0,r6,1
720 andc r3,r3,r0
721 mr r4,r3
7225: dcbst 0,r4
723 add r4,r4,r6
724 cmplw r4,r5
725 blt 5b
726 sync /* Wait for all dcbst to complete on bus */
727 mr r4,r3
7286: icbi 0,r4
729 add r4,r4,r6
730 cmplw r4,r5
731 blt 6b
47a6989c 7327: sync /* Wait for all icbi to complete on bus */
debb7354
JL
733 isync
734
735/*
736 * We are done. Do not return, instead branch to second part of board
737 * initialization, now running from RAM.
738 */
739 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
740 mtlr r0
741 blr
742
743in_ram:
debb7354 744 /*
0f8aa159 745 * Relocation Function, r12 point to got2+0x8000
debb7354
JL
746 *
747 * Adjust got2 pointers, no need to check for 0, this code
748 * already puts a few entries in the table.
749 */
750 li r0,__got2_entries@sectoff@l
751 la r3,GOT(_GOT2_TABLE_)
752 lwz r11,GOT(_GOT2_TABLE_)
753 mtctr r0
754 sub r11,r3,r11
755 addi r3,r3,-4
7561: lwzu r0,4(r3)
afc3ba0f
JT
757 cmpwi r0,0
758 beq- 2f
debb7354
JL
759 add r0,r0,r11
760 stw r0,0(r3)
afc3ba0f 7612: bdnz 1b
debb7354
JL
762
763 /*
764 * Now adjust the fixups and the pointers to the fixups
765 * in case we need to move ourselves again.
766 */
afc3ba0f 767 li r0,__fixup_entries@sectoff@l
debb7354
JL
768 lwz r3,GOT(_FIXUP_TABLE_)
769 cmpwi r0,0
770 mtctr r0
771 addi r3,r3,-4
772 beq 4f
7733: lwzu r4,4(r3)
774 lwzux r0,r4,r11
d1e0b10a 775 cmpwi r0,0
debb7354 776 add r0,r0,r11
34bbf618 777 stw r4,0(r3)
d1e0b10a 778 beq- 5f
debb7354 779 stw r0,0(r4)
d1e0b10a 7805: bdnz 3b
debb7354
JL
7814:
782/* clear_bss: */
783 /*
784 * Now clear BSS segment
785 */
786 lwz r3,GOT(__bss_start)
3929fb0a 787 lwz r4,GOT(__bss_end)
debb7354
JL
788
789 cmplw 0, r3, r4
790 beq 6f
791
792 li r0, 0
7935:
794 stw r0, 0(r3)
795 addi r3, r3, 4
796 cmplw 0, r3, r4
797 bne 5b
7986:
6cfea334
HW
799 mr r3, r9 /* Init Date pointer */
800 mr r4, r10 /* Destination Address */
801 bl board_init_r
debb7354
JL
802
803 /* not reached - end relocate_code */
804/*-----------------------------------------------------------------------*/
805
806 /*
807 * Copy exception vector code to low memory
808 *
809 * r3: dest_addr
810 * r7: source address, r8: end address, r9: target address
811 */
812 .globl trap_init
813trap_init:
0f8aa159
JT
814 mflr r4 /* save link register */
815 GET_GOT
debb7354
JL
816 lwz r7, GOT(_start)
817 lwz r8, GOT(_end_of_vectors)
818
819 li r9, 0x100 /* reset vector always at 0x100 */
820
821 cmplw 0, r7, r8
822 bgelr /* return if r7>=r8 - just in case */
debb7354
JL
8231:
824 lwz r0, 0(r7)
825 stw r0, 0(r9)
826 addi r7, r7, 4
827 addi r9, r9, 4
828 cmplw 0, r7, r8
829 bne 1b
830
831 /*
832 * relocate `hdlr' and `int_return' entries
833 */
834 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
835 li r8, Alignment - _start + EXC_OFF_SYS_RESET
8362:
837 bl trap_reloc
838 addi r7, r7, 0x100 /* next exception vector */
839 cmplw 0, r7, r8
840 blt 2b
841
842 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
843 bl trap_reloc
844
845 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
846 bl trap_reloc
847
848 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
849 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
8503:
851 bl trap_reloc
852 addi r7, r7, 0x100 /* next exception vector */
853 cmplw 0, r7, r8
854 blt 3b
855
856 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
857 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
8584:
859 bl trap_reloc
860 addi r7, r7, 0x100 /* next exception vector */
861 cmplw 0, r7, r8
862 blt 4b
863
864 /* enable execptions from RAM vectors */
865 mfmsr r7
866 li r8,MSR_IP
867 andc r7,r7,r8
cfc7a7f5 868 ori r7,r7,MSR_ME /* Enable Machine Check */
debb7354
JL
869 mtmsr r7
870
871 mtlr r4 /* restore link register */
872 blr
873
debb7354
JL
874.globl enable_ext_addr
875enable_ext_addr:
876 mfspr r0, HID0
47a6989c 877 lis r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h
debb7354 878 ori r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l
47a6989c 879 mtspr HID0, r0
debb7354
JL
880 sync
881 isync
882 blr
883
6d0f6bcf 884#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
debb7354 885.globl setup_ccsrbar
ffff3ae5 886setup_ccsrbar:
debb7354 887 /* Special sequence needed to update CCSRBAR itself */
6d0f6bcf
JCPV
888 lis r4, CONFIG_SYS_CCSRBAR_DEFAULT@h
889 ori r4, r4, CONFIG_SYS_CCSRBAR_DEFAULT@l
debb7354 890
3111d32c
BB
891 lis r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@h
892 ori r5, r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@l
893 srwi r5,r5,12
894 li r6, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l
895 rlwimi r5,r6,20,8,11
896 stw r5, 0(r4) /* Store physical value of CCSR */
debb7354
JL
897 isync
898
14d0a02a
WD
899 lis r5, CONFIG_SYS_TEXT_BASE@h
900 ori r5,r5,CONFIG_SYS_TEXT_BASE@l
debb7354
JL
901 lwz r5, 0(r5)
902 isync
903
3111d32c 904 /* Use VA of CCSR to do read */
6d0f6bcf
JCPV
905 lis r3, CONFIG_SYS_CCSRBAR@h
906 lwz r5, CONFIG_SYS_CCSRBAR@l(r3)
debb7354 907 isync
ffff3ae5 908
debb7354
JL
909 blr
910#endif
ffff3ae5 911
6d0f6bcf 912#ifdef CONFIG_SYS_INIT_RAM_LOCK
debb7354
JL
913lock_ram_in_cache:
914 /* Allocate Initial RAM in data cache.
915 */
6d0f6bcf
JCPV
916 lis r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
917 ori r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
553f0982 918 li r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \
6d0f6bcf 919 (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
39243840 920 mtctr r4
debb7354
JL
9211:
922 dcbz r0, r3
923 addi r3, r3, 32
924 bdnz 1b
925#if 1
926/* Lock the data cache */
927 mfspr r0, HID0
928 ori r0, r0, 0x1000
929 sync
930 mtspr HID0, r0
931 sync
932 blr
933#endif
934#if 0
935 /* Lock the first way of the data cache */
936 mfspr r0, LDSTCR
937 ori r0, r0, 0x0080
938#if defined(CONFIG_ALTIVEC)
939 dssall
940#endif
941 sync
942 mtspr LDSTCR, r0
943 sync
944 isync
945 blr
946#endif
ffff3ae5 947
debb7354
JL
948.globl unlock_ram_in_cache
949unlock_ram_in_cache:
950 /* invalidate the INIT_RAM section */
6d0f6bcf
JCPV
951 lis r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
952 ori r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
553f0982 953 li r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \
6d0f6bcf 954 (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
39243840 955 mtctr r4
debb7354
JL
9561: icbi r0, r3
957 addi r3, r3, 32
958 bdnz 1b
47a6989c 959 sync /* Wait for all icbi to complete on bus */
debb7354
JL
960 isync
961#if 1
962/* Unlock the data cache and invalidate it */
47a6989c
WD
963 mfspr r0, HID0
964 li r3,0x1000
965 andc r0,r0,r3
debb7354
JL
966 li r3,0x0400
967 or r0,r0,r3
968 sync
47a6989c 969 mtspr HID0, r0
debb7354
JL
970 sync
971 blr
972#endif
ffff3ae5 973#if 0
debb7354 974 /* Unlock the first way of the data cache */
47a6989c
WD
975 mfspr r0, LDSTCR
976 li r3,0x0080
977 andc r0,r0,r3
debb7354
JL
978#ifdef CONFIG_ALTIVEC
979 dssall
980#endif
981 sync
47a6989c 982 mtspr LDSTCR, r0
debb7354
JL
983 sync
984 isync
985 li r3,0x0400
986 or r0,r0,r3
987 sync
47a6989c 988 mtspr HID0, r0
debb7354
JL
989 sync
990 blr
991#endif
992#endif