base/include/asm-arm/rtai_sched.h

Go to the documentation of this file.
00001 /* 00002 * Architecture specific scheduler support. 00003 * 00004 * Original RTAI/x86 layer implementation: 00005 * Copyright (c) 2000 Paolo Mantegazza (mantegazza@aero.polimi.it) 00006 * Copyright (c) 2000 Steve Papacharalambous (stevep@zentropix.com) 00007 * Copyright (c) 2000 Stuart Hughes 00008 * and others. 00009 * 00010 * RTAI/x86 rewrite over Adeos: 00011 * Copyright (c) 2002 Philippe Gerum (rpm@xenomai.org) 00012 * 00013 * Original RTAI/ARM RTHAL implementation: 00014 * Copyright (c) 2000 Pierre Cloutier (pcloutier@poseidoncontrols.com) 00015 * Copyright (c) 2001 Alex Züpke, SYSGO RTS GmbH (azu@sysgo.de) 00016 * Copyright (c) 2002 Guennadi Liakhovetski DSA GmbH (gl@dsa-ac.de) 00017 * Copyright (c) 2002 Steve Papacharalambous (stevep@zentropix.com) 00018 * Copyright (c) 2002 Wolfgang Müller (wolfgang.mueller@dsa-ac.de) 00019 * Copyright (c) 2003 Bernard Haible, Marconi Communications 00020 * Copyright (c) 2003 Thomas Gleixner (tglx@linutronix.de) 00021 * Copyright (c) 2003 Philippe Gerum (rpm@xenomai.org) 00022 * 00023 * RTAI/ARM over Adeos rewrite: 00024 * Copyright (c) 2004-2005 Michael Neuhauser, Firmix Software GmbH (mike@firmix.at) 00025 * 00026 * RTAI/ARM over Adeos rewrite for PXA255_2.6.7: 00027 * Copyright (c) 2005 Stefano Gafforelli (stefano.gafforelli@tiscali.it) 00028 * Copyright (c) 2005 Luca Pizzi (lucapizzi@hotmail.com) 00029 * 00030 * 00031 * This program is free software; you can redistribute it and/or modify it under 00032 * the terms of the GNU General Public License as published by the Free Software 00033 * Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, USA; either version 2 of 00034 * the License, or (at your option) any later version. 00035 * 00036 * This program is distributed in the hope that it will be useful, but WITHOUT 00037 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00038 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 00039 * details. 00040 * 00041 * You should have received a copy of the GNU General Public License along with 00042 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00043 * Place - Suite 330, Boston, MA 02111-1307, USA. 00044 */ 00045 #ifndef _RTAI_ASM_ARM_RTAI_SCHED_H 00046 #define _RTAI_ASM_ARM_RTAI_SCHED_H 00047 00048 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 00049 # include <asm/proc/ptrace.h> 00050 #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */ 00051 # include <asm/ptrace.h> 00052 # define I_BIT PSR_I_BIT 00053 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) */ 00054 00055 /* 00056 * Registers according to the ARM procedure call standard: 00057 * Reg Description 00058 * r0-r3 argument/scratch registers 00059 * r4-r9 variable register 00060 * r10=sl stack limit/variable register 00061 * r11=fp frame pointer/variable register 00062 * r12=ip intra-procedure-call scratch register 00063 * r13=sp stack pointer (auto preserved) 00064 * r14=lr link register 00065 * r15=pc program counter (auto preserved) 00066 * 00067 * Take special care to restore r0/r1 for startup of new task (-> 00068 * init_arch_stack, rt_startup)! 00069 * 00070 * Stack layout: 00071 * 00072 * Offset Content 00073 * 00074 * 12 r14=lr (i.e. resume point for task) 00075 * 11 r11=fp 00076 * 10 r10=sl 00077 * 9 r9 00078 * 8 r8 00079 * 7 r7 00080 * 6 r6 00081 * 5 r5 00082 * 4 r4 00083 * 3 cpsr 00084 * 2 domain_access_control 00085 * 1 r1 (startup: data) 00086 * 0 r0 (startup: rt_thread) 00087 */ 00088 00089 #define rt_exchange_tasks(old_task, new_task) \ 00090 asm volatile( \ 00091 "mrc p15, 0, r2, c3, c0\n\t" /* get current domain_access_control */ \ 00092 "adr lr, 1f\n\t" /* get address of resume point */ \ 00093 "mrs r3, cpsr\n\t" /* get current cpsr */ \ 00094 "ldr ip, [%[oldp]]\n\t" /* get pointer to old task */ \ 00095 "stmfd sp!, {r0 - fp, lr}\n\t" /* push registers on stack */ \ 00096 "str %[new], [%[oldp]]\n\t" /* *oldp = new */ \ 00097 "str sp, [ip]\n\t" /* save current stack-pointer to old task */ \ 00098 "ldr sp, [%[new]]\n\t" /* get stack-pointer of new task */ \ 00099 "ldmfd sp!, {r0-r3}\n\t" /* pop new tasks' r0, r1, cpsr & d.a.c from stack */ \ 00100 "mcr p15, 0, r2, c3, c0\n\t" /* restore previous domain_access_control */ \ 00101 "msr cpsr_c, %[psr]\n\t" /* disable hw-irqs */ \ 00102 "msr spsr, r3\n\t" /* set spsr to previous cpsr */ \ 00103 "ldmfd sp!, {r4 - fp, pc}^\n\t" /* pop registers, pc = resume point, cpsr = spsr */ \ 00104 "1:" /* resume point (except for startup) */ \ 00105 : /* output */ /* none */ \ 00106 : /* input */ [oldp] "r" (&old_task), \ 00107 [new] "r" (new_task), \ 00108 [psr] "i" (SVC_MODE|I_BIT) \ 00109 : /* clobber */ "lr", "ip", "r2", "r3", "memory" \ 00110 ) 00111 00112 extern inline unsigned long 00113 current_domain_access_control(void) 00114 { 00115 unsigned long domain_access_control; 00116 asm("mrc p15, 0, %0, c3, c0" : "=r" (domain_access_control)); 00117 return domain_access_control; 00118 } 00119 00120 /* 00121 * Set up stack for new proper RTAI task (i.e. kernel task without 00122 * kernel-thread). This is called in rt_task_init_cpuid() where the following 00123 * variables are used (should be arguments to macro!): 00124 * rt_thread pointer to tasks function 00125 * data integer to pass to rt_thread 00126 * 00127 * The stack needs to be set-up so that a rt_exchange_tasks() on the newly 00128 * created task will call rt_startup(rt_thread = r0, data = r1). 00129 * 00130 * See rt_exchange_tasks() above for the stack layout. 00131 * 00132 */ 00133 #define init_arch_stack() \ 00134 do { \ 00135 task->stack -= 13; /* make room on stack */ \ 00136 task->stack[12] = (int)rt_startup; /* entry point */ \ 00137 task->stack[ 3] = SVC_MODE; /* cpsr */ \ 00138 task->stack[ 2] = (int)current_domain_access_control(); \ 00139 task->stack[ 1] = (int)data; /* arg 2 of rt_startup() */ \ 00140 task->stack[ 0] = (int)rt_thread; /* arg 1 " " */ \ 00141 } while (0) 00142 00143 #define DEFINE_LINUX_CR0 00144 #define DEFINE_LINUX_SMP_CR0 00145 #define init_fp_env(spare_fpu_reg) do { /* nop */ } while (0) 00146 00147 extern inline void * 00148 get_stack_pointer(void) 00149 { 00150 void *sp; 00151 asm("mov %0, sp" : "=r" (sp)); 00152 return sp; 00153 } 00154 00155 /* acknowledge timer interrupt in scheduler's timer-handler (using the 00156 * arch-specific rtai_timer_irq_ack()) also allows to bail out of timer irq 00157 * handler (because of spurious interrupt or whatever) */ 00158 #define DO_TIMER_PROPER_OP() \ 00159 do { \ 00160 if (rtai_timer_irq_ack() < 0) \ 00161 return; \ 00162 } while (0) 00163 00164 #endif /* _RTAI_ASM_ARM_RTAI_SCHED_H */

Generated on Thu Nov 20 11:49:49 2008 for RTAI API by doxygen 1.3.8