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