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