Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/agpgart
[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   0x08507FFC
67 __copy_end:     .long   0x08607FFC
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                  @ read the 1. entry of the memory map
77                 ldr     r0, [r0, #4]
78                 orr     r0, r0, #0x00600000
79                 sub     r0, r0, #4
80         
81                 ldr     r1, __copy_end
82                 ldr     r3, __copy_target
83
84 /* r0 = 0x0e600000 (current end of kernelcode)
85  * r3 = 0x08508000 (where it should begin)
86  * r1 = 0x08608000 (end of copying area, 1MB)
87  * The kernel is compressed, so 1 MB should be enough.
88  * copy the kernel to the beginning of physical memory
89  * We start from the highest address, so we can copy
90  * from 0x08500000 to 0x08508000 if we have only 8MB
91  */
92
93 /* As we get more 2.6-kernels it gets more and more
94  * uncomfortable to be bound to kernel images of 1MB only.
95  * So we add a loop here, to be able to copy some more.
96  * Alexander Schulz 2005-07-17
97  */
98
99                 mov     r4, #3                          @ How many megabytes to copy
100
101
102 __MoveCode:     sub     r4, r4, #1
103         
104 __Copy:         ldr     r2, [r0], #-4
105                 str     r2, [r1], #-4
106                 teq     r1, r3
107                 bne     __Copy
108
109                 /* The firmware maps us in blocks of 1 MB, the next block is
110                    _below_ the last one. So our decrementing source pointer
111                    ist right here, but the destination pointer must be increased
112                    by 2 MB */
113                 add     r1, r1, #0x00200000
114                 add     r3, r3, #0x00100000
115
116                 teq     r4, #0
117                 bne     __MoveCode
118
119
120                 /* and jump to it */
121                 adr     r2, __go_on                     @ where we want to jump
122                 adr     r0, __ofw_data                  @ read the 1. entry of the memory map
123                 ldr     r0, [r0, #4]
124                 sub     r2, r2, r0                      @ we are mapped add 0e50 now, sub that (-0e00)
125                 sub     r2, r2, #0x00500000             @ -0050
126                 ldr     r0, __copy_target               @ and add 0850 8000 instead
127                 add     r0, r0, #4
128                 add     r2, r2, r0
129                 mov     pc, r2                          @ and jump there
130
131 __go_on:
132                 adr     sp, __temp_stack
133                 add     sp, sp, #128
134                 adr     r0, __ofw_data
135                 mov     lr, pc
136                 b       create_params
137         
138                 mov     r8, #0
139                 mov     r7, #15