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.
130 void irq_enable(l4_utcb_t *utcb, l4vcpu_event_hndl_t do_event_work_cb,
131 l4vcpu_setup_ipc_t setup_ipc) throw()
132 { l4vcpu_irq_enable(this, utcb, do_event_work_cb, setup_ipc); }
135 * \brief Restore a previously saved IRQ/event state.
137 * \param s IRQ state to be restored.
138 * \param utcb The UTCB to use.
139 * \param do_event_work_cb Call-back function that is called in case an
140 * event (such as an interrupt) is pending.
141 * \param setup_ipc Call-back function that is called before an
142 * IPC operation is called.
144 void irq_restore(Irq_state s, l4_utcb_t *utcb,
145 l4vcpu_event_hndl_t do_event_work_cb,
146 l4vcpu_setup_ipc_t setup_ipc) throw()
147 { l4vcpu_irq_restore(this, s, utcb, do_event_work_cb, setup_ipc); }
150 * \brief Halt/block the vCPU.
152 * \param utcb The UTCB to use.
153 * \param do_event_work_cb Call-back function that is called in case an
154 * event (such as an interrupt) is pending.
155 * \param setup_ipc Call-back function that is called before an
156 * IPC operation is called.
158 void halt(l4_utcb_t *utcb, l4vcpu_event_hndl_t do_event_work_cb,
159 l4vcpu_setup_ipc_t setup_ipc) throw()
160 { l4vcpu_halt(this, utcb, do_event_work_cb, setup_ipc); }
163 * \brief Set the task of the vCPU.
164 * \param task Task to set, defaults to invalid task.
166 void task(L4::Cap<L4::Task> const task = L4::Cap<L4::Task>::Invalid) throw()
167 { user_task = task.cap(); }
170 * \brief Return whether the entry reason was a page fault.
171 * return 0 if not, !=0 otherwise.
173 int is_page_fault_entry()
174 { return l4vcpu_is_page_fault_entry(this); }
177 * \brief Return whether the entry reason was an IRQ/IPC message.
178 * return 0 if not, !=0 otherwise.
181 { return l4vcpu_is_irq_entry(this); }
184 * \brief Return pointer to register state.
185 * \return Pointer to register state.
187 l4_vcpu_regs_t *r() throw()
188 { return &(l4_vcpu_state_t::r); }
191 * \brief Return pointer to register state.
192 * \return Pointer to register state.
194 l4_vcpu_regs_t const *r() const throw()
195 { return &(l4_vcpu_state_t::r); }
198 * \brief Return pointer to IPC state.
199 * \return Pointer to IPC state.
201 l4_vcpu_ipc_regs_t *i() throw()
202 { return &(l4_vcpu_state_t::i); }
205 * \brief Return pointer to IPC state.
206 * \return Pointer to IPC state.
208 l4_vcpu_ipc_regs_t const *i() const throw()
209 { return &(l4_vcpu_state_t::i); }
212 * \brief Set vCPU entry stack pointer.
213 * \param sp Stack pointer address to set.
215 * \note The value is only used when entering from a user-task.
217 void entry_sp(l4_umword_t sp)
218 { l4_vcpu_state_t::entry_sp = sp; }
221 * \brief Set vCPU entry instruction pointer.
222 * \param ip Instruction pointer address to set.
224 void entry_ip(l4_umword_t ip)
225 { l4_vcpu_state_t::entry_ip = ip; }
228 * \brief Allocate state area for an extented vCPU.
230 * \retval vcpu Allocated vcpu-state area.
231 * \retval ext_state Allocated extended vcpu-state area.
232 * \param task Task to use for allocation, defaults to own task.
233 * \param rm Region manager to use for allocation defaults to standard region manager.
235 * \return 0 for success, error code otherwise
238 ext_alloc(Vcpu **vcpu,
239 l4_addr_t *ext_state,
240 L4::Cap<L4::Task> task = L4Re::Env::env()->task(),
241 L4::Cap<L4Re::Rm> rm = L4Re::Env::env()->rm()) throw();
244 * \brief Cast a void ponter to a class pointer.
248 * \return Pointer to Vcpu class.
250 static inline Vcpu *cast(void *x) throw()
251 { return reinterpret_cast<Vcpu *>(x); }
254 * \brief Cast an address to a class pointer.
258 * \return Pointer to Vcpu class.
260 static inline Vcpu *cast(l4_addr_t x) throw()
261 { return reinterpret_cast<Vcpu *>(x); }
264 * \brief Print the state of the vCPU.
266 void print_state(const char *prefix = "") throw()
267 { l4vcpu_print_state(this, prefix); }