revert between 56095 -> 55830 in arch
[AROS.git] / arch / ppc-all / prep / startup / startup.S
blobad20bb6d6f2756a3e6df089ae9fc95bb9a9da030
1 /*
2     Copyright C 2003, The AROS Development Team. All rights reserved.
3     $Id$
5     Desc: Bootstrap code for AROS/PPC on PReP
6     Lang: English
7 */
9 /*
10     This is the startup code for PReP (PowerPC Reference Platform) machines.
11     It may be loaded by Firmware into ram (at almost any possible location).
13     Real kernel location.
14     The older PReP machines have the DMA area limited to first 16MB of system
15     memory. Therefore it is reasonable, to place the kernel at the end of DMA
16     RAM. Both areas may be then easily separated.
18     Currently, the kernel should be located at 15th megabyte of RAM but it may
19     be changed in future.
22 #include <asm/ppc.h>
24         .text
26         .globl  startup
27         .type   startup,@function
28 startup:
29         /* Update the Link Pointer by jumping to the next instruction */
30         /* this way we know exactly where the code is loaded */
32         bl      1f
34         .globl  core_id
35 core_id:
36         .string "PPC Core 1.0"
37         .balign 4,0
39 1:      mflr    r20             /* Extract the laod address */
40         addi    r20,r20,-4
41         
42         mr      r30,r3          /* Residual/boot data */
43         mr      r31,r5          /* OFW pointer */
45         li      r3,'B'
46         bl      com1_putc
48         mfmsr   r29
49         /* Enable FPU and chose the 0xFFFxxxxx prefix for exception table */
50         li      r3,(MSR_FP|MSR_IP)
51         mtmsr   r3
53         li      r3,'O'
54         bl      com1_putc
56         lis     r4,startup@h    /* Calculate the size of kernel */
57         ori     r4,r4,startup@l
58         lis     r5,_END@h
59         ori     r5,r5,_END@l
60         addi    r5,r5,3
61         srwi    r21,r21,2
62         sub     r21,r5,r4       /* r21 contains the size of kernel in words */
63         mr      r22,r4
65         li      r3,'O'
66         bl      com1_putc
67         
68         /* Is the required address same as the load address? */
69         cmp     0,r20,r4
70         beq     address_ok
72 reloc:
73         addi    r3,r20,-4       /* r3 contains the target - 4 */
74         addi    r4,r4,-4        /* r4 contains the source - 4 */
75         mtctr   r21             /* length of data to move */
76 0:      lwzu    r5,4(r3)
77         stwu    r5,4(r4)
78         bdnz    0b
80         /* Jump to the relocated code */
81         lis     r5,address_ok@h
82         ori     r5,r5,address_ok@l
83         mtlr    r5
84         blr
85         
86 address_ok:
87         li      r3,'T'
88         bl      com1_putc
91     Setup the stack pointer. It will start just a little bit before the         
92     kernel. We may relocate it later.
94     I know this is a bit tricky hack, but I really want to avoid any .data
95     or .bss sections in kernel.
98         lis     r9,startup@h
99         la      r3,startup@l(r9)
100         addi    r1,r3,-32
101         rlwinm  r1,r1,0,0,27
104     Oh my.... if it happend at all, that we have some .bbs data, I should clear
105     it now. Other possibility would be to halt the kernel, display the message
106     that the kernel is f**ked and restart ;)
109         li      r0,0
110         lis     r3,_EDATA@h
111         ori     r3,r3,_EDATA@l
112         lis     r4,_END@h
113         ori     r4,r4,_END@l
114         sub.    r4,r4,r3
115         beq+    1f
116         subi    r3,r3,4
117         mtctr   r4
118 0:      stwu    r0,4(r3)
119         bdnz    0b
122         li      r0,0
123         /* Clear all BAT registers as we don't need any memory translation */
124         mtspr   DBAT0U,r0
125         mtspr   DBAT0L,r0
126         mtspr   DBAT1U,r0
127         mtspr   DBAT1L,r0
128         mtspr   DBAT2U,r0
129         mtspr   DBAT2L,r0
130         mtspr   DBAT3U,r0
131         mtspr   DBAT3L,r0
133         mtspr   IBAT0U,r0
134         mtspr   IBAT0L,r0
135         mtspr   IBAT1U,r0
136         mtspr   IBAT1L,r0
137         mtspr   IBAT2U,r0
138         mtspr   IBAT2L,r0
139         mtspr   IBAT3U,r0
140         mtspr   IBAT3L,r0
142 /* Setup the segment registers - Linear memory area 0x00000000 - 0xffffffff */
144         li      r3,16
145         mtctr   r3
146         lis     r3,0x2000
147         li      r4,0
148 2:      mtsrin  r3,r4
149         addi    r3,r3,0x0111
150         addis   r4,r4,0x1000
151         bdnz    2b
153         mr      r3,r20      /* load address */
154         mr      r4,r22      /* Real kernel address */
155         mr      r5,r21      /* Size of kernel in words */
156         mr      r6,r30      /* Residual/boot data */
157         mr      r7,r31      /* OFW pointer */
158         mr      r8,r29      /* Original MSR for OFW interface */
159         b       cstart      /* Jump to the C-part of kernel */
162         .globl  com1_putc
163         .type com1_putc,@function
164 com1_putc:
165         lis     r9,0x8000
166         ori     r9,r9,0x3f8
167 1:      lbz     r0,5(r9)
168         andi.   r11,r0,32
169         bc      12,2,1b
170         stb     r3,0(r9)
171         sync
172         blr