5 EXTENSION class Context
8 Space *_vcpu_user_space;
11 Vcpu_state *_vcpu_state;
19 Context::vcpu_state() const
20 { return _vcpu_state; }
24 Context::vcpu_state(void *s)
25 { _vcpu_state = (Vcpu_state*)s; }
30 Context::vcpu_disable_irqs()
32 if (EXPECT_FALSE(state() & Thread_vcpu_enabled))
34 Mword s = vcpu_state()->state;
35 vcpu_state()->state = s & ~Vcpu_state::F_irqs;
36 return s & Vcpu_state::F_irqs;
43 Context::vcpu_restore_irqs(bool irqs)
45 if (EXPECT_FALSE(state() & Thread_vcpu_enabled) && irqs)
46 vcpu_state()->state |= Vcpu_state::F_irqs;
51 Context::vcpu_save_state_and_upcall()
53 extern char leave_by_vcpu_upcall[];
54 _exc_cont.activate(regs(), leave_by_vcpu_upcall);
57 PUBLIC inline NEEDS["fpu.h"]
59 Context::vcpu_enter_kernel_mode()
61 if (EXPECT_FALSE(state() & Thread_vcpu_enabled))
63 vcpu_state()->_saved_state = vcpu_state()->state;
64 Mword flags = Vcpu_state::F_traps
65 | Vcpu_state::F_user_mode;
66 vcpu_state()->state &= ~flags;
67 if (state() & Thread_vcpu_user_mode)
69 vcpu_state()->_sp = vcpu_state()->_entry_sp;
70 state_del_dirty( Thread_vcpu_user_mode
71 | Thread_vcpu_fpu_disabled
74 if (current() == this)
76 if (state() & Thread_fpu_owner)
79 space()->switchin_context(vcpu_user_space());
83 vcpu_state()->_sp = regs()->sp();
91 Context::vcpu_irqs_enabled() const
93 return EXPECT_FALSE(state() & Thread_vcpu_enabled)
94 && vcpu_state()->state & Vcpu_state::F_irqs;
99 Context::vcpu_pagefaults_enabled() const
101 return EXPECT_FALSE(state() & Thread_vcpu_enabled)
102 && vcpu_state()->state & Vcpu_state::F_page_faults;
107 Context::vcpu_exceptions_enabled() const
109 return EXPECT_FALSE(state() & Thread_vcpu_enabled)
110 && vcpu_state()->state & Vcpu_state::F_exceptions;
115 Context::vcpu_set_irq_pending()
117 if (EXPECT_FALSE(state() & Thread_vcpu_enabled))
118 vcpu_state()->sticky_flags |= Vcpu_state::Sf_irq_pending;
123 Context::vcpu_irqs_pending() const
125 if (EXPECT_FALSE(state() & Thread_vcpu_enabled))
126 return vcpu_state()->sticky_flags & Vcpu_state::Sf_irq_pending;
130 /** Return the space context.
131 @return space context used for this execution context.
132 Set with set_space_context().
134 PUBLIC inline NEEDS["kdb_ke.h", "cpu_lock.h"]
136 Context::vcpu_user_space() const
138 //assert_kdb (cpu_lock.test());
139 return _vcpu_user_space;
142 PUBLIC inline NEEDS["space.h"]
144 Context::vcpu_set_user_space(Space *t)
146 assert_kdb (current() == this);
150 state_del_dirty(Thread_vcpu_user_mode);
152 Space *old = _vcpu_user_space;
153 _vcpu_user_space = t;
166 // --------------------------------------------------------------------------
169 EXTENSION class Context
171 static unsigned vcpu_log_fmt(Tb_entry *, int, char *)
172 asm ("__context_vcpu_log_fmt");
176 // --------------------------------------------------------------------------
177 IMPLEMENTATION [debug]:
179 #include "kobject_dbg.h"
183 Context::vcpu_log_fmt(Tb_entry *e, int maxlen, char *buf)
185 Vcpu_log *l = e->payload<Vcpu_log>();
191 return snprintf(buf, maxlen, "%sret pc=%lx sp=%lx state=%lx task=D:%lx",
192 l->type == 4 ? "f" : "", l->ip, l->sp, l->state, l->space);
194 return snprintf(buf, maxlen, "ipc from D:%lx task=D:%lx sp=%lx",
195 Kobject_dbg::pointer_to_id((Kobject*)l->ip), l->state, l->sp);
197 return snprintf(buf, maxlen, "exc #%x err=%lx pc=%lx sp=%lx state=%lx task=D:%lx",
198 (unsigned)l->trap, l->err, l->ip, l->sp, l->state, l->space);
200 return snprintf(buf, maxlen, "pf pc=%lx pfa=%lx state=%lx task=D:%lx",
201 l->ip, l->sp, l->state, l->space);
203 return snprintf(buf, maxlen, "unknown");