]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ppc32/context-ppc32.cpp
ba9514624f51e4be8475ecda8c10b390acef18a8
[l4.git] / kernel / fiasco / src / kern / ppc32 / context-ppc32.cpp
1 IMPLEMENTATION [ppc32]:
2
3 /** Note: TCB pointer is located in sprg1 */
4
5 /*
6 #include <cassert>
7 #include <cstdio>
8
9 #include "l4_types.h"
10 #include "cpu_lock.h"
11 #include "lock_guard.h"
12 #include "space.h"
13 #include "thread_state.h"
14 */
15
16 #include "kmem.h"
17 #include "utcb_support.h"
18
19 IMPLEMENT inline
20 void
21 Context::spill_user_state()
22 {}
23
24 IMPLEMENT inline
25 void
26 Context::fill_user_state()
27 {}
28
29 PUBLIC inline
30 Vcpu_state *
31 Context::access_vcpu(bool = false) const
32 { return vcpu_state(); }
33
34 IMPLEMENT inline
35 void
36 Context::switch_cpu(Context *t)
37 {
38   unsigned long dummy1, dummy2, dummy3;
39
40 //  printf("Switch %p -> %p (sp %p -> %p)\n", this, t, _kernel_sp, t->_kernel_sp);
41 #warning FIXIT: switchin_context_label needs a Context* parameter (old Context *)
42   asm volatile (" lis    %%r5, 1f@ha                \n"
43                 " addi   %%r5, %%r5, 1f@l           \n"
44
45                 //save return addr
46                 " stw    %%r5, 0(%%r1)              \n"
47                 " stw    %%r1, 0(%[kernel_sp])      \n"
48
49                 //switch stack
50                 " mr     %%r1, %[new_sp]            \n"
51                 " mr     %%r3, %[new_thread]        \n"
52
53                 //address space switch
54                 " bl     switchin_context_label     \n"
55                 " lwz    %%r5, 0(%%r1)              \n"
56                 " mtctr  %%r5                       \n"
57                 " bctr                              \n"
58                 "1:                                 \n"
59                 : [new_thread]"=r" (dummy1),
60                   [kernel_sp] "=r" (dummy2),
61                   [new_sp]    "=r" (dummy3)
62                 : "0" (t),
63                   "1" (&_kernel_sp),
64                   "2" (t->_kernel_sp)
65                 : "r0",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
66                   "r8",  "r9",  "r13", "r14", "r15", "r16", "r17", 
67                   "r18", "r19", "r20", "r21", "r22", "r23", "r24",
68                   "r25", "r26", "r27", "r28", "r29", "r30", "r31",
69                   "ctr", "lr",  "cr2", "cr3", "cr4", "xer", "memory"
70                   );
71 }
72
73 /** Thread context switchin.  Called on every re-activation of a
74     thread (switch_exec()).  This method is public only because it is 
75     called by an ``extern "C"'' function that is called
76     from assembly code (call_switchin_context).
77  */
78
79 IMPLEMENT
80 void Context::switchin_context(Context *from)
81 {
82   assert(this == current());
83   assert(state() & Thread_ready);
84   // Set kernel-esp in case we want to return to the user.
85   // kmem::kernel_esp() returns a pointer to the kernel SP (in the
86   // TSS) the CPU uses when next switching from user to kernel mode.  
87   // regs() + 1 returns a pointer to the end of our kernel stack.
88   Kmem::kernel_sp( reinterpret_cast<Mword*>(regs() + 1) );
89 #if 0
90   printf("switch in address space: %p\n",_space);
91 #endif
92
93   // switch to our page directory if nessecary
94   vcpu_aware_space()->switchin_context(from->vcpu_aware_space());
95
96   Utcb_support::current(utcb().usr());
97 }