]> rtime.felk.cvut.cz Git - arc.git/blob - arch/ppc/mpc55xx/kernel/arch_krn.sx
Merge with tip
[arc.git] / arch / ppc / mpc55xx / kernel / arch_krn.sx
1 \r
2 /*\r
3  * IVOR4\r
4  * 1. Save stack frames: EXC, VGPR, NVGPR and C\r
5  * 2. Call Irq_Entry(void *curr_stack)\r
6  * 2.1 Check for exception\r
7  * 2.2 If softint, clear it.\r
8  * 2.3 If PROC_ISR1, then just call the function\r
9  * 2.4 If PROC_ISR2 -> it's a PCB, let the OS handle it.\r
10  */\r
11 \r
12 #define _ASSEMBLER_\r
13 #include "asm_ppc.h"\r
14 #include "asm_offset.h"\r
15 #include "asm_book_e.h"\r
16 .extern os_intc_pcb_tbl\r
17 .extern os_intc_types_tbl\r
18 .extern os_sys\r
19 \r
20 \r
21 /*\r
22  * Small assembler school\r
23  * Compare imm(32-bit)\r
24  * > cmpwi rA,100\r
25  * Extract bits and right adjust\r
26  * > extrwi rA,rS,n,b  ( n-number of bits, b- startbit )\r
27  *\r
28  * Note!\r
29  * The offset's (d or D)for SPE instructins are rediculously low.\r
30  * Normally you have 16-bits offset, but when using spe load and store\r
31  * you can use only 8-bit.\r
32 */\r
33 \r
34 #define LOCK()                  wrteei  0\r
35 #define UNLOCK()                wrteei  1\r
36 \r
37 \r
38 .extern os_proc_start_extended\r
39 \r
40 //-------------------------------------------------------------------\r
41 \r
42     .global os_exception_IVOR8\r
43     .balign 16\r
44 os_exception_IVOR8:\r
45         stwu    sp,-(EXC_SIZE+VGPR_SIZE)(sp)\r
46         stw     r3,EXC_R3_OFF(r1)\r
47         stw     r4,EXC_R4_OFF(r1)\r
48         SAVE_EXC_FRAME(3,1,0,SPR_SRR0,SPR_SRR1)\r
49         SAVE_VGPR(1,EXC_SIZE);\r
50         li              r3,328\r
51         stw     r3,EXC_VECTOR_OFF(r1)\r
52 \r
53         rfi\r
54 \r
55 dummy_int:\r
56                 b dummy_int\r
57 \r
58 /*--------------------------------------------------------------------\r
59  * void os_swap_context(pcb_t *old, pcb_t *new )\r
60  *\r
61  * Saves a small context on current stack, pops a new one from new context\r
62  *\r
63  * r3 - pcb for old process\r
64  * r4 - pcb for new process\r
65  *\r
66  *--------------------------------------------------------------------*/\r
67 \r
68 // TODO: this assumes that both are in user mode?.. can this happen under trusted functions?\r
69 //       When I get here we're ALWAYS in kernel mode\r
70 \r
71 .global Os_ArchSwapContextToW\r
72 .global Os_ArchSwapContextTo\r
73 .global Os_ArchSwapContext\r
74 .global Os_ArchSetSpAndCall\r
75 .section .text\r
76 \r
77 Os_ArchSetSpAndCall:\r
78                 mr r1,r3\r
79                 mtlr r4\r
80                 blr\r
81 \r
82 Os_ArchSwapContextToW:\r
83                 mr              r1,r5\r
84                 b               Os_ArchSwapContextTo\r
85 \r
86 Os_ArchSwapContext:\r
87                 // allocate space for context+nvgpr\r
88                 // (no need for proper stack-frame here)\r
89                 stwu    r1,-(C_SIZE+NVGPR_SIZE)(r1)\r
90                 // save lr and cr */\r
91                 mflr    r0\r
92                 stw             r0,C_LR_OFF(sp)\r
93                 mfcr    r0\r
94                 stw             r0,C_CR_OFF(sp)\r
95                 // Save small-context pattern\r
96                 li              r0,SC_PATTERN\r
97                 stw             r0,C_CONTEXT_OFF(sp)\r
98                 // Save registers preserved by function call\r
99                 SAVE_NVGPR(sp,(C_SIZE-14*GPR_SIZE))\r
100 // Save stack ptr...\r
101                 stw             sp,PCB_STACK_CURR_P(r3)\r
102 \r
103 // Stack frame here\r
104 // --------- bottom( high address )\r
105 //  SC_xxx\r
106 //  C_xxx\r
107 // --------- <- stack.curr\r
108 //\r
109 // --------- top( low address )\r
110 \r
111 \r
112 // TODO: If we change application we must change mmu setup\r
113 Os_ArchSwapContextTo:\r
114 // Get stack for new task\r
115                 lwz             sp,PCB_STACK_CURR_P(r4)\r
116 \r
117 // Set new current process\r
118                 LOAD_ADDR_32(3,os_sys)\r
119                 stw             r4,SYS_CURR_PCB_P(r3)\r
120 \r
121 // Restore C context\r
122         lwz     r0,C_CR_OFF(sp)\r
123         mtcr    r0\r
124         lwz     r0,C_LR_OFF (sp)\r
125         mtlr    r0\r
126 \r
127 // Get the context type\r
128                 lwz             r0,C_CONTEXT_OFF(sp)\r
129                 cmpli   0,r0,SC_PATTERN\r
130                 beq+    os_sc_restore\r
131                 cmpli   0,r0,LC_PATTERN\r
132                 beq+    os_lc_restore\r
133                 b               os_bad_bad\r
134 \r
135 \r
136 // SC_xxx\r
137 // C_xxxx <- We point here\r
138 \r
139 os_sc_restore:\r
140                 RESTORE_NVGPR(sp,(C_SIZE-14*GPR_SIZE))\r
141                 addi    sp,sp,(C_SIZE+NVGPR_SIZE)\r
142                 // TODO: The blr will not do the trick if swapping to a user land task.\r
143                 blr\r
144 \r
145 os_lc_restore:\r
146         addi    r1,r1,C_SIZE\r
147         RESTORE_NVGPR(1,0)\r
148         addi    r1,r1,-C_SIZE\r
149         RESTORE_VGPR(1,C_SIZE)\r
150 \r
151         RESTORE_WORK_AND_MORE\r
152         rfi\r
153 \r
154 // When something really bad happens we end up here for the moment\r
155 os_bad_bad:\r
156                 b       os_bad_bad\r
157 \r
158 \r
159 \r
160 \r
161 // ------------------------------------------------------------------\r
162 \r
163 /*\r
164  * Trap interface !!!! See article http://www.linuxjournal.com/article/6516\r
165  * http://www.osweekly.com/index.php?option=com_content&task=view&id=2229\r
166  */\r
167 \r
168 /* The T32 instruction sim can't handle trap's so we have to make something\r
169  * - write SRR0, SRR1, MSR\r
170  * - jump to there routines\r
171  */\r
172 \r
173 // ------------------------------------------------------------------\r
174 \r
175 \r
176 // System call, use this for trusted function ???\r
177 // TODO: The example in autosar is not neccesary.. sc here here instead??\r
178 //\r
179 // NOTE!!!!!\r
180 // Since the sc is a sync call, it should be enough to save NV regs(14->)\r
181 // If I don't use the NV regs here I shouldn't need to save them\r
182 // TODO: Inform compiler in SC_CALL() that I clobber volatile regs( r0, r3->\r
183 //      (since the compiler does not know it's a function call)\r
184 // TODO: Could probably do this shorter....only NV regs that I use need saving\r
185 //       ( only cr2->cr4 according to e500 ABI )\r
186 \r
187 \r
188 \r
189 \r
190 \r
191 \r