]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libvcpu/include/vcpu
update
[l4.git] / l4 / pkg / libvcpu / include / vcpu
1 // vi:se ft=cpp:
2 /*
3  * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
5  *
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.
9  *
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.
18  */
19
20 #pragma once
21
22 #include <l4/re/env>
23 #include <l4/vcpu/vcpu.h>
24
25 namespace L4vcpu {
26
27 /**
28  * \brief C++ implementation of state word in the vCPU area
29  * \ingroup api_libvcpu
30  */
31 class State
32 {
33 public:
34   State() {}
35
36   /**
37    * \brief Initialize state.
38    *
39    * \param v Initial state.
40    */
41   explicit State(l4vcpu_state_t v) : _s(v) {}
42
43   /**
44    * \brief Add flags.
45    *
46    * \param bits Bits to add to the word.
47    */
48   void add(unsigned bits) throw()    { _s |= bits; }
49
50   /**
51    * \brief Clear flags.
52    *
53    * \param bits Bits to clear in the word.
54    */
55   void clear(unsigned bits) throw()  { _s &= ~bits; }
56
57   /**
58    * \brief Set flags.
59    *
60    * \param v Set the word to the value of v.
61    */
62   void set(l4vcpu_state_t v) throw() { _s = v; }
63
64 private:
65   l4vcpu_state_t _s;
66 };
67
68 /**
69  * \brief C++ implementation of the vCPU save state area
70  * \ingroup api_libvcpu
71  */
72 class Vcpu : private l4_vcpu_state_t
73 {
74 public:
75   /**
76    * \brief IRQ status type.
77    */
78   typedef l4vcpu_irq_state_t Irq_state;
79
80   /**
81    * \brief Disable the vCPU for event delivery.
82    */
83   void irq_disable() throw()
84   { l4vcpu_irq_disable(this); }
85
86   /**
87    * \brief Disable the vCPU for event delivery and return previous state.
88    * \return IRQ state before disabling IRQs.
89    */
90   Irq_state irq_disable_save() throw()
91   { return l4vcpu_irq_disable_save(this); }
92
93   /**
94    * \brief Get state word
95    * \return Pointer to state word in the vCPU
96    */
97   State *state() throw()
98   { return reinterpret_cast<State *>(&(l4_vcpu_state_t::state)); }
99
100   /**
101    * \brief Get state word
102    * \return Pointer to state word in the vCPU
103    */
104   State state() const throw()
105   { return static_cast<State>(l4_vcpu_state_t::state); }
106
107   /**
108    * \brief Get saved_state word
109    * \return Pointer to saved_state word in the vCPU
110    */
111   State *saved_state() throw()
112   { return reinterpret_cast<State *>(&(l4_vcpu_state_t::saved_state)); }
113
114   /**
115    * \brief Get saved_state word
116    * \return Pointer to saved_state word in the vCPU
117    */
118   State saved_state() const throw()
119   { return static_cast<State>(l4_vcpu_state_t::saved_state); }
120
121   /**
122    * \brief Enable the vCPU for event delivery.
123    *
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.
129    */
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); }
133
134   /**
135    * \brief Restore a previously saved IRQ/event state.
136    *
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.
143    */
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); }
148
149   /**
150    * \brief Wait for event.
151    *
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.
157    *
158    * Note that event delivery remains disabled after this function returns.
159    */
160   void wait_for_event(l4_utcb_t *utcb, l4vcpu_event_hndl_t do_event_work_cb,
161                       l4vcpu_setup_ipc_t setup_ipc) throw()
162   { l4vcpu_wait_for_event(this, utcb, do_event_work_cb, setup_ipc); }
163
164   /**
165    * \brief Set the task of the vCPU.
166    * \param task Task to set, defaults to invalid task.
167    */
168   void task(L4::Cap<L4::Task> const task = L4::Cap<L4::Task>::Invalid) throw()
169   { user_task = task.cap(); }
170
171   /**
172    * \brief Return whether the entry reason was a page fault.
173    * return 0 if not, !=0 otherwise.
174    */
175   int is_page_fault_entry()
176   { return l4vcpu_is_page_fault_entry(this); }
177
178   /**
179    * \brief Return whether the entry reason was an IRQ/IPC message.
180    * return 0 if not, !=0 otherwise.
181    */
182   int is_irq_entry()
183   { return l4vcpu_is_irq_entry(this); }
184
185   /**
186    * \brief Return pointer to register state.
187    * \return Pointer to register state.
188    */
189   l4_vcpu_regs_t *r() throw()
190   { return &(l4_vcpu_state_t::r); }
191
192   /**
193    * \brief Return pointer to register state.
194    * \return Pointer to register state.
195    */
196   l4_vcpu_regs_t const *r() const throw()
197   { return &(l4_vcpu_state_t::r); }
198
199   /**
200    * \brief Return pointer to IPC state.
201    * \return Pointer to IPC state.
202    */
203   l4_vcpu_ipc_regs_t *i() throw()
204   { return &(l4_vcpu_state_t::i); }
205
206   /**
207    * \brief Return pointer to IPC state.
208    * \return Pointer to IPC state.
209    */
210   l4_vcpu_ipc_regs_t const *i() const throw()
211   { return &(l4_vcpu_state_t::i); }
212
213   /**
214    * \brief Set vCPU entry stack pointer.
215    * \param sp  Stack pointer address to set.
216    *
217    * \note The value is only used when entering from a user-task.
218    */
219   void entry_sp(l4_umword_t sp)
220   { l4_vcpu_state_t::entry_sp = sp; }
221
222   /**
223    * \brief Set vCPU entry instruction pointer.
224    * \param ip  Instruction pointer address to set.
225    */
226   void entry_ip(l4_umword_t ip)
227   { l4_vcpu_state_t::entry_ip = ip; }
228
229   /**
230    * \brief Allocate state area for an extended vCPU.
231    *
232    * \retval vcpu      Allocated vcpu-state area.
233    * \retval ext_state Allocated extended vcpu-state area.
234    * \param  task      Task to use for allocation, defaults to own task.
235    * \param  rm        Region manager to use for allocation defaults to standard region manager.
236    *
237    * \return 0 for success, error code otherwise
238    */
239   L4_CV static int
240   ext_alloc(Vcpu **vcpu,
241             l4_addr_t *ext_state,
242             L4::Cap<L4::Task> task = L4Re::Env::env()->task(),
243             L4::Cap<L4Re::Rm> rm = L4Re::Env::env()->rm()) throw();
244
245   /**
246    * \brief Cast a void pointer to a class pointer.
247    *
248    * \param x Pointer.
249    *
250    * \return Pointer to Vcpu class.
251    */
252   static inline Vcpu *cast(void *x) throw()
253   { return reinterpret_cast<Vcpu *>(x); }
254
255   /**
256    * \brief Cast an address to a class pointer.
257    *
258    * \param x Pointer.
259    *
260    * \return Pointer to Vcpu class.
261    */
262   static inline Vcpu *cast(l4_addr_t x) throw()
263   { return reinterpret_cast<Vcpu *>(x); }
264
265   /**
266    * \brief Print the state of the vCPU.
267    */
268   void print_state(const char *prefix = "") throw()
269   { l4vcpu_print_state(this, prefix); }
270 };
271
272
273 }