]> git.ipfire.org Git - people/ms/u-boot.git/blame - cpu/mpc86xx/start.S
Cleanup compiler warnings.
[people/ms/u-boot.git] / cpu / mpc86xx / start.S
CommitLineData
debb7354
JL
1/*
2 * Copyright 2004 Freescale Semiconductor.
3 * Srikanth Srinivasan <srikanth.srinivaan@freescale.com>
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 86xx PowerPC based Embedded Boards
25 *
26 *
27 * The processor starts at 0xfff00100 and the code is executed
28 * from flash. The code is organized to be at an other address
29 * in memory, but as long we don't jump around before relocating.
30 * board_init lies at a quite high address and when the cpu has
31 * jumped there, everything is ok.
32 */
33#include <config.h>
34#include <mpc86xx.h>
35#include <version.h>
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/* We don't want the MMU yet.
48*/
49#undef MSR_KERNEL
50/* Machine Check and Recoverable Interr. */
51#define MSR_KERNEL ( MSR_ME | MSR_RI )
52
53/*
54 * Set up GOT: Global Offset Table
55 *
56 * Use r14 to access the GOT
57 */
58 START_GOT
59 GOT_ENTRY(_GOT2_TABLE_)
60 GOT_ENTRY(_FIXUP_TABLE_)
61
62 GOT_ENTRY(_start)
63 GOT_ENTRY(_start_of_vectors)
64 GOT_ENTRY(_end_of_vectors)
65 GOT_ENTRY(transfer_to_handler)
66
67 GOT_ENTRY(__init_end)
68 GOT_ENTRY(_end)
69 GOT_ENTRY(__bss_start)
70 END_GOT
71
72/*
73 * r3 - 1st arg to board_init(): IMMP pointer
74 * r4 - 2nd arg to board_init(): boot flag
75 */
76 .text
77 .long 0x27051956 /* U-Boot Magic Number */
78 .globl version_string
79version_string:
80 .ascii U_BOOT_VERSION
81 .ascii " (", __DATE__, " - ", __TIME__, ")"
82 .ascii CONFIG_IDENT_STRING, "\0"
83
84 . = EXC_OFF_SYS_RESET
85 .globl _start
86_start:
87 li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH */
88 b boot_cold
89 sync
90
91 . = EXC_OFF_SYS_RESET + 0x10
92
93 .globl _start_warm
94_start_warm:
95 li r21, BOOTFLAG_WARM /* Software reboot */
96 b boot_warm
97 sync
98
99 /* the boot code is located below the exception table */
100
101 .globl _start_of_vectors
102_start_of_vectors:
103
104/* Machine check */
105 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
106
107/* Data Storage exception. */
108 STD_EXCEPTION(0x300, DataStorage, UnknownException)
109
110/* Instruction Storage exception. */
111 STD_EXCEPTION(0x400, InstStorage, UnknownException)
112
113/* External Interrupt exception. */
114 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
115
116/* Alignment exception. */
117 . = 0x600
118Alignment:
119 EXCEPTION_PROLOG
120 mfspr r4,DAR
121 stw r4,_DAR(r21)
122 mfspr r5,DSISR
123 stw r5,_DSISR(r21)
124 addi r3,r1,STACK_FRAME_OVERHEAD
125 li r20,MSR_KERNEL
126 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
127 lwz r6,GOT(transfer_to_handler)
128 mtlr r6
129 blrl
130.L_Alignment:
131 .long AlignmentException - _start + EXC_OFF_SYS_RESET
132 .long int_return - _start + EXC_OFF_SYS_RESET
133
134/* Program check exception */
135 . = 0x700
136ProgramCheck:
137 EXCEPTION_PROLOG
138 addi r3,r1,STACK_FRAME_OVERHEAD
139 li r20,MSR_KERNEL
140 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
141 lwz r6,GOT(transfer_to_handler)
142 mtlr r6
143 blrl
144.L_ProgramCheck:
145 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
146 .long int_return - _start + EXC_OFF_SYS_RESET
147
148 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
149
150 /* I guess we could implement decrementer, and may have
151 * to someday for timekeeping.
152 */
153 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
154 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
155 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
156 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
157 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
158 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
159 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
160 STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException)
161 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
162 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
163 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
164 STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
165 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
166 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
167 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
168 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
169 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
170 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
171 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
172 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
173 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
174 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
175 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
176
177 .globl _end_of_vectors
178_end_of_vectors:
179
180 . = 0x2000
181
182boot_cold:
183boot_warm:
184
185 /* if this is a multi-core system we need to check which cpu
186 * this is, if it is not cpu 0 send the cpu to the linux reset
187 * vector */
188#if (CONFIG_NUM_CPUS > 1)
189 mfspr r0, MSSCR0
190 andi. r0, r0, 0x0020
191 rlwinm r0,r0,27,31,31
192 mtspr PIR, r0
193 beq 1f
194
195 bl secondary_cpu_setup
196#endif
197
198 /* disable everything */
1991: li r0, 0
200 mtspr HID0, r0
201 sync
202 mtmsr 0
203 bl invalidate_bats
204 sync
205
206#ifdef CFG_L2
207 /* init the L2 cache */
208 addis r3, r0, L2_INIT@h
209 ori r3, r3, L2_INIT@l
debb7354 210 mtspr l2cr, r3
debb7354
JL
211 /* invalidate the L2 cache */
212 bl l2cache_invalidate
213 sync
214#endif
215
216 /*
217 * Calculate absolute address in FLASH and jump there
218 *------------------------------------------------------*/
219 lis r3, CFG_MONITOR_BASE@h
220 ori r3, r3, CFG_MONITOR_BASE@l
221 addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
222 mtlr r3
223 blr
224
225in_flash:
226 /* let the C-code set up the rest */
227 /* */
228 /* Be careful to keep code relocatable ! */
229 /*------------------------------------------------------*/
230 /* perform low-level init */
231
232 /* enable extended addressing */
233 bl enable_ext_addr
234
235 /* setup the bats */
236 bl setup_bats
237 sync
238
239#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
240 /* setup ccsrbar */
241 bl setup_ccsrbar
242#endif
243
14e37081
JL
244 /* Fix for SMP linux - Changing arbitration to round-robin */
245 lis r3, CFG_CCSRBAR@h
246 ori r3, r3, 0x1000
247 xor r4, r4, r4
248 li r4, 0x1000
249 stw r4, 0(r3)
250
debb7354
JL
251 /* setup the law entries */
252 bl law_entry
253 sync
254
255 /* Don't use this feature due to bug in 8641D PD4 */
256 /* Disable ERD_DIS */
257 lis r3, CFG_CCSRBAR@h
258 ori r3, r3, 0x1008
259 lwz r4, 0(r3)
260 oris r4, r4, 0x4000
261 stw r4, 0(r3)
262 sync
263
264#if (EMULATOR_RUN == 1)
265 /* On the emulator we want to adjust these ASAP */
266 /* otherwise things are sloooow */
267 /* Setup OR0 (LALE FIX)*/
268 lis r3, CFG_CCSRBAR@h
269 ori r3, r3, 0x5004
270 li r4, 0x0FF3
271 stw r4, 0(r3)
272 sync
273
274 /* Setup LCRR */
275 lis r3, CFG_CCSRBAR@h
276 ori r3, r3, 0x50D4
277 lis r4, 0x8000
278 ori r4, r4, 0x0002
279 stw r4, 0(r3)
280 sync
281#endif
282#if 1
283 /* make sure timer enabled in guts register too */
284 lis r3, CFG_CCSRBAR@h
285 oris r3,r3, 0xE
14e37081 286 ori r3,r3,0x0070
debb7354 287 lwz r4, 0(r3)
14e37081 288 lis r5,0xFFFC
debb7354
JL
289 ori r5,r5,0x5FFF
290 and r4,r4,r5
291 stw r4,0(r3)
292#endif
293 /*
294 * Cache must be enabled here for stack-in-cache trick.
295 * This means we need to enable the BATS.
296 * Cache should be turned on after BATs, since by default
297 * everything is write-through.
298 */
299
300 /* enable address translation */
301 bl enable_addr_trans
302 sync
303
304 /* enable and invalidate the data cache */
305/* bl l1dcache_enable */
306 bl dcache_enable
307 sync
308
309#if 1
310 bl icache_enable
311#endif
312
313#ifdef CFG_INIT_RAM_LOCK
314 bl lock_ram_in_cache
315 sync
316#endif
317
318 /* set up the stack pointer in our newly created
319 * cache-ram (r1) */
320 lis r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h
321 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l
322
323 li r0, 0 /* Make room for stack frame header and */
324 stwu r0, -4(r1) /* clear final stack frame so that */
325 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
326
327 GET_GOT /* initialize GOT access */
328
329 /* run low-level CPU init code (from Flash) */
330 bl cpu_init_f
331 sync
332
333#ifdef RUN_DIAG
334
335 /* Sri: Code to run the diagnostic automatically */
336
337 /* Load PX_AUX register address in r4 */
338 lis r4, 0xf810
339 ori r4, r4, 0x6
340 /* Load contents of PX_AUX in r3 bits 24 to 31*/
341 lbz r3, 0(r4)
342
343 /* Mask and obtain the bit in r3 */
344 rlwinm. r3, r3, 0, 24, 24
345 /* If not zero, jump and continue with u-boot */
346 bne diag_done
347
348 /* Load back contents of PX_AUX in r3 bits 24 to 31 */
349 lbz r3, 0(r4)
350 /* Set the MSB of the register value */
351 ori r3, r3, 0x80
352 /* Write value in r3 back to PX_AUX */
353 stb r3, 0(r4)
354
355 /* Get the address to jump to in r3*/
356 lis r3, CFG_DIAG_ADDR@h
357 ori r3, r3, CFG_DIAG_ADDR@l
358
359 /* Load the LR with the branch address */
360 mtlr r3
361
362 /* Branch to diagnostic */
363 blr
364
365diag_done:
366#endif
367
368 /* bl l2cache_enable*/
369 mr r3, r21
370
371 /* r3: BOOTFLAG */
372 /* run 1st part of board init code (from Flash) */
373 bl board_init_f
374 sync
375
376 /* NOTREACHED */
377
378 .globl invalidate_bats
379invalidate_bats:
380
381 /* invalidate BATs */
382 mtspr IBAT0U, r0
383 mtspr IBAT1U, r0
384 mtspr IBAT2U, r0
385 mtspr IBAT3U, r0
386 mtspr IBAT4U, r0
387 mtspr IBAT5U, r0
388 mtspr IBAT6U, r0
389 mtspr IBAT7U, r0
390
391 isync
392 mtspr DBAT0U, r0
393 mtspr DBAT1U, r0
394 mtspr DBAT2U, r0
395 mtspr DBAT3U, r0
396 mtspr DBAT4U, r0
397 mtspr DBAT5U, r0
398 mtspr DBAT6U, r0
399 mtspr DBAT7U, r0
400
401 isync
402 sync
403 blr
404
405
406 /* setup_bats - set them up to some initial state */
407 .globl setup_bats
408setup_bats:
409
410 addis r0, r0, 0x0000
411
412 /* IBAT 0 */
413 addis r4, r0, CFG_IBAT0L@h
414 ori r4, r4, CFG_IBAT0L@l
415 addis r3, r0, CFG_IBAT0U@h
416 ori r3, r3, CFG_IBAT0U@l
417 mtspr IBAT0L, r4
418 mtspr IBAT0U, r3
419 isync
420
421 /* DBAT 0 */
422 addis r4, r0, CFG_DBAT0L@h
423 ori r4, r4, CFG_DBAT0L@l
424 addis r3, r0, CFG_DBAT0U@h
425 ori r3, r3, CFG_DBAT0U@l
426 mtspr DBAT0L, r4
427 mtspr DBAT0U, r3
428 isync
429
430 /* IBAT 1 */
431 addis r4, r0, CFG_IBAT1L@h
432 ori r4, r4, CFG_IBAT1L@l
433 addis r3, r0, CFG_IBAT1U@h
434 ori r3, r3, CFG_IBAT1U@l
435 mtspr IBAT1L, r4
436 mtspr IBAT1U, r3
437 isync
438
439 /* DBAT 1 */
440 addis r4, r0, CFG_DBAT1L@h
441 ori r4, r4, CFG_DBAT1L@l
442 addis r3, r0, CFG_DBAT1U@h
443 ori r3, r3, CFG_DBAT1U@l
444 mtspr DBAT1L, r4
445 mtspr DBAT1U, r3
446 isync
447
448 /* IBAT 2 */
449 addis r4, r0, CFG_IBAT2L@h
450 ori r4, r4, CFG_IBAT2L@l
451 addis r3, r0, CFG_IBAT2U@h
452 ori r3, r3, CFG_IBAT2U@l
453 mtspr IBAT2L, r4
454 mtspr IBAT2U, r3
455 isync
456
457 /* DBAT 2 */
458 addis r4, r0, CFG_DBAT2L@h
459 ori r4, r4, CFG_DBAT2L@l
460 addis r3, r0, CFG_DBAT2U@h
461 ori r3, r3, CFG_DBAT2U@l
462 mtspr DBAT2L, r4
463 mtspr DBAT2U, r3
464 isync
465
466 /* IBAT 3 */
467 addis r4, r0, CFG_IBAT3L@h
468 ori r4, r4, CFG_IBAT3L@l
469 addis r3, r0, CFG_IBAT3U@h
470 ori r3, r3, CFG_IBAT3U@l
471 mtspr IBAT3L, r4
472 mtspr IBAT3U, r3
473 isync
474
475 /* DBAT 3 */
476 addis r4, r0, CFG_DBAT3L@h
477 ori r4, r4, CFG_DBAT3L@l
478 addis r3, r0, CFG_DBAT3U@h
479 ori r3, r3, CFG_DBAT3U@l
480 mtspr DBAT3L, r4
481 mtspr DBAT3U, r3
482 isync
483
484 /* IBAT 4 */
485 addis r4, r0, CFG_IBAT4L@h
486 ori r4, r4, CFG_IBAT4L@l
487 addis r3, r0, CFG_IBAT4U@h
488 ori r3, r3, CFG_IBAT4U@l
489 mtspr IBAT4L, r4
490 mtspr IBAT4U, r3
491 isync
492
493 /* DBAT 4 */
494 addis r4, r0, CFG_DBAT4L@h
495 ori r4, r4, CFG_DBAT4L@l
496 addis r3, r0, CFG_DBAT4U@h
497 ori r3, r3, CFG_DBAT4U@l
498 mtspr DBAT4L, r4
499 mtspr DBAT4U, r3
500 isync
501
502 /* IBAT 5 */
503 addis r4, r0, CFG_IBAT5L@h
504 ori r4, r4, CFG_IBAT5L@l
505 addis r3, r0, CFG_IBAT5U@h
506 ori r3, r3, CFG_IBAT5U@l
507 mtspr IBAT5L, r4
508 mtspr IBAT5U, r3
509 isync
510
511 /* DBAT 5 */
512 addis r4, r0, CFG_DBAT5L@h
513 ori r4, r4, CFG_DBAT5L@l
514 addis r3, r0, CFG_DBAT5U@h
515 ori r3, r3, CFG_DBAT5U@l
516 mtspr DBAT5L, r4
517 mtspr DBAT5U, r3
518 isync
519
520 /* IBAT 6 */
521 addis r4, r0, CFG_IBAT6L@h
522 ori r4, r4, CFG_IBAT6L@l
523 addis r3, r0, CFG_IBAT6U@h
524 ori r3, r3, CFG_IBAT6U@l
525 mtspr IBAT6L, r4
526 mtspr IBAT6U, r3
527 isync
528
529 /* DBAT 6 */
530 addis r4, r0, CFG_DBAT6L@h
531 ori r4, r4, CFG_DBAT6L@l
532 addis r3, r0, CFG_DBAT6U@h
533 ori r3, r3, CFG_DBAT6U@l
534 mtspr DBAT6L, r4
535 mtspr DBAT6U, r3
536 isync
537
538 /* IBAT 7 */
539 addis r4, r0, CFG_IBAT7L@h
540 ori r4, r4, CFG_IBAT7L@l
541 addis r3, r0, CFG_IBAT7U@h
542 ori r3, r3, CFG_IBAT7U@l
543 mtspr IBAT7L, r4
544 mtspr IBAT7U, r3
545 isync
546
547 /* DBAT 7 */
548 addis r4, r0, CFG_DBAT7L@h
549 ori r4, r4, CFG_DBAT7L@l
550 addis r3, r0, CFG_DBAT7U@h
551 ori r3, r3, CFG_DBAT7U@l
552 mtspr DBAT7L, r4
553 mtspr DBAT7U, r3
554 isync
555
5561:
557 addis r3, 0, 0x0000
558 addis r5, 0, 0x4 /* upper bound of 0x00040000 for 7400/750 */
559 isync
560
561tlblp:
562 tlbie r3
563 sync
564 addi r3, r3, 0x1000
565 cmp 0, 0, r3, r5
566 blt tlblp
567
568 blr
569
570 .globl enable_addr_trans
571enable_addr_trans:
572 /* enable address translation */
573 mfmsr r5
574 ori r5, r5, (MSR_IR | MSR_DR)
575 mtmsr r5
576 isync
577 blr
578
579 .globl disable_addr_trans
580disable_addr_trans:
581 /* disable address translation */
582 mflr r4
583 mfmsr r3
584 andi. r0, r3, (MSR_IR | MSR_DR)
585 beqlr
586 andc r3, r3, r0
587 mtspr SRR0, r4
588 mtspr SRR1, r3
589 rfi
590
591/*
592 * This code finishes saving the registers to the exception frame
593 * and jumps to the appropriate handler for the exception.
594 * Register r21 is pointer into trap frame, r1 has new stack pointer.
595 */
596 .globl transfer_to_handler
597transfer_to_handler:
598 stw r22,_NIP(r21)
599 lis r22,MSR_POW@h
600 andc r23,r23,r22
601 stw r23,_MSR(r21)
602 SAVE_GPR(7, r21)
603 SAVE_4GPRS(8, r21)
604 SAVE_8GPRS(12, r21)
605 SAVE_8GPRS(24, r21)
606 mflr r23
607 andi. r24,r23,0x3f00 /* get vector offset */
608 stw r24,TRAP(r21)
609 li r22,0
610 stw r22,RESULT(r21)
611 mtspr SPRG2,r22 /* r1 is now kernel sp */
612 lwz r24,0(r23) /* virtual address of handler */
613 lwz r23,4(r23) /* where to go when done */
614 mtspr SRR0,r24
615 mtspr SRR1,r20
616 mtlr r23
617 SYNC
618 rfi /* jump to handler, enable MMU */
619
620int_return:
621 mfmsr r28 /* Disable interrupts */
622 li r4,0
623 ori r4,r4,MSR_EE
624 andc r28,r28,r4
625 SYNC /* Some chip revs need this... */
626 mtmsr r28
627 SYNC
628 lwz r2,_CTR(r1)
629 lwz r0,_LINK(r1)
630 mtctr r2
631 mtlr r0
632 lwz r2,_XER(r1)
633 lwz r0,_CCR(r1)
634 mtspr XER,r2
635 mtcrf 0xFF,r0
636 REST_10GPRS(3, r1)
637 REST_10GPRS(13, r1)
638 REST_8GPRS(23, r1)
639 REST_GPR(31, r1)
640 lwz r2,_NIP(r1) /* Restore environment */
641 lwz r0,_MSR(r1)
642 mtspr SRR0,r2
643 mtspr SRR1,r0
644 lwz r0,GPR0(r1)
645 lwz r2,GPR2(r1)
646 lwz r1,GPR1(r1)
647 SYNC
648 rfi
649
650 .globl dc_read
651dc_read:
652 blr
653
654 .globl get_pvr
655get_pvr:
656 mfspr r3, PVR
657 blr
658
659 .globl get_svr
660get_svr:
661 mfspr r3, SVR
662 blr
663
664
665/*------------------------------------------------------------------------------- */
666/* Function: in8 */
667/* Description: Input 8 bits */
668/*------------------------------------------------------------------------------- */
669 .globl in8
670in8:
671 lbz r3,0x0000(r3)
672 blr
673
674/*------------------------------------------------------------------------------- */
675/* Function: out8 */
676/* Description: Output 8 bits */
677/*------------------------------------------------------------------------------- */
678 .globl out8
679out8:
680 stb r4,0x0000(r3)
681 blr
682
683/*------------------------------------------------------------------------------- */
684/* Function: out16 */
685/* Description: Output 16 bits */
686/*------------------------------------------------------------------------------- */
687 .globl out16
688out16:
689 sth r4,0x0000(r3)
690 blr
691
692/*------------------------------------------------------------------------------- */
693/* Function: out16r */
694/* Description: Byte reverse and output 16 bits */
695/*------------------------------------------------------------------------------- */
696 .globl out16r
697out16r:
698 sthbrx r4,r0,r3
699 blr
700
701/*------------------------------------------------------------------------------- */
702/* Function: out32 */
703/* Description: Output 32 bits */
704/*------------------------------------------------------------------------------- */
705 .globl out32
706out32:
707 stw r4,0x0000(r3)
708 blr
709
710/*------------------------------------------------------------------------------- */
711/* Function: out32r */
712/* Description: Byte reverse and output 32 bits */
713/*------------------------------------------------------------------------------- */
714 .globl out32r
715out32r:
716 stwbrx r4,r0,r3
717 blr
718
719/*------------------------------------------------------------------------------- */
720/* Function: in16 */
721/* Description: Input 16 bits */
722/*------------------------------------------------------------------------------- */
723 .globl in16
724in16:
725 lhz r3,0x0000(r3)
726 blr
727
728/*------------------------------------------------------------------------------- */
729/* Function: in16r */
730/* Description: Input 16 bits and byte reverse */
731/*------------------------------------------------------------------------------- */
732 .globl in16r
733in16r:
734 lhbrx r3,r0,r3
735 blr
736
737/*------------------------------------------------------------------------------- */
738/* Function: in32 */
739/* Description: Input 32 bits */
740/*------------------------------------------------------------------------------- */
741 .globl in32
742in32:
743 lwz 3,0x0000(3)
744 blr
745
746/*------------------------------------------------------------------------------- */
747/* Function: in32r */
748/* Description: Input 32 bits and byte reverse */
749/*------------------------------------------------------------------------------- */
750 .globl in32r
751in32r:
752 lwbrx r3,r0,r3
753 blr
754
755/*------------------------------------------------------------------------------- */
756/* Function: ppcDcbf */
757/* Description: Data Cache block flush */
758/* Input: r3 = effective address */
759/* Output: none. */
760/*------------------------------------------------------------------------------- */
761 .globl ppcDcbf
762ppcDcbf:
763 dcbf r0,r3
764 blr
765
766/*------------------------------------------------------------------------------- */
767/* Function: ppcDcbi */
768/* Description: Data Cache block Invalidate */
769/* Input: r3 = effective address */
770/* Output: none. */
771/*------------------------------------------------------------------------------- */
772 .globl ppcDcbi
773ppcDcbi:
774 dcbi r0,r3
775 blr
776
777/*--------------------------------------------------------------------------
778 * Function: ppcDcbz
779 * Description: Data Cache block zero.
780 * Input: r3 = effective address
781 * Output: none.
782 *-------------------------------------------------------------------------- */
783
784 .globl ppcDcbz
785ppcDcbz:
786 dcbz r0,r3
787 blr
788
5c9efb36 789/*-------------------------------------------------------------------------- */
debb7354
JL
790/* Function: ppcSync */
791/* Description: Processor Synchronize */
792/* Input: none. */
793/* Output: none. */
5c9efb36 794/*-------------------------------------------------------------------------- */
debb7354
JL
795 .globl ppcSync
796ppcSync:
797 sync
798 blr
799
800/*-----------------------------------------------------------------------*/
801/*
802 * void relocate_code (addr_sp, gd, addr_moni)
803 *
804 * This "function" does not return, instead it continues in RAM
805 * after relocating the monitor code.
806 *
807 * r3 = dest
808 * r4 = src
809 * r5 = length in bytes
810 * r6 = cachelinesize
811 */
812 .globl relocate_code
813relocate_code:
814
815 mr r1, r3 /* Set new stack pointer */
816 mr r9, r4 /* Save copy of Global Data pointer */
67256678 817 mr r29, r9 /* Save for DECLARE_GLOBAL_DATA_PTR */
debb7354 818 mr r10, r5 /* Save copy of Destination Address */
67256678 819
debb7354
JL
820 mr r3, r5 /* Destination Address */
821 lis r4, CFG_MONITOR_BASE@h /* Source Address */
822 ori r4, r4, CFG_MONITOR_BASE@l
823 lwz r5, GOT(__init_end)
824 sub r5, r5, r4
825 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
826
827 /*
828 * Fix GOT pointer:
829 *
830 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
831 *
832 * Offset:
833 */
834 sub r15, r10, r4
835
836 /* First our own GOT */
837 add r14, r14, r15
838 /* then the one used by the C code */
839 add r30, r30, r15
840
841 /*
842 * Now relocate code
843 */
844#ifdef CONFIG_ECC
845 bl board_relocate_rom
846 sync
847 mr r3, r10 /* Destination Address */
848 lis r4, CFG_MONITOR_BASE@h /* Source Address */
849 ori r4, r4, CFG_MONITOR_BASE@l
850 lwz r5, GOT(__init_end)
851 sub r5, r5, r4
852 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
853#else
854 cmplw cr1,r3,r4
855 addi r0,r5,3
856 srwi. r0,r0,2
857 beq cr1,4f /* In place copy is not necessary */
858 beq 7f /* Protect against 0 count */
859 mtctr r0
860 bge cr1,2f
861
862 la r8,-4(r4)
863 la r7,-4(r3)
8641: lwzu r0,4(r8)
865 stwu r0,4(r7)
866 bdnz 1b
867 b 4f
868
8692: slwi r0,r0,2
870 add r8,r4,r0
871 add r7,r3,r0
8723: lwzu r0,-4(r8)
873 stwu r0,-4(r7)
874 bdnz 3b
875#endif
876/*
877 * Now flush the cache: note that we must start from a cache aligned
878 * address. Otherwise we might miss one cache line.
879 */
8804: cmpwi r6,0
881 add r5,r3,r5
882 beq 7f /* Always flush prefetch queue in any case */
883 subi r0,r6,1
884 andc r3,r3,r0
885 mr r4,r3
8865: dcbst 0,r4
887 add r4,r4,r6
888 cmplw r4,r5
889 blt 5b
890 sync /* Wait for all dcbst to complete on bus */
891 mr r4,r3
8926: icbi 0,r4
893 add r4,r4,r6
894 cmplw r4,r5
895 blt 6b
8967: sync /* Wait for all icbi to complete on bus */
897 isync
898
899/*
900 * We are done. Do not return, instead branch to second part of board
901 * initialization, now running from RAM.
902 */
903 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
904 mtlr r0
905 blr
906
907in_ram:
908#ifdef CONFIG_ECC
909 bl board_init_ecc
910#endif
911 /*
912 * Relocation Function, r14 point to got2+0x8000
913 *
914 * Adjust got2 pointers, no need to check for 0, this code
915 * already puts a few entries in the table.
916 */
917 li r0,__got2_entries@sectoff@l
918 la r3,GOT(_GOT2_TABLE_)
919 lwz r11,GOT(_GOT2_TABLE_)
920 mtctr r0
921 sub r11,r3,r11
922 addi r3,r3,-4
9231: lwzu r0,4(r3)
924 add r0,r0,r11
925 stw r0,0(r3)
926 bdnz 1b
927
928 /*
929 * Now adjust the fixups and the pointers to the fixups
930 * in case we need to move ourselves again.
931 */
9322: li r0,__fixup_entries@sectoff@l
933 lwz r3,GOT(_FIXUP_TABLE_)
934 cmpwi r0,0
935 mtctr r0
936 addi r3,r3,-4
937 beq 4f
9383: lwzu r4,4(r3)
939 lwzux r0,r4,r11
940 add r0,r0,r11
941 stw r10,0(r3)
942 stw r0,0(r4)
943 bdnz 3b
9444:
945/* clear_bss: */
946 /*
947 * Now clear BSS segment
948 */
949 lwz r3,GOT(__bss_start)
950 lwz r4,GOT(_end)
951
952 cmplw 0, r3, r4
953 beq 6f
954
955 li r0, 0
9565:
957 stw r0, 0(r3)
958 addi r3, r3, 4
959 cmplw 0, r3, r4
960 bne 5b
9616:
6cfea334
HW
962 mr r3, r9 /* Init Date pointer */
963 mr r4, r10 /* Destination Address */
964 bl board_init_r
debb7354
JL
965
966 /* not reached - end relocate_code */
967/*-----------------------------------------------------------------------*/
968
969 /*
970 * Copy exception vector code to low memory
971 *
972 * r3: dest_addr
973 * r7: source address, r8: end address, r9: target address
974 */
975 .globl trap_init
976trap_init:
977 lwz r7, GOT(_start)
978 lwz r8, GOT(_end_of_vectors)
979
980 li r9, 0x100 /* reset vector always at 0x100 */
981
982 cmplw 0, r7, r8
983 bgelr /* return if r7>=r8 - just in case */
984
985 mflr r4 /* save link register */
9861:
987 lwz r0, 0(r7)
988 stw r0, 0(r9)
989 addi r7, r7, 4
990 addi r9, r9, 4
991 cmplw 0, r7, r8
992 bne 1b
993
994 /*
995 * relocate `hdlr' and `int_return' entries
996 */
997 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
998 li r8, Alignment - _start + EXC_OFF_SYS_RESET
9992:
1000 bl trap_reloc
1001 addi r7, r7, 0x100 /* next exception vector */
1002 cmplw 0, r7, r8
1003 blt 2b
1004
1005 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1006 bl trap_reloc
1007
1008 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1009 bl trap_reloc
1010
1011 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1012 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
10133:
1014 bl trap_reloc
1015 addi r7, r7, 0x100 /* next exception vector */
1016 cmplw 0, r7, r8
1017 blt 3b
1018
1019 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1020 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
10214:
1022 bl trap_reloc
1023 addi r7, r7, 0x100 /* next exception vector */
1024 cmplw 0, r7, r8
1025 blt 4b
1026
1027 /* enable execptions from RAM vectors */
1028 mfmsr r7
1029 li r8,MSR_IP
1030 andc r7,r7,r8
1031 mtmsr r7
1032
1033 mtlr r4 /* restore link register */
1034 blr
1035
1036 /*
1037 * Function: relocate entries for one exception vector
1038 */
1039trap_reloc:
1040 lwz r0, 0(r7) /* hdlr ... */
1041 add r0, r0, r3 /* ... += dest_addr */
1042 stw r0, 0(r7)
1043
1044 lwz r0, 4(r7) /* int_return ... */
1045 add r0, r0, r3 /* ... += dest_addr */
1046 stw r0, 4(r7)
1047
1048 sync
1049 isync
1050
1051 blr
1052
1053.globl enable_ext_addr
1054enable_ext_addr:
1055 mfspr r0, HID0
1056 lis r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h
1057 ori r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l
1058 mtspr HID0, r0
1059 sync
1060 isync
1061 blr
1062
1063#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
1064.globl setup_ccsrbar
1065setup_ccsrbar:
1066 /* Special sequence needed to update CCSRBAR itself */
1067 lis r4, CFG_CCSRBAR_DEFAULT@h
1068 ori r4, r4, CFG_CCSRBAR_DEFAULT@l
1069
1070 lis r5, CFG_CCSRBAR@h
1071 ori r5, r5, CFG_CCSRBAR@l
1072 srwi r6,r5,12
1073 stw r6, 0(r4)
1074 isync
1075
1076 lis r5, 0xffff
1077 ori r5,r5,0xf000
1078 lwz r5, 0(r5)
1079 isync
1080
1081 lis r3, CFG_CCSRBAR@h
1082 lwz r5, CFG_CCSRBAR@l(r3)
1083 isync
1084
1085 blr
1086#endif
1087
1088#ifdef CFG_INIT_RAM_LOCK
1089lock_ram_in_cache:
1090 /* Allocate Initial RAM in data cache.
1091 */
1092 lis r3, (CFG_INIT_RAM_ADDR & ~31)@h
1093 ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
1094 li r2, ((CFG_INIT_RAM_END & ~31) + \
1095 (CFG_INIT_RAM_ADDR & 31) + 31) / 32
1096 mtctr r2
10971:
1098 dcbz r0, r3
1099 addi r3, r3, 32
1100 bdnz 1b
1101#if 1
1102/* Lock the data cache */
1103 mfspr r0, HID0
1104 ori r0, r0, 0x1000
1105 sync
1106 mtspr HID0, r0
1107 sync
1108 blr
1109#endif
1110#if 0
1111 /* Lock the first way of the data cache */
1112 mfspr r0, LDSTCR
1113 ori r0, r0, 0x0080
1114#if defined(CONFIG_ALTIVEC)
1115 dssall
1116#endif
1117 sync
1118 mtspr LDSTCR, r0
1119 sync
1120 isync
1121 blr
1122#endif
1123
1124.globl unlock_ram_in_cache
1125unlock_ram_in_cache:
1126 /* invalidate the INIT_RAM section */
1127 lis r3, (CFG_INIT_RAM_ADDR & ~31)@h
1128 ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
1129 li r2, ((CFG_INIT_RAM_END & ~31) + \
1130 (CFG_INIT_RAM_ADDR & 31) + 31) / 32
1131 mtctr r2
11321: icbi r0, r3
1133 addi r3, r3, 32
1134 bdnz 1b
1135 sync /* Wait for all icbi to complete on bus */
1136 isync
1137#if 1
1138/* Unlock the data cache and invalidate it */
1139 mfspr r0, HID0
1140 li r3,0x1000
1141 andc r0,r0,r3
1142 li r3,0x0400
1143 or r0,r0,r3
1144 sync
1145 mtspr HID0, r0
1146 sync
1147 blr
1148#endif
1149#if 0
1150 /* Unlock the first way of the data cache */
1151 mfspr r0, LDSTCR
1152 li r3,0x0080
1153 andc r0,r0,r3
1154#ifdef CONFIG_ALTIVEC
1155 dssall
1156#endif
1157 sync
1158 mtspr LDSTCR, r0
1159 sync
1160 isync
1161 li r3,0x0400
1162 or r0,r0,r3
1163 sync
1164 mtspr HID0, r0
1165 sync
1166 blr
1167#endif
1168#endif
1169
1170/* If this is a multi-cpu system then we need to handle the
1171 * 2nd cpu. The assumption is that the 2nd cpu is being
1172 * held in boot holdoff mode until the 1st cpu unlocks it
1173 * from Linux. We'll do some basic cpu init and then pass
1174 * it to the Linux Reset Vector.
1175 * Sri: Much of this initialization is not required. Linux
1176 * rewrites the bats, and the sprs and also enables the L1 cache.
1177 */
1178#if (CONFIG_NUM_CPUS > 1)
1179.globl secondary_cpu_setup
1180secondary_cpu_setup:
1181 /* Do only core setup on all cores except cpu0 */
1182 bl invalidate_bats
1183 sync
1184 bl enable_ext_addr
1185
1186#ifdef CFG_L2
1187 /* init the L2 cache */
1188 addis r3, r0, L2_INIT@h
1189 ori r3, r3, L2_INIT@l
1190 sync
1191 mtspr l2cr, r3
1192#ifdef CONFIG_ALTIVEC
1193 dssall
1194#endif
1195 /* invalidate the L2 cache */
1196 bl l2cache_invalidate
1197 sync
1198#endif
1199
debb7354
JL
1200 /* enable and invalidate the data cache */
1201 bl dcache_enable
1202 sync
1203
1204 /* enable and invalidate the instruction cache*/
1205 bl icache_enable
1206 sync
1207
debb7354
JL
1208
1209 /* TBEN in HID0 */
1210 mfspr r4, HID0
1211 oris r4, r4, 0x0400
1212 mtspr HID0, r4
1213 sync
1214 isync
1215
1216 /*SYNCBE|ABE in HID1*/
1217 mfspr r4, HID1
1218 ori r4, r4, 0x0C00
1219 mtspr HID1, r4
1220 sync
1221 isync
1222
1223 lis r3, CONFIG_LINUX_RESET_VEC@h
1224 ori r3, r3, CONFIG_LINUX_RESET_VEC@l
1225 mtlr r3
1226 blr
1227
1228 /* Never Returns, Running in Linux Now */
1229#endif
1230