Kernel/armv7 - Implementing MM_Clone and fixing MMU errors
[tpg/acess2.git] / Kernel / arch / armv7 / start.S
1
2 #include "include/assembly.h"
3 #include "include/options.h"
4
5 @
6 @ Exception defs taken from ARM DDI 0406B
7
8 .section .init
9 interrupt_vector_table:
10 ivt_reset:      b _start @ Reset
11 ivt_undef:      b .     @ #UD
12 ivt_svc:        b SyscallHandler @ SVC (SWI assume)
13 ivt_prefetch:   b PrefetchAbort @ Prefetch abort
14 ivt_data:       b DataAbort     @ Data abort
15 ivt_unused:     b .     @ Not Used
16 ivt_irq:        b IRQHandler    @ IRQ
17 ivt_fiq:        b .     @ FIQ (Fast interrupt)
18
19 .globl _start
20 _start:
21         ldr r0, =kernel_table0-KERNEL_BASE
22         mcr p15, 0, r0, c2, c0, 1       @ Set TTBR1 to r0
23         mcr p15, 0, r0, c2, c0, 0       @ Set TTBR0 to r0 too (for identity)
24
25         mov r0, #1
26         mcr p15, 0, r0, c2, c0, 2       @ Set TTCR to 1 (50/50 split)
27         
28         mov r0, #3
29         mcr p15, 0, r0, c3, c0, 0       @ Set Domain 0 to Manager
30
31         mrc p15, 0, r0, c1, c0, 0
32         orr r0, r0, #1
33         orr r0, r0, #1 << 23
34         mcr p15, 0, r0, c1, c0, 0
35
36         @ Prepare for interrupts
37         cps #18 @ IRQ Mode
38         ldr sp, =irqstack+0x1000        @ Set up stack
39         cps #19
40
41 @       ldr sp, =stack+0x10000  @ Set up stack
42         ldr sp, =0x80000000-4   @ Set up stack (top of user range)
43         ldr r0, =kmain
44         mov pc, r0
45 1:      b 1b    @ Infinite loop
46 _ptr_kmain:
47         .long kmain
48
49 .comm irqstack, 0x1000  @ ; 4KiB Stack
50
51 SyscallHandler:
52         b .
53
54 .globl gpIRQHandler
55 gpIRQHandler:   .long   0
56 IRQ_saved_sp:   .long   0
57 IRQ_saved_lr:   .long   0
58 .globl IRQHandler
59 IRQHandler:
60         sub lr, #4      @ Adjust LR to the correct value
61         srsdb sp!, #19  @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
62         cps #19
63
64         PUSH_GPRS
65
66 @       ldr r0, =csIRQ_Tag
67 @       ldr r1, =csIRQ_Fmt
68 @       ldr r4, =Log_Debug
69 @       blx r4
70         
71         @ Call the registered handler
72         ldr r0, gpIRQHandler
73         blx r0
74
75         @ Restore CPU state
76         POP_GPRS
77         cpsie i
78         rfeia sp!       @ Pop state (actually RFEFD)
79         bx lr
80
81 .globl DataAbort
82 DataAbort:
83         sub lr, #8      @ Adjust LR to the correct value
84         srsdb sp!, #19  @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
85         cpsid ifa, #19
86 @       PUSH_GPRS
87
88         mrc p15, 0, r4, c5, c0, 0       @ Read DFSR (Data Fault Address Register) to stack
89         push {r4}
90         mrc p15, 0, r3, c6, c0, 0       @ Read DFAR (Data Fault Address Register) into R3
91         mov r2, lr
92         ldr r1, =csDataAbort_Fmt
93         ldr r0, =csAbort_Tag
94         ldr r4, =Log_Error
95         blx r4
96         b .
97
98         POP_GPRS
99         rfeia sp!       @ Pop state (actually RFEFD)
100         bx lr
101
102 .globl PrefetchAbort
103 PrefetchAbort:
104         sub lr, #4      @ Adjust LR to the correct value
105         srsdb sp!, #19  @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
106         cpsid ifa, #19
107         PUSH_GPRS
108
109         ldr r0, =csAbort_Tag
110         ldr r1, =csPrefetchAbort_Fmt
111         mov r2, lr
112         mrc p15, 0, r3, c5, c0, 0       @ Read IFSR (Instruction Fault Address Register) into R3
113         ldr r4, =Log_Error
114         blx r4
115         b .
116
117 csIRQ_Tag:
118 csAbort_Tag:
119         .asciz "ARMv7"
120 csIRQ_Fmt:
121         .asciz "IRQ"
122 csDataAbort_Fmt:
123         .asciz "Data Abort - %p accessed %p, DFSR=%x Unk:%x Unk:%x"
124 csPrefetchAbort_Fmt:
125         .asciz "Prefetch Abort at %p, IFSR=%x"
126
127 .section .padata
128 .globl kernel_table0
129
130 kernel_table0:
131         .long 0x00000002        @ Identity map the first 1 MiB
132         .rept 0x7FC - 1
133                 .long 0
134         .endr
135         .long user_table1_map + 0x000 - KERNEL_BASE + 1 @ 0x7FC00000
136         .long user_table1_map + 0x400 - KERNEL_BASE + 1 @ 0x7FD00000
137         .long user_table1_map + 0x800 - KERNEL_BASE + 1 @ KStacks
138         .long user_table1_map + 0xC00 - KERNEL_BASE + 1
139         @ 0x80000000 - User/Kernel split
140         .long 0x00000002        @ Map first 4 MiB to 2GiB
141         .long 0x00100002        @ 
142         .long 0x00200002        @ 
143         .long 0x00300002        @ 
144         .rept 0xF00 - 0x800 - 4
145                 .long 0
146         .endr
147 #if PCI_PADDR
148         .long PCI_PADDR +  0*(1 << 20) + 2      @ Map PCI config space
149         .long PCI_PADDR +  1*(1 << 20) + 2
150         .long PCI_PADDR +  2*(1 << 20) + 2
151         .long PCI_PADDR +  3*(1 << 20) + 2
152         .long PCI_PADDR +  4*(1 << 20) + 2
153         .long PCI_PADDR +  5*(1 << 20) + 2
154         .long PCI_PADDR +  6*(1 << 20) + 2
155         .long PCI_PADDR +  7*(1 << 20) + 2
156         .long PCI_PADDR +  8*(1 << 20) + 2
157         .long PCI_PADDR +  9*(1 << 20) + 2
158         .long PCI_PADDR + 10*(1 << 20) + 2
159         .long PCI_PADDR + 11*(1 << 20) + 2
160         .long PCI_PADDR + 12*(1 << 20) + 2
161         .long PCI_PADDR + 13*(1 << 20) + 2
162         .long PCI_PADDR + 14*(1 << 20) + 2
163         .long PCI_PADDR + 15*(1 << 20) + 2
164 #else
165         .rept 16
166                 .long 0
167         .endr
168 #endif
169         .long hwmap_table_0 + 0x000 - KERNEL_BASE + 1
170         .long hwmap_table_0 + 0x400 - KERNEL_BASE + 1
171         .long hwmap_table_0 + 0x800 - KERNEL_BASE + 1
172         .long hwmap_table_0 + 0xC00 - KERNEL_BASE + 1
173         .rept 0xFF8 - 0xF00 - 16 - 4
174                 .long 0
175         .endr
176         @ Page fractals
177         .long kernel_table1_map + 0x000 - KERNEL_BASE + 1
178         .long kernel_table1_map + 0x400 - KERNEL_BASE + 1
179         .long kernel_table1_map + 0x800 - KERNEL_BASE + 1
180         .long kernel_table1_map + 0xC00 - KERNEL_BASE + 1
181         .rept 0x1000 - 0xFFC
182                 .long 0
183         .endr
184
185 @ PID0 user table
186 .globl user_table1_map
187 @ User table1 data table (only the first half is needed)
188 @ - Abused to provide kernel stacks in upper half
189 user_table1_map:        @ Size = 4KiB (only 2KiB used)
190         .rept 0x800/4-4
191                 .long 0
192         .endr
193         .long kernel_table0 + 0x0000 - KERNEL_BASE + 0x10 + 3   @ ...1FC000 = 0x7FDDC000
194         .long kernel_table0 + 0x1000 - KERNEL_BASE + 0x10 + 3   @ ...1FD000 = 0x7FDDD000
195         .long 0
196         .long user_table1_map - KERNEL_BASE + 0x10 + 3          @ ...1FF000 = 0x7FDFF000
197         @ Kernel stack zone
198         .rept (0x800/4)-(MM_KSTACK_SIZE/0x1000)
199                 .long 0
200         .endr
201         #if MM_KSTACK_SIZE != 0x2000
202         #error Kernel stack size not changed in start.S
203         #endif
204         .long stack + 0x0000 - KERNEL_BASE + 0x10 + 3   @ Kernel Stack
205         .long stack + 0x1000 - KERNEL_BASE + 0x10 + 3   @ 
206
207 .globl kernel_table1_map
208 kernel_table1_map:      @ Size = 4KiB
209         .rept (0xF00+16)/4
210                 .long 0
211         .endr
212         .long hwmap_table_0 - KERNEL_BASE + (1 << 4) + 3
213         .rept 0xFF8/4 - (0xF00+16)/4 - 1
214                 .long 0
215         .endr
216         .long kernel_table1_map - KERNEL_BASE + (1 << 4) + 3
217         .long 0
218
219 @ Hardware mappings 
220 .globl hwmap_table_0
221 hwmap_table_0:
222         .long UART0_PADDR + (1 << 4) + 3        @ UART0
223         .rept 1024 - 1
224                 .long 0
225         .endr
226         
227 .section .padata
228 stack:
229         .space MM_KSTACK_SIZE, 0        @ Original kernel stack
230

UCC git Repository :: git.ucc.asn.au