Merge upstream kernel changes into 'C/H/S support' branch of libata.
[linux-2.6] / arch / arm / boot / compressed / head-shark.S
1 /* The head-file for the Shark
2  * by Alexander Schulz
3  *
4  * Does the following:
5  * - get the memory layout from firmware. This can only be done as long as the mmu
6  *   is still on.
7  * - switch the mmu off, so we have physical addresses
8  * - copy the kernel to 0x08508000. This is done to have a fixed address where the
9  *   C-parts (misc.c) are executed. This address must be known at compile-time,
10  *   but the load-address of the kernel depends on how much memory is installed.
11  * - Jump to this location.
12  * - Set r8 with 0, r7 with the architecture ID for head.S
13  */
14
15 #include <linux/linkage.h>
16
17 #include <asm/assembler.h>
18         
19                 .section        ".start", "ax"
20
21                 b       __beginning
22         
23 __ofw_data:     .long   0                               @ the number of memory blocks
24                 .space  128                             @ (startaddr,size) ...
25                 .space  128                             @ bootargs
26                 .align
27
28 __beginning:    mov     r4, r0                          @ save the entry to the firmware
29
30                 mov     r0, #0xC0                       @ disable irq and fiq
31                 mov     r1, r0
32                 mrs     r3, cpsr
33                 bic     r2, r3, r0
34                 eor     r2, r2, r1
35                 msr     cpsr_c, r2
36
37                 mov     r0, r4                          @ get the Memory layout from firmware
38                 adr     r1, __ofw_data
39                 add     r2, r1, #4
40                 mov     lr, pc
41                 b       ofw_init
42                 mov     r1, #0
43
44                 adr     r2, __mmu_off                   @ calculate physical address
45                 sub     r2, r2, #0xf0000000             @ openprom maps us at f000 virt, 0e50 phys
46                 adr     r0, __ofw_data
47                 ldr     r0, [r0, #4]
48                 add     r2, r2, r0
49                 add     r2, r2, #0x00500000
50
51                 mrc     p15, 0, r3, c1, c0
52                 bic     r3, r3, #0xC                    @ Write Buffer and DCache
53                 bic     r3, r3, #0x1000                 @ ICache
54                 mcr     p15, 0, r3, c1, c0              @ disabled
55
56                 mov     r0, #0
57                 mcr     p15, 0, r0, c7, c7              @ flush I,D caches on v4
58                 mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer on v4
59                 mcr     p15, 0, r0, c8, c7              @ flush I,D TLBs on v4
60
61                 bic     r3, r3, #0x1                    @ MMU
62                 mcr     p15, 0, r3, c1, c0              @ disabled
63
64                 mov     pc, r2
65
66 __copy_target:  .long   0x08508000
67 __copy_end:     .long   0x08608000
68                 
69                 .word   _start
70                 .word   __bss_start
71
72                 .align
73 __temp_stack:   .space 128
74
75 __mmu_off:
76                 adr     r0, __ofw_data
77                 ldr     r0, [r0, #4]
78                 orr     r0, r0, #0x00600000
79         
80                 ldr     r1, __copy_end
81                 ldr     r3, __copy_target
82
83 /* r0 = 0x0e600000 (current end of kernelcode)
84  * r3 = 0x08508000 (where it should begin)
85  * r1 = 0x08608000 (end of copying area, 1MB)
86  * The kernel is compressed, so 1 MB should be enough.
87  * copy the kernel to the beginning of physical memory
88  * We start from the highest address, so we can copy
89  * from 0x08500000 to 0x08508000 if we have only 8MB
90  */
91
92         
93 __Copy:         ldr     r2, [r0], #-4
94                 str     r2, [r1], #-4
95                 teq     r1, r3
96                 bne     __Copy
97                 /* and jump to it */
98                 adr     r2, __go_on
99                 adr     r0, __ofw_data
100                 ldr     r0, [r0, #4]
101                 sub     r2, r2, r0
102                 sub     r2, r2, #0x00500000
103                 ldr     r0, __copy_target
104                 add     r2, r2, r0
105                 mov     pc, r2
106
107 __go_on:
108                 adr     sp, __temp_stack
109                 add     sp, sp, #128
110                 adr     r0, __ofw_data
111                 mov     lr, pc
112                 b       create_params
113         
114                 mov     r8, #0
115                 mov     r7, #15