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