xref: /reactos/ntoskrnl/ke/arm/ctxswtch.s (revision c2c66aff)
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