3 * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
6 * This file is part of TUD:OS and distributed under the terms of the
7 * GNU General Public License 2.
8 * Please see the COPYING-GPL-2 file for details.
10 * As a special exception, you may use this file as part of a free software
11 * library without restriction. Specifically, if other files instantiate
12 * templates or use macros or inline functions from this file, or you compile
13 * this file and link it with other files to produce an executable, this
14 * file does not by itself cause the resulting executable to be covered by
15 * the GNU General Public License. This exception does not however
16 * invalidate any other reasons why the executable file might be covered by
17 * the GNU General Public License.
23 #include <l4/vcpu/vcpu.h>
28 * \brief C++ implementation of state word in the vCPU area
29 * \ingroup api_libvcpu
37 * \brief Initialize state.
39 * \param v Initial state.
41 explicit State(l4vcpu_state_t v) : _s(v) {}
46 * \param bits Bits to add to the word.
48 void add(unsigned bits) throw() { _s |= bits; }
53 * \param bits Bits to clear in the word.
55 void clear(unsigned bits) throw() { _s &= ~bits; }
60 * \param v Set the word to the value of v.
62 void set(l4vcpu_state_t v) throw() { _s = v; }
69 * \brief C++ implementation of the vCPU save state area
70 * \ingroup api_libvcpu
72 class Vcpu : private l4_vcpu_state_t
76 * \brief IRQ status type.
78 typedef l4vcpu_irq_state_t Irq_state;
81 * \brief Disable the vCPU for event delivery.
83 void irq_disable() throw()
84 { l4vcpu_irq_disable(this); }
87 * \brief Disable the vCPU for event delivery and return previous state.
88 * \return IRQ state before disabling IRQs.
90 Irq_state irq_disable_save() throw()
91 { return l4vcpu_irq_disable_save(this); }
94 * \brief Get state word
95 * \return Pointer to state word in the vCPU
97 State *state() throw()
98 { return reinterpret_cast<State *>(&(l4_vcpu_state_t::state)); }
101 * \brief Get state word
102 * \return Pointer to state word in the vCPU
104 State state() const throw()
105 { return static_cast<State>(l4_vcpu_state_t::state); }
108 * \brief Get saved_state word
109 * \return Pointer to saved_state word in the vCPU
111 State *saved_state() throw()
112 { return reinterpret_cast<State *>(&(l4_vcpu_state_t::saved_state)); }
115 * \brief Get saved_state word
116 * \return Pointer to saved_state word in the vCPU
118 State saved_state() const throw()
119 { return static_cast<State>(l4_vcpu_state_t::saved_state); }
122 * \brief Enable the vCPU for event delivery.
124 * \param utcb The UTCB to use.
125 * \param do_event_work_cb Call-back function that is called in case an
126 * event (such as an interrupt) is pending.
127 * \param setup_ipc Call-back function that is called before an
128 * IPC operation is called, and before event
129 * delivery is enabled.
131 void irq_enable(l4_utcb_t *utcb, l4vcpu_event_hndl_t do_event_work_cb,
132 l4vcpu_setup_ipc_t setup_ipc) throw()
133 { l4vcpu_irq_enable(this, utcb, do_event_work_cb, setup_ipc); }
136 * \brief Restore a previously saved IRQ/event state.
138 * \param s IRQ state to be restored.
139 * \param utcb The UTCB to use.
140 * \param do_event_work_cb Call-back function that is called in case an
141 * event (such as an interrupt) is pending.
142 * \param setup_ipc Call-back function that is called before an
143 * IPC operation is called, and before event
144 * delivery is enabled.
146 void irq_restore(Irq_state s, l4_utcb_t *utcb,
147 l4vcpu_event_hndl_t do_event_work_cb,
148 l4vcpu_setup_ipc_t setup_ipc) throw()
149 { l4vcpu_irq_restore(this, s, utcb, do_event_work_cb, setup_ipc); }
152 * \brief Wait for event.
154 * \param utcb The UTCB to use.
155 * \param do_event_work_cb Call-back function that is called in case an
156 * event (such as an interrupt) is pending.
157 * \param setup_ipc Call-back function that is called before an
158 * IPC operation is called.
160 * Note that event delivery remains disabled after this function returns.
162 void wait_for_event(l4_utcb_t *utcb, l4vcpu_event_hndl_t do_event_work_cb,
163 l4vcpu_setup_ipc_t setup_ipc) throw()
164 { l4vcpu_wait_for_event(this, utcb, do_event_work_cb, setup_ipc); }
167 * \brief Set the task of the vCPU.
168 * \param task Task to set, defaults to invalid task.
170 void task(L4::Cap<L4::Task> const task = L4::Cap<L4::Task>::Invalid) throw()
171 { user_task = task.cap(); }
174 * \brief Return whether the entry reason was a page fault.
175 * return 0 if not, !=0 otherwise.
177 int is_page_fault_entry()
178 { return l4vcpu_is_page_fault_entry(this); }
181 * \brief Return whether the entry reason was an IRQ/IPC message.
182 * return 0 if not, !=0 otherwise.
185 { return l4vcpu_is_irq_entry(this); }
188 * \brief Return pointer to register state.
189 * \return Pointer to register state.
191 l4_vcpu_regs_t *r() throw()
192 { return &(l4_vcpu_state_t::r); }
195 * \brief Return pointer to register state.
196 * \return Pointer to register state.
198 l4_vcpu_regs_t const *r() const throw()
199 { return &(l4_vcpu_state_t::r); }
202 * \brief Return pointer to IPC state.
203 * \return Pointer to IPC state.
205 l4_vcpu_ipc_regs_t *i() throw()
206 { return &(l4_vcpu_state_t::i); }
209 * \brief Return pointer to IPC state.
210 * \return Pointer to IPC state.
212 l4_vcpu_ipc_regs_t const *i() const throw()
213 { return &(l4_vcpu_state_t::i); }
216 * \brief Set vCPU entry stack pointer.
217 * \param sp Stack pointer address to set.
219 * \note The value is only used when entering from a user-task.
221 void entry_sp(l4_umword_t sp)
222 { l4_vcpu_state_t::entry_sp = sp; }
225 * \brief Set vCPU entry instruction pointer.
226 * \param ip Instruction pointer address to set.
228 void entry_ip(l4_umword_t ip)
229 { l4_vcpu_state_t::entry_ip = ip; }
232 * \brief Allocate state area for an extended vCPU.
234 * \retval vcpu Allocated vcpu-state area.
235 * \retval ext_state Allocated extended vcpu-state area.
236 * \param task Task to use for allocation, defaults to own task.
237 * \param rm Region manager to use for allocation defaults to standard region manager.
239 * \return 0 for success, error code otherwise
242 ext_alloc(Vcpu **vcpu,
243 l4_addr_t *ext_state,
244 L4::Cap<L4::Task> task = L4Re::Env::env()->task(),
245 L4::Cap<L4Re::Rm> rm = L4Re::Env::env()->rm()) throw();
248 * \brief Cast a void pointer to a class pointer.
252 * \return Pointer to Vcpu class.
254 static inline Vcpu *cast(void *x) throw()
255 { return reinterpret_cast<Vcpu *>(x); }
258 * \brief Cast an address to a class pointer.
262 * \return Pointer to Vcpu class.
264 static inline Vcpu *cast(l4_addr_t x) throw()
265 { return reinterpret_cast<Vcpu *>(x); }
268 * \brief Print the state of the vCPU.
270 void print_state(const char *prefix = "") throw()
271 { l4vcpu_print_state(this, prefix); }