]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/context-vcpu.cpp
update
[l4.git] / kernel / fiasco / src / kern / context-vcpu.cpp
1 INTERFACE:
2
3 #include "vcpu.h"
4
5 EXTENSION class Context
6 {
7 protected:
8   Space *_vcpu_user_space;
9
10 private:
11   Vcpu_state *_vcpu_state;
12 };
13
14
15 IMPLEMENTATION:
16
17 PROTECTED inline
18 Vcpu_state *
19 Context::vcpu_state() const
20 { return _vcpu_state; }
21
22 PROTECTED inline
23 void
24 Context::vcpu_state(void *s)
25 { _vcpu_state = (Vcpu_state*)s; }
26
27
28 PUBLIC inline
29 Mword
30 Context::vcpu_disable_irqs()
31 {
32   if (EXPECT_FALSE(state() & Thread_vcpu_enabled))
33     {
34       Vcpu_state *vcpu = access_vcpu();
35       Mword s = vcpu->state;
36       vcpu->state = s & ~Vcpu_state::F_irqs;
37       return s & Vcpu_state::F_irqs;
38     }
39   return 0;
40 }
41
42 PUBLIC inline
43 void
44 Context::vcpu_save_state_and_upcall()
45 {
46   extern char leave_by_vcpu_upcall[];
47   _exc_cont.activate(regs(), leave_by_vcpu_upcall);
48 }
49
50 PUBLIC inline NEEDS["fpu.h"]
51 void
52 Context::vcpu_enter_kernel_mode(Vcpu_state *vcpu)
53 {
54   if (EXPECT_FALSE(state() & Thread_vcpu_enabled))
55     {
56       vcpu->_saved_state = vcpu->state;
57       Mword flags = Vcpu_state::F_traps
58                     | Vcpu_state::F_user_mode;
59       vcpu->state &= ~flags;
60       if (state() & Thread_vcpu_user_mode)
61         {
62           vcpu->_sp = vcpu->_entry_sp;
63           state_del_dirty(Thread_vcpu_user_mode | Thread_vcpu_fpu_disabled);
64
65           if (current() == this)
66             {
67               if (state() & Thread_fpu_owner)
68                 Fpu::enable();
69
70               space()->switchin_context(vcpu_user_space());
71             }
72         }
73       else
74         vcpu->_sp = regs()->sp();
75     }
76 }
77
78
79
80 PUBLIC inline
81 bool
82 Context::vcpu_irqs_enabled(Vcpu_state *vcpu) const
83 {
84   return EXPECT_FALSE(state() & Thread_vcpu_enabled)
85     && vcpu->state & Vcpu_state::F_irqs;
86 }
87
88 PUBLIC inline
89 bool
90 Context::vcpu_pagefaults_enabled(Vcpu_state *vcpu) const
91 {
92   return EXPECT_FALSE(state() & Thread_vcpu_enabled)
93     && vcpu->state & Vcpu_state::F_page_faults;
94 }
95
96 PUBLIC inline
97 bool
98 Context::vcpu_exceptions_enabled(Vcpu_state *vcpu) const
99 {
100   return EXPECT_FALSE(state() & Thread_vcpu_enabled)
101     && vcpu->state & Vcpu_state::F_exceptions;
102 }
103
104 PUBLIC inline
105 void
106 Context::vcpu_set_irq_pending()
107 {
108   if (EXPECT_FALSE(state() & Thread_vcpu_enabled))
109     access_vcpu()->sticky_flags |= Vcpu_state::Sf_irq_pending;
110 }
111
112 /** Return the space context.
113     @return space context used for this execution context.
114             Set with set_space_context().
115  */
116 PUBLIC inline NEEDS["kdb_ke.h", "cpu_lock.h"]
117 Space *
118 Context::vcpu_user_space() const
119 {
120   //assert_kdb (cpu_lock.test());
121   return _vcpu_user_space;
122 }
123
124 PUBLIC inline NEEDS["space.h"]
125 void
126 Context::vcpu_set_user_space(Space *t)
127 {
128   assert_kdb (current() == this);
129   if (t)
130     t->inc_ref();
131   else
132     state_del_dirty(Thread_vcpu_user_mode);
133
134   Space *old = _vcpu_user_space;
135   _vcpu_user_space = t;
136
137   if (old)
138     {
139       if (!old->dec_ref())
140         {
141           rcu_wait();
142           delete old;
143         }
144     }
145 }
146
147
148 // --------------------------------------------------------------------------
149 INTERFACE [debug]:
150
151 EXTENSION class Context
152 {
153   static unsigned vcpu_log_fmt(Tb_entry *, int, char *)
154   asm ("__context_vcpu_log_fmt");
155 };
156
157
158 // --------------------------------------------------------------------------
159 IMPLEMENTATION [debug]:
160
161 #include "kobject_dbg.h"
162
163 IMPLEMENT
164 unsigned
165 Context::vcpu_log_fmt(Tb_entry *e, int maxlen, char *buf)
166 {
167   Vcpu_log *l = e->payload<Vcpu_log>();
168
169   switch (l->type)
170     {
171     case 0:
172     case 4:
173       return snprintf(buf, maxlen, "%sret pc=%lx sp=%lx state=%lx task=D:%lx",
174           l->type == 4 ? "f" : "", l->ip, l->sp, l->state, l->space);
175     case 1:
176       return snprintf(buf, maxlen, "ipc from D:%lx task=D:%lx sp=%lx",
177           Kobject_dbg::pointer_to_id((Kobject*)l->ip), l->state, l->sp);
178     case 2:
179       return snprintf(buf, maxlen, "exc #%x err=%lx pc=%lx sp=%lx state=%lx task=D:%lx",
180           (unsigned)l->trap, l->err, l->ip, l->sp, l->state, l->space);
181     case 3:
182       return snprintf(buf, maxlen, "pf  pc=%lx pfa=%lx state=%lx task=D:%lx",
183           l->ip, l->sp, l->state, l->space);
184     default:
185       return snprintf(buf, maxlen, "unknown");
186     }
187 }
188