1: /*
2: *----------------------------------------------------------------------
3: * T-Kernel 2.0 Software Package
4: *
5: * Copyright 2011 by Ken Sakamura.
6: * This software is distributed under the latest version of T-License 2.x.
7: *----------------------------------------------------------------------
8: *
9: * Released by T-Engine Forum(http://www.t-engine.org/) at 2011/05/17.
10: * Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
11: *
12: *----------------------------------------------------------------------
13: */
14:
15: /*
16: * monhdr.S
17: *
18: * Monitor handler (after ARMv6)
19: */
20:
21: #define _in_asm_source_
22:
23: #include <machine.h>
24: #include <sys/sysinfo.h>
25: #include "cpudep.h"
26:
27: /*
28: * Monitor entry (registered as default handler)
29: * +---------------+
30: * sp -> |R3 | <- only in the case of interrupt
31: * +---------------+
32: * |R12=ip |
33: * |R14=lr | <- return address from exception / interupt
34: * |SPSR |
35: * +---------------+
36: * registers upon handler invocation
37: * r3 = varies according machine type and situation (only in the case of interrupt)
38: * ip = vector table address
39: * lr = indeterminate
40: */
41: .text
42: .balign 4
43: .globl Csym(_defaultHdr)
44: .type Csym(_defaultHdr), %function
45: Csym(_defaultHdr):
46: // save register
47: // regStack[0-7] r0 .. r7
48: // [8,9] Entry cspr, ip
49: // [10] return cspr
50: // [11] return r15(pc)
51: // [12-18] USR: r8 ..r12, sp, lr
52: // [19-26] FIQ: spsr, r8 ..r12, sp, lr
53: // [27-29] IRQ: spsr, sp, lr
54: // [30-32] ABT: spsr, sp, lr
55: // [33-35] UND: spsr, sp, lr
56: // [36-38] SVC: spsr, sp, lr
57: // [39] CP15: SCTLR (CP15.c1.0.c0.0)
58: // [40-42] TTBR0,TTBR1,TTBCR (CP15.c2.0.c0.0 - 2)
59: // [43] DACR (CP15.c3.0.c0.0)
60: // [44-45] DFSR,IFSR (CP15.c5.0.c0.0 - 1)
61: // [46-47] DFAR,IFAR (CP15.c6.0.c0.0,2)
62: // [48] CTXIDR (CP15.c13.0.c0.1)
63:
64: // save r0 .. r7
65: ldr lr, =Csym(regStack)
66: stmia lr!, {r0-r2} // r0 .. r2
67:
68: // restore R3 inside stack in the case of interrupt
69: mrs r1, cpsr // cpsr -> r1
70: and r0, r1, #PSR_M(31)
71: cmp r0, #PSR_FIQ
72: cmpne r0, #PSR_IRQ
73: ldmeqfd sp!, {r3} // in the case of interrupt
74:
75: stmia lr!, {r3-r7} // r3 .. r7
76: mov r7, lr // regStack -> r7
77:
78: // save the status on entry (cpsr, ip)
79: cpsid aif // disable FIQ and IRQ
80: stmia r7!, {r1, ip} // Entry cspr & ip saved
81:
82: // restore ip, lr, spsr from the values inside stack and return
83: ldr r2, =EIT_VECTBL
84: sub r0, ip, r2
85: mov r0, r0, asr #2 // interrupt/exception vector number -> r0
86: ldmfd sp!, {ip, lr} // restore ip and lr
87: ldmfd sp!, {r2} // r2 <- spsr restored
88: stmia r7!, {r2, lr} // save spsr, lr(pc)
89:
90: // save registers of each mode
91: stmia r7, {r8-r12,sp,lr}^ // usr: r8 .. r12,sp,lr
92: add r7, r7, #(4*7)
93:
94: cps #PSR_FIQ
95: mrs r3, spsr
96: stmia r7!, {r3, r8-r12,sp,lr} // fiq: spsr, r8 .. r12,sp,lr
97:
98: cps #PSR_IRQ
99: mrs r3, spsr
100: stmia r7!, {r3, sp, lr} // irq: spsr, sp, lr
101:
102: cps #PSR_ABT
103: mrs r3, spsr
104: stmia r7!, {r3, sp, lr} // abt: spsr, sp, lr
105:
106: cps #PSR_UND
107: mrs r3, spsr
108: stmia r7!, {r3, sp, lr} // und: spsr, sp, lr
109:
110: cps #PSR_SVC
111: mrs r3, spsr
112: stmia r7!, {r3, sp, lr} // svc: spsr, sp, lr
113:
114: mrc p15, 0, r2, cr1, cr0, 0
115: mrc p15, 0, r3, cr2, cr0, 0
116: mrc p15, 0, r4, cr2, cr0, 1
117: mrc p15, 0, r5, cr2, cr0, 2
118: mrc p15, 0, r6, cr3, cr0, 0
119: stmia r7!, {r2,r3,r4,r5,r6} // cp15: r1,r2,r3
120:
121: mrc p15, 0, r2, cr5, cr0, 0
122: mrc p15, 0, r3, cr5, cr0, 1
123: mrc p15, 0, r4, cr6, cr0, 0
124: mrc p15, 0, r5, cr6, cr0, 2
125: mrc p15, 0, r6, cr13, cr0, 1 // cp15: r5,r6,r13
126: stmia r7!, {r2,r3,r4,r5,r6}
127:
128: ldr r2, =0xFFFFFFFF
129: mcr p15, 0, r2, cr3, cr0, 0 // cp15:r3(domain) manager
130:
131: // set up stack exclusively used for monitor (SVC mode)
132: ldr r2, =__stack_top
133: ldr r3, =__stack_bottom // stack exclusively used for monitor
134: cmp sp, r2
135: cmpcs r3, sp // using monitor stack?
136: movcc sp, r3 // switch to monitor stack
137:
138: // monitor entry: r0 = interrupt/exception vector number (r1 = cpsr) : SVC mode
139: bl Csym(entMonitor) // call entMonitor(vec)
140:
141: // restore registers
142: ldr r7, =Csym(regStack) + ((39 + 10) * 4)
143:
144: ldmdb r7!, {r2,r3,r4,r5,r6} // cp15: r5,r6,r13
145: mcr p15, 0, r2, cr5, cr0, 0
146: mcr p15, 0, r3, cr5, cr0, 1
147: mcr p15, 0, r4, cr6, cr0, 0
148: mcr p15, 0, r5, cr6, cr0, 2
149: mcr p15, 0, r6, cr13, cr0, 1
150:
151: ldmdb r7!, {r2,r3,r4,r5,r6} // cp15: r1,r2,r3
152: // mcr p15, 0, r2, cr1, cr0, 0 // already restored inside entMonitor
153: //RO mcr p15, 0, r3, cr2, cr0, 0 // no need to restore (Read Only)
154: //RO mcr p15, 0, r4, cr2, cr0, 1
155: //RO mcr p15, 0, r5, cr2, cr0, 2
156: mcr p15, 0, r6, cr3, cr0, 0
157:
158: ldmdb r7!, {r3, sp, lr} // svc: spsr, sp, lr
159: msr spsr_fsxc, r3
160: mov r1, lr // r1: lr_svc (used for forcible terminal of processes)
161:
162: cps #PSR_UND
163: ldmdb r7!, {r3, sp, lr} // und: spsr, sp, lr
164: msr spsr_fsxc, r3
165:
166: cps #PSR_ABT
167: ldmdb r7!, {r3, sp, lr} // abt: spsr, sp, lr
168: msr spsr_fsxc, r3
169:
170: cps #PSR_IRQ
171: ldmdb r7!, {r3, sp, lr} // irq: spsr, sp, lr
172: msr spsr_fsxc, r3
173:
174: cps #PSR_FIQ
175: ldmdb r7!, {r3, r8-r12,sp,lr} // fiq: spsr, r8 .. r12,sp,lr
176: msr spsr_fsxc, r3
177:
178: sub r7, r7, #(4*7)
179: ldmia r7, {r8-r12,sp,lr}^ // usr: r8 .. r12,sp,lr
180:
181: // restore status on etry
182: ldmdb r7!, {r0, r2, r3, r4} // r0:Entry cpsr, r2:Entry ip
183: // r3:cpsr(spsr), r4:pc(lr)
184: msr cpsr_fsxc, r0 // entry cpsr
185: stmfd sp!, {r3} // spsr -> stack
186: stmfd sp!, {r4} // pc(lr) -> stack
187:
188: // do we have request for forcible termination of processe(es)?
189: ldr r4, =Csym(killProcReq)
190: ldr r0, [r4]
191: tst r0, #0xff
192: beq no_kill // no request
193: mov r0, #0
194: str r0, [r4] // clear forcible termination request
195:
196: // restore to the state on entry completely, and then push lr_svc
197: stmfd sp!, {r1, ip} // sp -> lr_svc, ip
198: mov ip, r2 // restore ip
199: ldmdb r7, {r0-r7} // r0 .. r7
200:
201: swi #SWI_KILLPROC // forcible termination of processes request
202: nop // do not return
203: nop
204:
205: no_kill:
206: ldmdb r7, {r0-r7} // r0 .. r7
207:
208: // return from monitor
209: rfefd sp!
210:
211: /* ------------------------------------------------------------------------ */
212:
213: /*
214: * calling an external program
215: * W callExtProg( FP entry )
216: */
217: .text
218: .balign 4
219: .globl Csym(callExtProg)
220: .type Csym(callExtProg), %function
221: Csym(callExtProg):
222: stmfd sp!, {r4-r10, fp, lr} // save registers
223: blx r0 // call entry(void)
224: ldmfd sp!, {r4-r10, fp, pc} // restore registers