Usermode/libc - Fix strchr and strrchr behavior
[tpg/acess2.git] / KernelLand / 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        @ 0x00 Reset
11 ivt_undef:      b Undef_Handler @ 0x04 #UD
12 ivt_svc:        b SVC_Handler   @ 0x08 SVC (used to be called SWI)
13 ivt_prefetch:   b PrefetchAbort @ 0x0C Prefetch abort
14 ivt_data:       b DataAbort     @ 0x10 Data abort
15 ivt_unused:     b .             @ 0x14 Not Used
16 ivt_irq:        b IRQHandler    @ 0x18 IRQ
17 ivt_fiq:        b .             @ 0x1C FIQ (Fast interrupt)
18
19 init_lock:      .long 0
20
21 .extern SHORTLOCK
22 .globl _start
23 _start:
24         ldr r1, =init_lock
25         mov r0, #1
26         swp r0, r0, [r1]
27         tst r0,r0
28         bne .smp_halt
29         
30         ldr r2, =UART0_PADDR
31         mov r1, #'A'
32         str r1, [r2]    
33
34         ldr r0, =kernel_table0-KERNEL_BASE
35         mcr p15, 0, r0, c2, c0, 1       @ Set TTBR1 to r0
36         mcr p15, 0, r0, c2, c0, 0       @ Set TTBR0 to r0 too (for identity)
37
38         mov r1, #'c'
39         str r1, [r2]    
40
41         mov r0, #1
42         mcr p15, 0, r0, c2, c0, 2       @ Set TTCR to 1 (50/50 split)
43
44         mov r1, #'e'
45         str r1, [r2]    
46         
47         mov r0, #3
48         mcr p15, 0, r0, c3, c0, 0       @ Set Domain 0 to Manager
49
50         mov r1, #'s'
51         str r1, [r2]    
52
53         @ Enable VMSA
54         mrc p15, 0, r0, c1, c0, 0
55         orr r0, r0, #1
56         orr r0, r0, #1 << 23
57         mcr p15, 0, r0, c1, c0, 0
58
59         @ HACK: Set ASID to non zero
60         mov r0, #1
61         MCR p15,0,r0,c13,c0,1
62
63         ldr r2, =0xF1000000
64         mov r1, #'s'
65         str r1, [r2]    
66
67         @ Enable access faults on domains 0 & 1
68         mov r0, #0x55   @ 01010101b
69         mcr p15, 0, r0, c3, c0, 0
70
71         mov r1, #'2'
72         str r1, [r2]    
73
74         @
75         @ Check for security extensions
76         @
77         mrc p15, 0, r0, c0, c1, 1
78         and r0, #0xF0
79         beq .no_sec_ext
80         @ - Present
81         ldr r0,=KERNEL_BASE
82         mcr p15, 0, r0, c12, c0, 0      @ Set the VBAR (brings exceptions into high memory)
83         b .exceptions_vectored
84 .no_sec_ext:
85         @ - Absent
86         mrc p15, 0, r0, c1, c0, 0       @ Set SCTLR.V
87         orr r0, #0x2000
88         mcr p15, 0, r0, c1, c0, 0
89 .exceptions_vectored:
90
91         mov r1, #'-'
92         str r1, [r2]    
93
94         @ Prepare for interrupts
95         cps #18 @ IRQ Mode
96         ldr sp, =irqstack+0x1000        @ Set up stack
97         cps #23 @ Abort Mode
98         ldr sp, =abortstack+0x1000
99         cps #19
100
101         mov r1, #'a'
102         str r1, [r2]    
103         mov r1, #'r'
104         str r1, [r2]    
105         mov r1, #'m'
106         str r1, [r2]    
107         mov r1, #13
108         str r1, [r2]    
109         mov r1, #10
110         str r1, [r2]    
111
112 .extern bss_start
113 .extern bss_size_div_4
114 .zero_bss:
115         ldr r0, =bss_start
116         ldr r1, =bss_end
117         mov r3, #0
118 .zero_bss_loop:
119         str r3, [r0],#4
120         cmp r0, r1
121         bls .zero_bss_loop
122
123 .goto_c:
124         ldr sp, =0x80000000-8   @ Set up stack (top of user range)
125         ldr r0, =kmain
126         mov pc, r0
127 1:      b 1b    @ Infinite loop
128 .smp_halt:
129 1:      b 1b
130
131 .comm irqstack, 0x1000  @ ; 4KiB Stack
132 .comm abortstack, 0x1000        @ ; 4KiB Stack
133
134 .extern SyscallHandler
135 SVC_Handler:
136 @       sub lr, #4
137         srsdb sp!, #19  @ Save state to stack
138         cpsie ifa, #19  @ Ensure we're in supervisor with interrupts enabled (should already be there)
139         push {r0-r12}
140
141         ldr r4, [lr,#-4]
142         mvn r5, #0xFF000000
143         and r4, r5
144
145         tst r4, #0x1000 
146         bne .arm_specifics
147
148         push {r4}
149
150         mov r0, sp
151         ldr r4, =SyscallHandler
152         blx r4
153         
154 @       ldr r0, =csSyscallPrintRetAddr
155 @       ldr r1, [sp,#9*4+5*4]
156 @       ldr r4, =Log
157 @       blx r4
158         
159         pop {r2}        @ errno
160         pop {r0,r1}     @ Ret/RetHi
161         add sp, #2*4    @ Saved r2/r3
162
163         pop {r4-r12}
164         rfeia sp!       @ Pop state (actually RFEFD)
165 .arm_specifics:
166         and r4, #0xFF
167         mov r0, r4      @ Number
168         mov r1, sp      @ Arguments
169         
170         ldr r4, =ARMv7_int_HandleSyscalls
171         blx r4
172
173         add sp, #4*4
174         pop {r4-r12}
175         rfeia sp!
176
177
178 .globl gpIRQHandler
179 gpIRQHandler:   .long   0
180 IRQ_saved_sp:   .long   0
181 IRQ_saved_lr:   .long   0
182 .globl IRQHandler
183 IRQHandler:
184         sub lr, #4      @ Adjust LR to the correct value
185         srsdb sp!, #19  @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
186         cps #19
187
188         PUSH_GPRS
189
190 @       ldr r0, =csIRQ_Tag
191 @       ldr r1, =csIRQ_Fmt
192 @       ldr r4, =Log_Debug
193 @       blx r4
194         
195         @ Call the registered handler
196         ldr r0, gpIRQHandler
197         blx r0
198
199         @ Restore CPU state
200         POP_GPRS
201         cpsie i
202         rfeia sp!       @ Pop state (actually RFEFD)
203         bx lr
204
205 .globl DataAbort
206 DataAbort:
207         sub lr, #8      @ Adjust LR to the correct value
208         srsdb sp!, #23  @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
209 @       cpsid ifa, #19
210         PUSH_GPRS
211
212         @ Get the user's LR value (and push to stack)
213         cps #31 @ Go to system mode
214         mov r1, lr
215         cps #19 @ Go to supervisor
216         mov r0, lr
217         cps #23 @ back to exception
218         push {r0,r1}
219         
220         mov r3, #0      @ not a prefetch abort
221         mrc p15, 0, r2, c5, c0, 0       @ Read DFSR (Data Fault Status Register) to R2
222         mrc p15, 0, r1, c6, c0, 0       @ Read DFAR (Data Fault Address Register) into R1
223         mov r0, lr      @ PC
224         ldr r4, =MM_PageFault
225         blx r4
226         add sp, #8      @ Undo push of the user/system LR
227
228         POP_GPRS
229         rfeia sp!       @ Pop state (actually RFEFD)
230
231 .globl PrefetchAbort
232 PrefetchAbort:
233         sub lr, #4      @ Adjust LR to the correct value
234         srsdb sp!, #23  @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
235 @       cpsid ifa, #19
236         PUSH_GPRS
237
238
239         @ Get the user's LR value (and push to stack)
240         cps #31 @ Go to system mode
241         mov r0, lr
242         cps #23 @ back to supervisor
243         push {r0}
244         
245         mrc p15, 0, r2, c5, c0, 1       @ Read IFSR (Instruction Fault Status Register) into R3
246         mrc p15, 0, r1, c6, c0, 2       @ Read IFAR (Instruction Fault Address Register) into R3
247         mov r0, r1
248         mov r3, #1      @ IS a prefetch abort
249         ldr r4, =MM_PageFault
250         blx r4
251         add sp, #4      @ Undo push of the user LR
252
253         POP_GPRS
254         rfeia sp!       @ Pop state (actually RFEFD)
255
256 .globl Undef_Handler
257 Undef_Handler:
258         wfi
259         b Undef_Handler
260
261
262
263 .section .rodata
264 csIRQ_Tag:
265 csAbort_Tag:
266         .asciz "ARMv7"
267 csIRQ_Fmt:
268         .asciz "IRQ"
269 csDataAbort_Fmt:
270         .asciz "Data Abort - %p accessed %p, DFSR=%x Unk:%x Unk:%x"
271 csPrefetchAbort_Fmt:
272         .asciz "Prefetch Abort at %p, IFSR=%x, UserLR:0x%x"
273 csSyscallPrintRetAddr:
274         .asciz "Syscall ret to %p"
275
276 .section .padata
277 .globl kernel_table0
278
279 kernel_table0:
280         .long 0x00000402        @ Identity map the first 1 MiB
281         .rept 0x7FC - 1
282                 .long 0
283         .endr
284         .long user_table1_map + 0x000 - KERNEL_BASE + 1 @ 0x7FC00000
285         .long user_table1_map + 0x400 - KERNEL_BASE + 1 @ 0x7FD00000
286         .long user_table1_map + 0x800 - KERNEL_BASE + 1 @ KStacks
287         .long user_table1_map + 0xC00 - KERNEL_BASE + 1
288         @ 0x80000000 - User/Kernel split
289         .long 0x00000402        @ Map first 4 MiB to 2GiB (KRW only)
290         .long 0x00100402        @ 
291         .long 0x00200402        @ 
292         .long 0x00300402        @ 
293         .rept 0xF00 - 0x800 - 4
294                 .long 0
295         .endr
296 #if PCI_PADDR
297         .long PCI_PADDR +  0*(1 << 20) + 0x402  @ Map PCI config space
298         .long PCI_PADDR +  1*(1 << 20) + 0x402
299         .long PCI_PADDR +  2*(1 << 20) + 0x402
300         .long PCI_PADDR +  3*(1 << 20) + 0x402
301         .long PCI_PADDR +  4*(1 << 20) + 0x402
302         .long PCI_PADDR +  5*(1 << 20) + 0x402
303         .long PCI_PADDR +  6*(1 << 20) + 0x402
304         .long PCI_PADDR +  7*(1 << 20) + 0x402
305         .long PCI_PADDR +  8*(1 << 20) + 0x402
306         .long PCI_PADDR +  9*(1 << 20) + 0x402
307         .long PCI_PADDR + 10*(1 << 20) + 0x402
308         .long PCI_PADDR + 11*(1 << 20) + 0x402
309         .long PCI_PADDR + 12*(1 << 20) + 0x402
310         .long PCI_PADDR + 13*(1 << 20) + 0x402
311         .long PCI_PADDR + 14*(1 << 20) + 0x402
312         .long PCI_PADDR + 15*(1 << 20) + 0x402
313 #else
314         .rept 16
315                 .long 0
316         .endr
317 #endif
318         .long hwmap_table_0 + 0x000 - KERNEL_BASE + 1
319         .long hwmap_table_0 + 0x400 - KERNEL_BASE + 1
320         .long hwmap_table_0 + 0x800 - KERNEL_BASE + 1
321         .long hwmap_table_0 + 0xC00 - KERNEL_BASE + 1
322         .rept 0xFF8 - 0xF00 - 16 - 4
323                 .long 0
324         .endr
325         @ Page fractals
326         .long kernel_table1_map + 0x000 - KERNEL_BASE + 1
327         .long kernel_table1_map + 0x400 - KERNEL_BASE + 1
328         .long kernel_table1_map + 0x800 - KERNEL_BASE + 1
329         .long kernel_table1_map + 0xC00 - KERNEL_BASE + 1
330         .long kernel_exception_map + 0x000 - KERNEL_BASE + 1
331         .long kernel_exception_map + 0x400 - KERNEL_BASE + 1
332         .long kernel_exception_map + 0x800 - KERNEL_BASE + 1
333         .long kernel_exception_map + 0xC00 - KERNEL_BASE + 1
334
335 @ PID0 user table
336 .globl user_table1_map
337 @ User table1 data table (only the first half is needed)
338 @ - Abused to provide kernel stacks in the unused half of the table
339 user_table1_map:        @ Size = 4KiB (only 2KiB used)
340         .rept 0x800/4-1
341                 .long 0
342         .endr
343         .long user_table1_map - KERNEL_BASE + 0x13      @ ...1FF000 = 0x7FDFF000
344         @ Kernel stack zone
345         .long kernel_table0 + 0x0000 - KERNEL_BASE + 0x13       @ ...200000 = 0x7FE00000
346         .long kernel_table0 + 0x1000 - KERNEL_BASE + 0x13       @ ...201000 = 0x7FE01000
347         .rept (0x800/4)-(MM_KSTACK_SIZE/0x1000)-2
348                 .long 0
349         .endr
350         #if MM_KSTACK_SIZE != 0x2000
351         #error Kernel stack size not changed in start.S
352         #endif
353         .long stack + 0x0000 - KERNEL_BASE + 0x13       @ Kernel Stack
354         .long stack + 0x1000 - KERNEL_BASE + 0x13       @ 
355
356 .globl kernel_table1_map
357 kernel_table1_map:      @ Size = 4KiB
358         .rept (0xF00+16)/4
359                 .long 0
360         .endr
361         .long hwmap_table_0 - KERNEL_BASE + 0x13
362         .rept 0xFF8/4 - (0xF00+16)/4 - 1
363                 .long 0
364         .endr
365         .long kernel_table1_map - KERNEL_BASE + 0x13
366         .long kernel_exception_map - KERNEL_BASE + 0x13
367
368 @ Hardware mappings 
369 .globl hwmap_table_0
370 hwmap_table_0:
371         .long UART0_PADDR + 0x13        @ UART0
372         .rept 1024 - 1
373                 .long 0
374         .endr
375 .globl kernel_exception_map
376 kernel_exception_map:
377         @ Padding
378         .rept 1024-256
379                 .long 0
380         .endr
381         @ Align to nearly the end
382         .rept 256-16
383                 .long   0
384         .endr
385         .long 0x212     @ Map first page for exceptions (Kernel RO, Execute)
386         .rept 16-1-2
387                 .long 0
388         .endr
389         .long gUsertextPhysStart + 0x22 @ User .text (User RO, Kernel RW, because both is COW)
390         .long 0
391         
392 .section .padata
393 stack:
394         .space MM_KSTACK_SIZE, 0        @ Original kernel stack
395
396 // vim: ts=8 ft=armv7
397

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