1*c2c66affSColin Finck/* 2*c2c66affSColin Finck * PROJECT: ReactOS Kernel 3*c2c66affSColin Finck * LICENSE: BSD - See COPYING.ARM in the top level directory 4*c2c66affSColin Finck * FILE: ntoskrnl/ke/arm/ctxswtch.s 5*c2c66affSColin Finck * PURPOSE: Context Switch and Idle Thread on ARM 6*c2c66affSColin Finck * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) 7*c2c66affSColin Finck * ReactOS Portable Systems Group 8*c2c66affSColin Finck */ 9*c2c66affSColin Finck 10*c2c66affSColin Finck#include <ksarm.h> 11*c2c66affSColin Finck 12*c2c66affSColin Finck IMPORT KeLowerIrql 13*c2c66affSColin Finck 14*c2c66affSColin Finck TEXTAREA 15*c2c66affSColin Finck 16*c2c66affSColin Finck/*! 17*c2c66affSColin Finck * \name KiSwapContextInternal 18*c2c66affSColin Finck * 19*c2c66affSColin Finck * \brief 20*c2c66affSColin Finck * The KiSwapContextInternal routine switches context to another thread. 21*c2c66affSColin Finck * 22*c2c66affSColin Finck * \param r0 23*c2c66affSColin Finck * Pointer to the KTHREAD to which the caller wishes to switch to. 24*c2c66affSColin Finck * 25*c2c66affSColin Finck * \param r1 26*c2c66affSColin Finck * Pointer to the KTHREAD to which the caller wishes to switch from. 27*c2c66affSColin Finck * 28*c2c66affSColin Finck * \param r2 29*c2c66affSColin Finck * APC bypass 30*c2c66affSColin Finck * 31*c2c66affSColin Finck * \return 32*c2c66affSColin Finck * None. 33*c2c66affSColin Finck * 34*c2c66affSColin Finck * \remarks 35*c2c66affSColin Finck * ... 36*c2c66affSColin Finck * 37*c2c66affSColin Finck *--*/ 38*c2c66affSColin Finck NESTED_ENTRY KiSwapContextInternal 39*c2c66affSColin Finck 40*c2c66affSColin Finck /* Push a KSWITCH_FRAME on the stack */ 41*c2c66affSColin Finck stmdb sp!,{r2,r3,r11,lr} // FIXME: what is the 2nd field? 42*c2c66affSColin Finck // PROLOG_PUSH {r2,r3,r11,lr} 43*c2c66affSColin Finck 44*c2c66affSColin Finck PROLOG_END KiSwapContextInternal 45*c2c66affSColin Finck 46*c2c66affSColin Finck /* Save kernel stack of old thread */ 47*c2c66affSColin Finck str sp, [r1, #ThKernelStack] 48*c2c66affSColin Finck 49*c2c66affSColin Finck /* Save new thread in R11 */ 50*c2c66affSColin Finck mov r11, r0 51*c2c66affSColin Finck 52*c2c66affSColin Finck //bl KiSwapContextSuspend 53*c2c66affSColin Finck __debugbreak 54*c2c66affSColin Finck 55*c2c66affSColin Finck /* Load stack of new thread */ 56*c2c66affSColin Finck ldr sp, [r11, #ThKernelStack] 57*c2c66affSColin Finck 58*c2c66affSColin Finck /* Reload APC bypass */ 59*c2c66affSColin Finck ldr r2, [sp, #SwApcBypass] 60*c2c66affSColin Finck 61*c2c66affSColin Finck //bl KiSwapContextResume 62*c2c66affSColin Finck __debugbreak 63*c2c66affSColin Finck 64*c2c66affSColin Finck /* Restore R2, R11 and return */ 65*c2c66affSColin Finck ldmia sp!,{r2,r3,r11,pc} 66*c2c66affSColin Finck 67*c2c66affSColin Finck NESTED_END KiSwapContextInternal 68*c2c66affSColin Finck 69*c2c66affSColin Finck 70*c2c66affSColin Finck/*! 71*c2c66affSColin Finck * KiSwapContext 72*c2c66affSColin Finck * 73*c2c66affSColin Finck * \brief 74*c2c66affSColin Finck * The KiSwapContext routine switches context to another thread. 75*c2c66affSColin Finck * 76*c2c66affSColin Finck * BOOLEAN 77*c2c66affSColin Finck * KiSwapContext( 78*c2c66affSColin Finck * _In_ KIRQL WaitIrql, 79*c2c66affSColin Finck * _Inout_ PKTHREAD CurrentThread); 80*c2c66affSColin Finck * 81*c2c66affSColin Finck * \param WaitIrql <r0> 82*c2c66affSColin Finck * ... 83*c2c66affSColin Finck * 84*c2c66affSColin Finck * \param CurrentThread <r1> 85*c2c66affSColin Finck * Pointer to the KTHREAD of the current thread. 86*c2c66affSColin Finck * 87*c2c66affSColin Finck * \return 88*c2c66affSColin Finck * The WaitStatus of the Target Thread. 89*c2c66affSColin Finck * 90*c2c66affSColin Finck * \remarks 91*c2c66affSColin Finck * This is a wrapper around KiSwapContextInternal which will save all the 92*c2c66affSColin Finck * non-volatile registers so that the Internal function can use all of 93*c2c66affSColin Finck * them. It will also save the old current thread and set the new one. 94*c2c66affSColin Finck * 95*c2c66affSColin Finck * The calling thread does not return after KiSwapContextInternal until 96*c2c66affSColin Finck * another thread switches to it. 97*c2c66affSColin Finck * 98*c2c66affSColin Finck *--*/ 99*c2c66affSColin Finck NESTED_ENTRY KiSwapContext 100*c2c66affSColin Finck 101*c2c66affSColin Finck /* Push non-volatiles and return address on the stack */ 102*c2c66affSColin Finck stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,lr} 103*c2c66affSColin Finck // PROLOG_PUSH {r4,r5,r6,r7,r8,r9,r10,r11,lr} 104*c2c66affSColin Finck 105*c2c66affSColin Finck PROLOG_END KiSwapContext 106*c2c66affSColin Finck 107*c2c66affSColin Finck /* Do the swap with the registers correctly setup */ 108*c2c66affSColin Finck mov32 r0, 0xFFDFF000 // FIXME: properly load the PCR into r0 (PCR should be in CP15, c3, TPIDRPRW) 109*c2c66affSColin Finck ldr r0, [r0, #PcCurrentThread] /* Pointer to the new thread */ 110*c2c66affSColin Finck bl KiSwapContextInternal 111*c2c66affSColin Finck 112*c2c66affSColin Finck /* Restore non-volatiles and return */ 113*c2c66affSColin Finck ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc} 114*c2c66affSColin Finck 115*c2c66affSColin Finck NESTED_END KiSwapContext 116*c2c66affSColin Finck 117*c2c66affSColin Finck 118*c2c66affSColin Finck 119*c2c66affSColin Finck NESTED_ENTRY KiThreadStartup 120*c2c66affSColin Finck PROLOG_END KiThreadStartup 121*c2c66affSColin Finck 122*c2c66affSColin Finck /* Lower IRQL to APC_LEVEL */ 123*c2c66affSColin Finck mov a1, #1 124*c2c66affSColin Finck bl KeLowerIrql 125*c2c66affSColin Finck 126*c2c66affSColin Finck /* Set the start address and startup context */ 127*c2c66affSColin Finck mov a1, r6 128*c2c66affSColin Finck mov a2, r5 129*c2c66affSColin Finck blx r7 130*c2c66affSColin Finck 131*c2c66affSColin Finck /* The function must not return! */ 132*c2c66affSColin Finck __assertfail 133*c2c66affSColin Finck 134*c2c66affSColin Finck NESTED_END KiThreadStartup 135*c2c66affSColin Finck 136*c2c66affSColin Finck 137*c2c66affSColin Finck NESTED_ENTRY KiSwitchThreads 138*c2c66affSColin Finck PROLOG_END KiSwitchThreads 139*c2c66affSColin Finck 140*c2c66affSColin Finck // UNIMPLEMENTED! 141*c2c66affSColin Finck __debugbreak 142*c2c66affSColin Finck 143*c2c66affSColin Finck NESTED_END KiSwitchThreads 144*c2c66affSColin Finck 145*c2c66affSColin Finck END 146*c2c66affSColin Finck/* EOF */ 147