1 /* -------------------------------- Arctic Core ------------------------------
\r
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
\r
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
\r
6 * This source code is free software; you can redistribute it and/or modify it
\r
7 * under the terms of the GNU General Public License version 2 as published by the
\r
8 * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
\r
10 * This program is distributed in the hope that it will be useful, but
\r
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
\r
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
\r
14 * -------------------------------- Arctic Core ------------------------------*/
\r
15 #include "internal.h"
\r
16 #include "asm_ppc.h"
\r
17 #include "mpc55xx.h"
\r
18 #include "asm_book_e.h"
\r
20 #define USE_LDEBUG_PRINTF
\r
24 * Function make sure that we switch to supervisor mode(rfi) before
\r
25 * we call a task for the first time.
\r
27 void Os_ArchFirstCall( void )
\r
29 #if USE_MM_USER_MODE
\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
38 "mtspr 26,%0;\r\t" // srr0
\r
39 "mtspr 27,%1;\r\t" // srr1
\r
42 : "r" (ea), "r" (msr) );
\r
44 // TODO: This really depends on if scheduling policy
\r
46 os_sys.curr_pcb->entry();
\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
54 void *Os_ArchGetStackPtr( void ) {
\r
56 // Get stack ptr(r1) from current context
\r
57 asm volatile(" mr %0,1":"=r" (stackp));
\r
62 unsigned int Os_ArchGetScSize( void ) {
\r
66 extern void os_arch_setup_context_asm( void *context,unsigned int msr);
\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
80 * Stack grows from high -> low addresses
\r
87 * ---------------- bottom of the stack( high address )
\r
91 * ---------------- top of the stack( low address )
\r
95 void Os_ArchSetupContext( OsPcbType *pcb ) {
\r
100 #if defined(CFG_SPE)
\r
104 #if ( OS_SC3 == STD_ON) || ( OS_SC4== STD_ON)
\r
105 if( !pcb->application->trusted ) {
\r
106 // Non-trusted = User mode..
\r
107 msr |= MSR_PR | MSR_DS | MSR_IS;
\r
110 pcb->regs[0] = msr;
\r
118 void Os_ArchSetTaskEntry(OsPcbType *pcbPtr ) {
\r
119 uint32_t *context = (uint32_t *)pcbPtr->stack.curr;
\r
121 context[C_CONTEXT_OFF/4] = SC_PATTERN;
\r
123 /* Set LR to start function */
\r
124 if( pcbPtr->proc_type == PROC_EXTENDED ) {
\r
125 context[C_LR_OFF/4] = (uint32_t)Os_TaskStartExtended;
\r
126 } else if( pcbPtr->proc_type == PROC_BASIC ) {
\r
127 context[C_LR_OFF/4] = (uint32_t)Os_TaskStartBasic;
\r
132 #define C_CONTEXT_OFF 12
\r
133 #define C_LR_OFF 16
\r
134 #define C_CR_OFF 20
\r
136 void os_arch_print_context( char *str, OsPcbType *pcb ) {
\r
139 LDEBUG_PRINTF("%s CONTEXT: %d\n",str, pcb->pid);
\r
140 LDEBUG_PRINTF(" stack: curr=%p top=%p bottom=%p\n",
\r
143 pcb->stack.top+ pcb->stack.size);
\r
144 stack = pcb->stack.curr;
\r
145 LDEBUG_PRINTF(" val : context=%08x LR=%08x CR=%08x\n",
\r
146 (unsigned)stack[C_CONTEXT_OFF/4],
\r
147 (unsigned)stack[C_LR_OFF/4],
\r
148 (unsigned)stack[C_CR_OFF/4]
\r
153 void Os_ArchInit( void ) {
\r
154 #if defined(CFG_SPE)
\r
155 uint32_t msr = get_msr();
\r
161 #define EXC_VECTOR_CRITICAL_INPUT_OFF 0
\r
162 #define EXC_VECTOR_MACHINE_CHECK_OFF 1
\r
163 #define EXC_VECTOR_PROGRAM_OFF 6
\r
164 #define EXC_VECTOR_DECREMENTER_OFF 10
\r
165 #define EXC_VECTOR_DATA_TLB_OFF 13
\r
166 #define EXC_VECTOR_INSTRUCTION_TLB_OFF 14
\r
169 typedef void (*exc_func_t)(uint32_t *);
\r
171 /* How do I construct the PTE table ??
\r
173 * 1. Calculate the section sizes for each application
\r
174 * ( objdump on the object file)
\r
175 * 2. Generate a Table for each application
\r
178 * Trusted OS-applications CAN write to
\r
180 * What do I do with the global data ???
\r
186 /* Move these somewhere else if we need the speed */
\r
187 void os_arch_data_tlb( uint32_t *regs ) {
\r
188 uint32_t dear = regs[EXC_DEAR_OFF];
\r
192 void os_arch_instruction_tlb( uint32_t *regs ) {
\r
193 uint32_t srr0 = regs[EXC_SRR0_OFF];
\r
195 /* What information can I get here??
\r
196 * - The pcb to MMU mapping ???
\r
199 /* TODO: How do I construct the PTE(Page Table Entry) ??*/
\r
203 void os_arch_exc_program( uint32_t *regs ) {
\r
204 uint32_t esr = regs[EXC_ESR_OFF];
\r
206 if( esr & ESR_PTR ) {
\r
208 if( !(regs[EXC_SRR1_OFF] & MSR_PR) ) {
\r
209 // User -> Supervisor
\r
210 regs[EXC_SRR1_OFF] |= MSR_PR;
\r