]> git.ipfire.org Git - people/ms/u-boot.git/blame - cpu/mpc86xx/start.S
Initial support for MPC8641 HPCN board.
[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
210 sync
211 mtspr l2cr, r3
212#ifdef CONFIG_ALTIVEC
213 dssall
214#endif
215 /* invalidate the L2 cache */
216 bl l2cache_invalidate
217 sync
218#endif
219
220 /*
221 * Calculate absolute address in FLASH and jump there
222 *------------------------------------------------------*/
223 lis r3, CFG_MONITOR_BASE@h
224 ori r3, r3, CFG_MONITOR_BASE@l
225 addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
226 mtlr r3
227 blr
228
229in_flash:
230 /* let the C-code set up the rest */
231 /* */
232 /* Be careful to keep code relocatable ! */
233 /*------------------------------------------------------*/
234 /* perform low-level init */
235
236 /* enable extended addressing */
237 bl enable_ext_addr
238
239 /* setup the bats */
240 bl setup_bats
241 sync
242
243#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
244 /* setup ccsrbar */
245 bl setup_ccsrbar
246#endif
247
248 /* setup the law entries */
249 bl law_entry
250 sync
251
252 /* Don't use this feature due to bug in 8641D PD4 */
253 /* Disable ERD_DIS */
254 lis r3, CFG_CCSRBAR@h
255 ori r3, r3, 0x1008
256 lwz r4, 0(r3)
257 oris r4, r4, 0x4000
258 stw r4, 0(r3)
259 sync
260
261#if (EMULATOR_RUN == 1)
262 /* On the emulator we want to adjust these ASAP */
263 /* otherwise things are sloooow */
264 /* Setup OR0 (LALE FIX)*/
265 lis r3, CFG_CCSRBAR@h
266 ori r3, r3, 0x5004
267 li r4, 0x0FF3
268 stw r4, 0(r3)
269 sync
270
271 /* Setup LCRR */
272 lis r3, CFG_CCSRBAR@h
273 ori r3, r3, 0x50D4
274 lis r4, 0x8000
275 ori r4, r4, 0x0002
276 stw r4, 0(r3)
277 sync
278#endif
279#if 1
280 /* make sure timer enabled in guts register too */
281 lis r3, CFG_CCSRBAR@h
282 oris r3,r3, 0xE
283 ori r3,r3,0x0070 /*Jason from 3*/
284 lwz r4, 0(r3)
285 lis r5,0xFFFC /*Jason from 0xffff*/
286 ori r5,r5,0x5FFF
287 and r4,r4,r5
288 stw r4,0(r3)
289#endif
290 /*
291 * Cache must be enabled here for stack-in-cache trick.
292 * This means we need to enable the BATS.
293 * Cache should be turned on after BATs, since by default
294 * everything is write-through.
295 */
296
297 /* enable address translation */
298 bl enable_addr_trans
299 sync
300
301 /* enable and invalidate the data cache */
302/* bl l1dcache_enable */
303 bl dcache_enable
304 sync
305
306#if 1
307 bl icache_enable
308#endif
309
310#ifdef CFG_INIT_RAM_LOCK
311 bl lock_ram_in_cache
312 sync
313#endif
314
315 /* set up the stack pointer in our newly created
316 * cache-ram (r1) */
317 lis r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h
318 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l
319
320 li r0, 0 /* Make room for stack frame header and */
321 stwu r0, -4(r1) /* clear final stack frame so that */
322 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
323
324 GET_GOT /* initialize GOT access */
325
326 /* run low-level CPU init code (from Flash) */
327 bl cpu_init_f
328 sync
329
330#ifdef RUN_DIAG
331
332 /* Sri: Code to run the diagnostic automatically */
333
334 /* Load PX_AUX register address in r4 */
335 lis r4, 0xf810
336 ori r4, r4, 0x6
337 /* Load contents of PX_AUX in r3 bits 24 to 31*/
338 lbz r3, 0(r4)
339
340 /* Mask and obtain the bit in r3 */
341 rlwinm. r3, r3, 0, 24, 24
342 /* If not zero, jump and continue with u-boot */
343 bne diag_done
344
345 /* Load back contents of PX_AUX in r3 bits 24 to 31 */
346 lbz r3, 0(r4)
347 /* Set the MSB of the register value */
348 ori r3, r3, 0x80
349 /* Write value in r3 back to PX_AUX */
350 stb r3, 0(r4)
351
352 /* Get the address to jump to in r3*/
353 lis r3, CFG_DIAG_ADDR@h
354 ori r3, r3, CFG_DIAG_ADDR@l
355
356 /* Load the LR with the branch address */
357 mtlr r3
358
359 /* Branch to diagnostic */
360 blr
361
362diag_done:
363#endif
364
365 /* bl l2cache_enable*/
366 mr r3, r21
367
368 /* r3: BOOTFLAG */
369 /* run 1st part of board init code (from Flash) */
370 bl board_init_f
371 sync
372
373 /* NOTREACHED */
374
375 .globl invalidate_bats
376invalidate_bats:
377
378 /* invalidate BATs */
379 mtspr IBAT0U, r0
380 mtspr IBAT1U, r0
381 mtspr IBAT2U, r0
382 mtspr IBAT3U, r0
383 mtspr IBAT4U, r0
384 mtspr IBAT5U, r0
385 mtspr IBAT6U, r0
386 mtspr IBAT7U, r0
387
388 isync
389 mtspr DBAT0U, r0
390 mtspr DBAT1U, r0
391 mtspr DBAT2U, r0
392 mtspr DBAT3U, r0
393 mtspr DBAT4U, r0
394 mtspr DBAT5U, r0
395 mtspr DBAT6U, r0
396 mtspr DBAT7U, r0
397
398 isync
399 sync
400 blr
401
402
403 /* setup_bats - set them up to some initial state */
404 .globl setup_bats
405setup_bats:
406
407 addis r0, r0, 0x0000
408
409 /* IBAT 0 */
410 addis r4, r0, CFG_IBAT0L@h
411 ori r4, r4, CFG_IBAT0L@l
412 addis r3, r0, CFG_IBAT0U@h
413 ori r3, r3, CFG_IBAT0U@l
414 mtspr IBAT0L, r4
415 mtspr IBAT0U, r3
416 isync
417
418 /* DBAT 0 */
419 addis r4, r0, CFG_DBAT0L@h
420 ori r4, r4, CFG_DBAT0L@l
421 addis r3, r0, CFG_DBAT0U@h
422 ori r3, r3, CFG_DBAT0U@l
423 mtspr DBAT0L, r4
424 mtspr DBAT0U, r3
425 isync
426
427 /* IBAT 1 */
428 addis r4, r0, CFG_IBAT1L@h
429 ori r4, r4, CFG_IBAT1L@l
430 addis r3, r0, CFG_IBAT1U@h
431 ori r3, r3, CFG_IBAT1U@l
432 mtspr IBAT1L, r4
433 mtspr IBAT1U, r3
434 isync
435
436 /* DBAT 1 */
437 addis r4, r0, CFG_DBAT1L@h
438 ori r4, r4, CFG_DBAT1L@l
439 addis r3, r0, CFG_DBAT1U@h
440 ori r3, r3, CFG_DBAT1U@l
441 mtspr DBAT1L, r4
442 mtspr DBAT1U, r3
443 isync
444
445 /* IBAT 2 */
446 addis r4, r0, CFG_IBAT2L@h
447 ori r4, r4, CFG_IBAT2L@l
448 addis r3, r0, CFG_IBAT2U@h
449 ori r3, r3, CFG_IBAT2U@l
450 mtspr IBAT2L, r4
451 mtspr IBAT2U, r3
452 isync
453
454 /* DBAT 2 */
455 addis r4, r0, CFG_DBAT2L@h
456 ori r4, r4, CFG_DBAT2L@l
457 addis r3, r0, CFG_DBAT2U@h
458 ori r3, r3, CFG_DBAT2U@l
459 mtspr DBAT2L, r4
460 mtspr DBAT2U, r3
461 isync
462
463 /* IBAT 3 */
464 addis r4, r0, CFG_IBAT3L@h
465 ori r4, r4, CFG_IBAT3L@l
466 addis r3, r0, CFG_IBAT3U@h
467 ori r3, r3, CFG_IBAT3U@l
468 mtspr IBAT3L, r4
469 mtspr IBAT3U, r3
470 isync
471
472 /* DBAT 3 */
473 addis r4, r0, CFG_DBAT3L@h
474 ori r4, r4, CFG_DBAT3L@l
475 addis r3, r0, CFG_DBAT3U@h
476 ori r3, r3, CFG_DBAT3U@l
477 mtspr DBAT3L, r4
478 mtspr DBAT3U, r3
479 isync
480
481 /* IBAT 4 */
482 addis r4, r0, CFG_IBAT4L@h
483 ori r4, r4, CFG_IBAT4L@l
484 addis r3, r0, CFG_IBAT4U@h
485 ori r3, r3, CFG_IBAT4U@l
486 mtspr IBAT4L, r4
487 mtspr IBAT4U, r3
488 isync
489
490 /* DBAT 4 */
491 addis r4, r0, CFG_DBAT4L@h
492 ori r4, r4, CFG_DBAT4L@l
493 addis r3, r0, CFG_DBAT4U@h
494 ori r3, r3, CFG_DBAT4U@l
495 mtspr DBAT4L, r4
496 mtspr DBAT4U, r3
497 isync
498
499 /* IBAT 5 */
500 addis r4, r0, CFG_IBAT5L@h
501 ori r4, r4, CFG_IBAT5L@l
502 addis r3, r0, CFG_IBAT5U@h
503 ori r3, r3, CFG_IBAT5U@l
504 mtspr IBAT5L, r4
505 mtspr IBAT5U, r3
506 isync
507
508 /* DBAT 5 */
509 addis r4, r0, CFG_DBAT5L@h
510 ori r4, r4, CFG_DBAT5L@l
511 addis r3, r0, CFG_DBAT5U@h
512 ori r3, r3, CFG_DBAT5U@l
513 mtspr DBAT5L, r4
514 mtspr DBAT5U, r3
515 isync
516
517 /* IBAT 6 */
518 addis r4, r0, CFG_IBAT6L@h
519 ori r4, r4, CFG_IBAT6L@l
520 addis r3, r0, CFG_IBAT6U@h
521 ori r3, r3, CFG_IBAT6U@l
522 mtspr IBAT6L, r4
523 mtspr IBAT6U, r3
524 isync
525
526 /* DBAT 6 */
527 addis r4, r0, CFG_DBAT6L@h
528 ori r4, r4, CFG_DBAT6L@l
529 addis r3, r0, CFG_DBAT6U@h
530 ori r3, r3, CFG_DBAT6U@l
531 mtspr DBAT6L, r4
532 mtspr DBAT6U, r3
533 isync
534
535 /* IBAT 7 */
536 addis r4, r0, CFG_IBAT7L@h
537 ori r4, r4, CFG_IBAT7L@l
538 addis r3, r0, CFG_IBAT7U@h
539 ori r3, r3, CFG_IBAT7U@l
540 mtspr IBAT7L, r4
541 mtspr IBAT7U, r3
542 isync
543
544 /* DBAT 7 */
545 addis r4, r0, CFG_DBAT7L@h
546 ori r4, r4, CFG_DBAT7L@l
547 addis r3, r0, CFG_DBAT7U@h
548 ori r3, r3, CFG_DBAT7U@l
549 mtspr DBAT7L, r4
550 mtspr DBAT7U, r3
551 isync
552
5531:
554 addis r3, 0, 0x0000
555 addis r5, 0, 0x4 /* upper bound of 0x00040000 for 7400/750 */
556 isync
557
558tlblp:
559 tlbie r3
560 sync
561 addi r3, r3, 0x1000
562 cmp 0, 0, r3, r5
563 blt tlblp
564
565 blr
566
567 .globl enable_addr_trans
568enable_addr_trans:
569 /* enable address translation */
570 mfmsr r5
571 ori r5, r5, (MSR_IR | MSR_DR)
572 mtmsr r5
573 isync
574 blr
575
576 .globl disable_addr_trans
577disable_addr_trans:
578 /* disable address translation */
579 mflr r4
580 mfmsr r3
581 andi. r0, r3, (MSR_IR | MSR_DR)
582 beqlr
583 andc r3, r3, r0
584 mtspr SRR0, r4
585 mtspr SRR1, r3
586 rfi
587
588/*
589 * This code finishes saving the registers to the exception frame
590 * and jumps to the appropriate handler for the exception.
591 * Register r21 is pointer into trap frame, r1 has new stack pointer.
592 */
593 .globl transfer_to_handler
594transfer_to_handler:
595 stw r22,_NIP(r21)
596 lis r22,MSR_POW@h
597 andc r23,r23,r22
598 stw r23,_MSR(r21)
599 SAVE_GPR(7, r21)
600 SAVE_4GPRS(8, r21)
601 SAVE_8GPRS(12, r21)
602 SAVE_8GPRS(24, r21)
603 mflr r23
604 andi. r24,r23,0x3f00 /* get vector offset */
605 stw r24,TRAP(r21)
606 li r22,0
607 stw r22,RESULT(r21)
608 mtspr SPRG2,r22 /* r1 is now kernel sp */
609 lwz r24,0(r23) /* virtual address of handler */
610 lwz r23,4(r23) /* where to go when done */
611 mtspr SRR0,r24
612 mtspr SRR1,r20
613 mtlr r23
614 SYNC
615 rfi /* jump to handler, enable MMU */
616
617int_return:
618 mfmsr r28 /* Disable interrupts */
619 li r4,0
620 ori r4,r4,MSR_EE
621 andc r28,r28,r4
622 SYNC /* Some chip revs need this... */
623 mtmsr r28
624 SYNC
625 lwz r2,_CTR(r1)
626 lwz r0,_LINK(r1)
627 mtctr r2
628 mtlr r0
629 lwz r2,_XER(r1)
630 lwz r0,_CCR(r1)
631 mtspr XER,r2
632 mtcrf 0xFF,r0
633 REST_10GPRS(3, r1)
634 REST_10GPRS(13, r1)
635 REST_8GPRS(23, r1)
636 REST_GPR(31, r1)
637 lwz r2,_NIP(r1) /* Restore environment */
638 lwz r0,_MSR(r1)
639 mtspr SRR0,r2
640 mtspr SRR1,r0
641 lwz r0,GPR0(r1)
642 lwz r2,GPR2(r1)
643 lwz r1,GPR1(r1)
644 SYNC
645 rfi
646
647 .globl dc_read
648dc_read:
649 blr
650
651 .globl get_pvr
652get_pvr:
653 mfspr r3, PVR
654 blr
655
656 .globl get_svr
657get_svr:
658 mfspr r3, SVR
659 blr
660
661
662/*------------------------------------------------------------------------------- */
663/* Function: in8 */
664/* Description: Input 8 bits */
665/*------------------------------------------------------------------------------- */
666 .globl in8
667in8:
668 lbz r3,0x0000(r3)
669 blr
670
671/*------------------------------------------------------------------------------- */
672/* Function: out8 */
673/* Description: Output 8 bits */
674/*------------------------------------------------------------------------------- */
675 .globl out8
676out8:
677 stb r4,0x0000(r3)
678 blr
679
680/*------------------------------------------------------------------------------- */
681/* Function: out16 */
682/* Description: Output 16 bits */
683/*------------------------------------------------------------------------------- */
684 .globl out16
685out16:
686 sth r4,0x0000(r3)
687 blr
688
689/*------------------------------------------------------------------------------- */
690/* Function: out16r */
691/* Description: Byte reverse and output 16 bits */
692/*------------------------------------------------------------------------------- */
693 .globl out16r
694out16r:
695 sthbrx r4,r0,r3
696 blr
697
698/*------------------------------------------------------------------------------- */
699/* Function: out32 */
700/* Description: Output 32 bits */
701/*------------------------------------------------------------------------------- */
702 .globl out32
703out32:
704 stw r4,0x0000(r3)
705 blr
706
707/*------------------------------------------------------------------------------- */
708/* Function: out32r */
709/* Description: Byte reverse and output 32 bits */
710/*------------------------------------------------------------------------------- */
711 .globl out32r
712out32r:
713 stwbrx r4,r0,r3
714 blr
715
716/*------------------------------------------------------------------------------- */
717/* Function: in16 */
718/* Description: Input 16 bits */
719/*------------------------------------------------------------------------------- */
720 .globl in16
721in16:
722 lhz r3,0x0000(r3)
723 blr
724
725/*------------------------------------------------------------------------------- */
726/* Function: in16r */
727/* Description: Input 16 bits and byte reverse */
728/*------------------------------------------------------------------------------- */
729 .globl in16r
730in16r:
731 lhbrx r3,r0,r3
732 blr
733
734/*------------------------------------------------------------------------------- */
735/* Function: in32 */
736/* Description: Input 32 bits */
737/*------------------------------------------------------------------------------- */
738 .globl in32
739in32:
740 lwz 3,0x0000(3)
741 blr
742
743/*------------------------------------------------------------------------------- */
744/* Function: in32r */
745/* Description: Input 32 bits and byte reverse */
746/*------------------------------------------------------------------------------- */
747 .globl in32r
748in32r:
749 lwbrx r3,r0,r3
750 blr
751
752/*------------------------------------------------------------------------------- */
753/* Function: ppcDcbf */
754/* Description: Data Cache block flush */
755/* Input: r3 = effective address */
756/* Output: none. */
757/*------------------------------------------------------------------------------- */
758 .globl ppcDcbf
759ppcDcbf:
760 dcbf r0,r3
761 blr
762
763/*------------------------------------------------------------------------------- */
764/* Function: ppcDcbi */
765/* Description: Data Cache block Invalidate */
766/* Input: r3 = effective address */
767/* Output: none. */
768/*------------------------------------------------------------------------------- */
769 .globl ppcDcbi
770ppcDcbi:
771 dcbi r0,r3
772 blr
773
774/*--------------------------------------------------------------------------
775 * Function: ppcDcbz
776 * Description: Data Cache block zero.
777 * Input: r3 = effective address
778 * Output: none.
779 *-------------------------------------------------------------------------- */
780
781 .globl ppcDcbz
782ppcDcbz:
783 dcbz r0,r3
784 blr
785
786/*------------------------------------------------------------------------------- */
787/* Function: ppcSync */
788/* Description: Processor Synchronize */
789/* Input: none. */
790/* Output: none. */
791/*------------------------------------------------------------------------------- */
792 .globl ppcSync
793ppcSync:
794 sync
795 blr
796
797/*-----------------------------------------------------------------------*/
798/*
799 * void relocate_code (addr_sp, gd, addr_moni)
800 *
801 * This "function" does not return, instead it continues in RAM
802 * after relocating the monitor code.
803 *
804 * r3 = dest
805 * r4 = src
806 * r5 = length in bytes
807 * r6 = cachelinesize
808 */
809 .globl relocate_code
810relocate_code:
811
812 mr r1, r3 /* Set new stack pointer */
813 mr r9, r4 /* Save copy of Global Data pointer */
814 mr r10, r5 /* Save copy of Destination Address */
815
816 mr r3, r5 /* Destination Address */
817 lis r4, CFG_MONITOR_BASE@h /* Source Address */
818 ori r4, r4, CFG_MONITOR_BASE@l
819 lwz r5, GOT(__init_end)
820 sub r5, r5, r4
821 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
822
823 /*
824 * Fix GOT pointer:
825 *
826 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
827 *
828 * Offset:
829 */
830 sub r15, r10, r4
831
832 /* First our own GOT */
833 add r14, r14, r15
834 /* then the one used by the C code */
835 add r30, r30, r15
836
837 /*
838 * Now relocate code
839 */
840#ifdef CONFIG_ECC
841 bl board_relocate_rom
842 sync
843 mr r3, r10 /* Destination Address */
844 lis r4, CFG_MONITOR_BASE@h /* Source Address */
845 ori r4, r4, CFG_MONITOR_BASE@l
846 lwz r5, GOT(__init_end)
847 sub r5, r5, r4
848 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
849#else
850 cmplw cr1,r3,r4
851 addi r0,r5,3
852 srwi. r0,r0,2
853 beq cr1,4f /* In place copy is not necessary */
854 beq 7f /* Protect against 0 count */
855 mtctr r0
856 bge cr1,2f
857
858 la r8,-4(r4)
859 la r7,-4(r3)
8601: lwzu r0,4(r8)
861 stwu r0,4(r7)
862 bdnz 1b
863 b 4f
864
8652: slwi r0,r0,2
866 add r8,r4,r0
867 add r7,r3,r0
8683: lwzu r0,-4(r8)
869 stwu r0,-4(r7)
870 bdnz 3b
871#endif
872/*
873 * Now flush the cache: note that we must start from a cache aligned
874 * address. Otherwise we might miss one cache line.
875 */
8764: cmpwi r6,0
877 add r5,r3,r5
878 beq 7f /* Always flush prefetch queue in any case */
879 subi r0,r6,1
880 andc r3,r3,r0
881 mr r4,r3
8825: dcbst 0,r4
883 add r4,r4,r6
884 cmplw r4,r5
885 blt 5b
886 sync /* Wait for all dcbst to complete on bus */
887 mr r4,r3
8886: icbi 0,r4
889 add r4,r4,r6
890 cmplw r4,r5
891 blt 6b
8927: sync /* Wait for all icbi to complete on bus */
893 isync
894
895/*
896 * We are done. Do not return, instead branch to second part of board
897 * initialization, now running from RAM.
898 */
899 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
900 mtlr r0
901 blr
902
903in_ram:
904#ifdef CONFIG_ECC
905 bl board_init_ecc
906#endif
907 /*
908 * Relocation Function, r14 point to got2+0x8000
909 *
910 * Adjust got2 pointers, no need to check for 0, this code
911 * already puts a few entries in the table.
912 */
913 li r0,__got2_entries@sectoff@l
914 la r3,GOT(_GOT2_TABLE_)
915 lwz r11,GOT(_GOT2_TABLE_)
916 mtctr r0
917 sub r11,r3,r11
918 addi r3,r3,-4
9191: lwzu r0,4(r3)
920 add r0,r0,r11
921 stw r0,0(r3)
922 bdnz 1b
923
924 /*
925 * Now adjust the fixups and the pointers to the fixups
926 * in case we need to move ourselves again.
927 */
9282: li r0,__fixup_entries@sectoff@l
929 lwz r3,GOT(_FIXUP_TABLE_)
930 cmpwi r0,0
931 mtctr r0
932 addi r3,r3,-4
933 beq 4f
9343: lwzu r4,4(r3)
935 lwzux r0,r4,r11
936 add r0,r0,r11
937 stw r10,0(r3)
938 stw r0,0(r4)
939 bdnz 3b
9404:
941/* clear_bss: */
942 /*
943 * Now clear BSS segment
944 */
945 lwz r3,GOT(__bss_start)
946 lwz r4,GOT(_end)
947
948 cmplw 0, r3, r4
949 beq 6f
950
951 li r0, 0
9525:
953 stw r0, 0(r3)
954 addi r3, r3, 4
955 cmplw 0, r3, r4
956 bne 5b
9576:
958 mr r3, r10 /* Destination Address */
959 bl after_reloc
960
961 /* not reached - end relocate_code */
962/*-----------------------------------------------------------------------*/
963
964 /*
965 * Copy exception vector code to low memory
966 *
967 * r3: dest_addr
968 * r7: source address, r8: end address, r9: target address
969 */
970 .globl trap_init
971trap_init:
972 lwz r7, GOT(_start)
973 lwz r8, GOT(_end_of_vectors)
974
975 li r9, 0x100 /* reset vector always at 0x100 */
976
977 cmplw 0, r7, r8
978 bgelr /* return if r7>=r8 - just in case */
979
980 mflr r4 /* save link register */
9811:
982 lwz r0, 0(r7)
983 stw r0, 0(r9)
984 addi r7, r7, 4
985 addi r9, r9, 4
986 cmplw 0, r7, r8
987 bne 1b
988
989 /*
990 * relocate `hdlr' and `int_return' entries
991 */
992 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
993 li r8, Alignment - _start + EXC_OFF_SYS_RESET
9942:
995 bl trap_reloc
996 addi r7, r7, 0x100 /* next exception vector */
997 cmplw 0, r7, r8
998 blt 2b
999
1000 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1001 bl trap_reloc
1002
1003 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1004 bl trap_reloc
1005
1006 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1007 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
10083:
1009 bl trap_reloc
1010 addi r7, r7, 0x100 /* next exception vector */
1011 cmplw 0, r7, r8
1012 blt 3b
1013
1014 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1015 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
10164:
1017 bl trap_reloc
1018 addi r7, r7, 0x100 /* next exception vector */
1019 cmplw 0, r7, r8
1020 blt 4b
1021
1022 /* enable execptions from RAM vectors */
1023 mfmsr r7
1024 li r8,MSR_IP
1025 andc r7,r7,r8
1026 mtmsr r7
1027
1028 mtlr r4 /* restore link register */
1029 blr
1030
1031 /*
1032 * Function: relocate entries for one exception vector
1033 */
1034trap_reloc:
1035 lwz r0, 0(r7) /* hdlr ... */
1036 add r0, r0, r3 /* ... += dest_addr */
1037 stw r0, 0(r7)
1038
1039 lwz r0, 4(r7) /* int_return ... */
1040 add r0, r0, r3 /* ... += dest_addr */
1041 stw r0, 4(r7)
1042
1043 sync
1044 isync
1045
1046 blr
1047
1048.globl enable_ext_addr
1049enable_ext_addr:
1050 mfspr r0, HID0
1051 lis r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h
1052 ori r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l
1053 mtspr HID0, r0
1054 sync
1055 isync
1056 blr
1057
1058#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
1059.globl setup_ccsrbar
1060setup_ccsrbar:
1061 /* Special sequence needed to update CCSRBAR itself */
1062 lis r4, CFG_CCSRBAR_DEFAULT@h
1063 ori r4, r4, CFG_CCSRBAR_DEFAULT@l
1064
1065 lis r5, CFG_CCSRBAR@h
1066 ori r5, r5, CFG_CCSRBAR@l
1067 srwi r6,r5,12
1068 stw r6, 0(r4)
1069 isync
1070
1071 lis r5, 0xffff
1072 ori r5,r5,0xf000
1073 lwz r5, 0(r5)
1074 isync
1075
1076 lis r3, CFG_CCSRBAR@h
1077 lwz r5, CFG_CCSRBAR@l(r3)
1078 isync
1079
1080 blr
1081#endif
1082
1083#ifdef CFG_INIT_RAM_LOCK
1084lock_ram_in_cache:
1085 /* Allocate Initial RAM in data cache.
1086 */
1087 lis r3, (CFG_INIT_RAM_ADDR & ~31)@h
1088 ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
1089 li r2, ((CFG_INIT_RAM_END & ~31) + \
1090 (CFG_INIT_RAM_ADDR & 31) + 31) / 32
1091 mtctr r2
10921:
1093 dcbz r0, r3
1094 addi r3, r3, 32
1095 bdnz 1b
1096#if 1
1097/* Lock the data cache */
1098 mfspr r0, HID0
1099 ori r0, r0, 0x1000
1100 sync
1101 mtspr HID0, r0
1102 sync
1103 blr
1104#endif
1105#if 0
1106 /* Lock the first way of the data cache */
1107 mfspr r0, LDSTCR
1108 ori r0, r0, 0x0080
1109#if defined(CONFIG_ALTIVEC)
1110 dssall
1111#endif
1112 sync
1113 mtspr LDSTCR, r0
1114 sync
1115 isync
1116 blr
1117#endif
1118
1119.globl unlock_ram_in_cache
1120unlock_ram_in_cache:
1121 /* invalidate the INIT_RAM section */
1122 lis r3, (CFG_INIT_RAM_ADDR & ~31)@h
1123 ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
1124 li r2, ((CFG_INIT_RAM_END & ~31) + \
1125 (CFG_INIT_RAM_ADDR & 31) + 31) / 32
1126 mtctr r2
11271: icbi r0, r3
1128 addi r3, r3, 32
1129 bdnz 1b
1130 sync /* Wait for all icbi to complete on bus */
1131 isync
1132#if 1
1133/* Unlock the data cache and invalidate it */
1134 mfspr r0, HID0
1135 li r3,0x1000
1136 andc r0,r0,r3
1137 li r3,0x0400
1138 or r0,r0,r3
1139 sync
1140 mtspr HID0, r0
1141 sync
1142 blr
1143#endif
1144#if 0
1145 /* Unlock the first way of the data cache */
1146 mfspr r0, LDSTCR
1147 li r3,0x0080
1148 andc r0,r0,r3
1149#ifdef CONFIG_ALTIVEC
1150 dssall
1151#endif
1152 sync
1153 mtspr LDSTCR, r0
1154 sync
1155 isync
1156 li r3,0x0400
1157 or r0,r0,r3
1158 sync
1159 mtspr HID0, r0
1160 sync
1161 blr
1162#endif
1163#endif
1164
1165/* If this is a multi-cpu system then we need to handle the
1166 * 2nd cpu. The assumption is that the 2nd cpu is being
1167 * held in boot holdoff mode until the 1st cpu unlocks it
1168 * from Linux. We'll do some basic cpu init and then pass
1169 * it to the Linux Reset Vector.
1170 * Sri: Much of this initialization is not required. Linux
1171 * rewrites the bats, and the sprs and also enables the L1 cache.
1172 */
1173#if (CONFIG_NUM_CPUS > 1)
1174.globl secondary_cpu_setup
1175secondary_cpu_setup:
1176 /* Do only core setup on all cores except cpu0 */
1177 bl invalidate_bats
1178 sync
1179 bl enable_ext_addr
1180
1181#ifdef CFG_L2
1182 /* init the L2 cache */
1183 addis r3, r0, L2_INIT@h
1184 ori r3, r3, L2_INIT@l
1185 sync
1186 mtspr l2cr, r3
1187#ifdef CONFIG_ALTIVEC
1188 dssall
1189#endif
1190 /* invalidate the L2 cache */
1191 bl l2cache_invalidate
1192 sync
1193#endif
1194
1195 /* setup the bats */
1196 bl setup_bats
1197 sync
1198 /* enable address translation */
1199 bl enable_addr_trans
1200 sync
1201
1202 /* enable and invalidate the data cache */
1203 bl dcache_enable
1204 sync
1205
1206 /* enable and invalidate the instruction cache*/
1207 bl icache_enable
1208 sync
1209
1210 /* Set up MSR and HID0, HID1*/
1211 /* Enable interrupts */
1212/* mfmsr r28
1213 li r4,0
1214 ori r4,r4,MSR_EE
1215 or r28,r28,r4
1216 mtmsr r28
1217 */
1218
1219 /* TBEN in HID0 */
1220 mfspr r4, HID0
1221 oris r4, r4, 0x0400
1222 mtspr HID0, r4
1223 sync
1224 isync
1225
1226 /*SYNCBE|ABE in HID1*/
1227 mfspr r4, HID1
1228 ori r4, r4, 0x0C00
1229 mtspr HID1, r4
1230 sync
1231 isync
1232
1233 lis r3, CONFIG_LINUX_RESET_VEC@h
1234 ori r3, r3, CONFIG_LINUX_RESET_VEC@l
1235 mtlr r3
1236 blr
1237
1238 /* Never Returns, Running in Linux Now */
1239#endif
1240