]> rtime.felk.cvut.cz Git - arc.git/blob - arch/ppc/mpc55xx/kernel/arch.c
Again, loads of refactoring and removing and adding files.
[arc.git] / arch / ppc / mpc55xx / kernel / arch.c
1 /* -------------------------------- Arctic Core ------------------------------
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com
3  *
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>
5  *
6  * This source code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 as published by the
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * for more details.
14  * -------------------------------- Arctic Core ------------------------------*/
15 #include "internal.h"
16 #include "asm_ppc.h"\r
17 #include "mpc55xx.h"\r
18 #include "asm_book_e.h"
19 \r
20 #define USE_DEBUG\r
21 #include "Trace.h"\r
22 \r
23 /**\r
24  * Function make sure that we switch to supervisor mode(rfi) before\r
25  * we call a task for the first time.\r
26  */\r
27 void os_arch_first_call( void )\r
28 {\r
29 #if USE_MM_USER_MODE\r
30 \r
31         // Assume that regs[0] is setup before and contains the settings\r
32         // to switch to user mode.\r
33         register uint32_t msr asm("r3") = os_sys.curr_pcb->regs[0];\r
34         register void *ea asm("r4") = (void *) os_sys.curr_pcb->entry;\r
35 \r
36         // Do the switch\r
37         asm volatile(\r
38                         "mtspr 26,%0;\r\t"      // srr0\r
39                         "mtspr 27,%1;\r\t"      // srr1\r
40                         "rfi;\r\t"\r
41                         :\r
42                         : "r" (ea), "r" (msr)   );\r
43 #else\r
44 // TODO: This really depends on if scheduling policy\r
45         Irq_Enable();\r
46         os_sys.curr_pcb->entry();\r
47 #endif\r
48 }\r
49 \r
50 \r
51 /* TODO: This actually gives the stack ptr here...not the callers stack ptr\r
52  * Should probably be a macro instead..... in some arch part..\r
53  */\r
54 void *Os_ArchGetStackPtr( void ) {\r
55         void *stackp;\r
56         // Get stack ptr(r1) from current context\r
57         asm volatile(" mr %0,1":"=r" (stackp));\r
58 \r
59         return stackp;\r
60 }\r
61 \r
62 unsigned int Os_ArchGetScSize( void ) {\r
63         return SC_SIZE;\r
64 }\r
65 \r
66 extern void os_arch_setup_context_asm( void *context,unsigned int msr);\r
67 \r
68 // TODO: I have no clue why I wrote this????\r
69 void os_arch_stack_to_small(OsPcbType *pcb ,uint32_t size_min) {\r
70         OsPcbType *t;\r
71         uint32_t min;\r
72 \r
73         while(1) {\r
74                 t = pcb;\r
75                 min = size_min;\r
76         }\r
77 }\r
78 \r
79 /*\r
80  * Stack grows from high -> low addresses\r
81  *\r
82 \r
83  *\r
84  *\r
85 \r
86 \r
87  * ----------------  bottom of the stack( high address )\r
88  *  small context\r
89  * ----------------\r
90  *\r
91  * ----------------  top of the stack( low address )\r
92  *\r
93  */\r
94 \r
95 void os_arch_setup_context( OsPcbType *pcb ) {\r
96         uint32_t msr;\r
97         // Note! stack.curr already points to where to save the context\r
98 \r
99         // Check that the stack size is enough\r
100         #define STACK_SIZE_MIN  (SC_SIZE + 16*2 )
101
102 #if 0\r
103         if( pcb->stack.size < (STACK_SIZE_MIN) ) {\r
104                 os_arch_stack_to_small(pcb, STACK_SIZE_MIN);\r
105         }\r
106 #endif
107
108 \r
109         msr = MSR_EE;\r
110 \r
111 #if defined(CFG_SPE)\r
112         msr |= MSR_SPE;\r
113 #endif\r
114
115 #if (  OS_SC3 == STD_ON) || (  OS_SC4== STD_ON)\r
116         if( !pcb->application->trusted ) {\r
117                 // Non-trusted = User mode..\r
118                 msr |= MSR_PR | MSR_DS | MSR_IS;\r
119         }
120 #endif\r
121         pcb->regs[0] = msr;\r
122 }\r
123
124 /**
125  *
126  * @param pcbPtr
127  */
128
129 void OsArch_SetTaskEntry(OsPcbType *pcbPtr ) {
130         uint32_t *context = (uint32_t *)pcbPtr->stack.curr;
131
132         context[C_CONTEXT_OFF/4] = SC_PATTERN;
133
134         /* Set LR to start function */
135         if( pcbPtr->proc_type == PROC_EXTENDED ) {
136                 context[C_LR_OFF/4] = (uint32_t)Os_TaskStartExtended;
137         } else if( pcbPtr->proc_type == PROC_BASIC ) {
138                 context[C_LR_OFF/4] = (uint32_t)Os_TaskStartBasic;
139         }
140 }
141 \r
142 \r
143 #define C_CONTEXT_OFF   12\r
144 #define C_LR_OFF                16\r
145 #define C_CR_OFF                20\r
146 \r
147 void os_arch_print_context( char *str, OsPcbType *pcb ) {\r
148         uint32_t *stack;\r
149 \r
150         dbg_printf("%s CONTEXT: %d\n",str, pcb->pid);\r
151         dbg_printf("  stack: curr=%08x top=%08x bottom=%08x\n",pcb->stack.curr, pcb->stack.top, pcb->stack.top+ pcb->stack.size);\r
152         stack = pcb->stack.curr;\r
153         dbg_printf("  val  : context=%08x LR=%08x CR=%08x\n",\r
154                                         stack[C_CONTEXT_OFF/4],\r
155                                         stack[C_LR_OFF/4],\r
156                                         stack[C_CR_OFF/4]\r
157                                         );\r
158 }\r
159 \r
160 \r
161 void os_arch_init( void ) {\r
162 #if defined(CFG_SPE)\r
163         uint32_t msr = get_msr();\r
164         msr |= MSR_SPE;\r
165         set_msr(msr);\r
166 #endif\r
167 }\r
168 \r
169 #define EXC_VECTOR_CRITICAL_INPUT_OFF   0\r
170 #define EXC_VECTOR_MACHINE_CHECK_OFF    1\r
171 #define EXC_VECTOR_PROGRAM_OFF                  6\r
172 #define EXC_VECTOR_DECREMENTER_OFF              10\r
173 #define EXC_VECTOR_DATA_TLB_OFF                 13\r
174 #define EXC_VECTOR_INSTRUCTION_TLB_OFF  14\r
175 \r
176 \r
177 typedef void (*exc_func_t)(uint32_t *);\r
178 \r
179 /* How do I construct the PTE table ??\r
180  *\r
181  * 1. Calculate the section sizes for each application\r
182  *    ( objdump on the object file)\r
183  * 2. Generate a Table for each application\r
184  *\r
185  * OS207\r
186  * Trusted OS-applications CAN write to\r
187  *\r
188  * What do I do with the global data ???\r
189  *\r
190  *\r
191  */\r
192 \r
193 \r
194 /* Move these somewhere else if we need the speed */\r
195 void os_arch_data_tlb( uint32_t *regs ) {\r
196         uint32_t dear = regs[EXC_DEAR_OFF];\r
197         (void)dear;\r
198 }\r
199 \r
200 void os_arch_instruction_tlb( uint32_t *regs ) {\r
201         uint32_t srr0 = regs[EXC_SRR0_OFF];\r
202         (void)srr0;\r
203         /* What information can I get here??\r
204          * - The pcb to MMU mapping ???\r
205          */\r
206 \r
207         /* TODO: How do I construct the PTE(Page Table Entry) ??*/\r
208 \r
209 }\r
210 \r
211 void os_arch_exc_program( uint32_t *regs ) {\r
212         uint32_t esr = regs[EXC_ESR_OFF];\r
213 \r
214         if( esr & ESR_PTR ) {\r
215                 // Trap\r
216                 if( !(regs[EXC_SRR1_OFF] & MSR_PR) ) {\r
217                         // User -> Supervisor\r
218                         regs[EXC_SRR1_OFF] |= MSR_PR;\r
219                 }\r
220         }\r
221 }\r
222 \r
223 \r