]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libvcpu/include/vcpu
8e480b4b17b005839da361f4117cd802de73909c
[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, and before event
129    *                         delivery is enabled.
130    */
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); }
134
135   /**
136    * \brief Restore a previously saved IRQ/event state.
137    *
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.
145    */
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); }
150
151   /**
152    * \brief Wait for event.
153    *
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.
159    *
160    * Note that event delivery remains disabled after this function returns.
161    */
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); }
165
166   /**
167    * \brief Set the task of the vCPU.
168    * \param task Task to set, defaults to invalid task.
169    */
170   void task(L4::Cap<L4::Task> const task = L4::Cap<L4::Task>::Invalid) throw()
171   { user_task = task.cap(); }
172
173   /**
174    * \brief Return whether the entry reason was a page fault.
175    * return 0 if not, !=0 otherwise.
176    */
177   int is_page_fault_entry()
178   { return l4vcpu_is_page_fault_entry(this); }
179
180   /**
181    * \brief Return whether the entry reason was an IRQ/IPC message.
182    * return 0 if not, !=0 otherwise.
183    */
184   int is_irq_entry()
185   { return l4vcpu_is_irq_entry(this); }
186
187   /**
188    * \brief Return pointer to register state.
189    * \return Pointer to register state.
190    */
191   l4_vcpu_regs_t *r() throw()
192   { return &(l4_vcpu_state_t::r); }
193
194   /**
195    * \brief Return pointer to register state.
196    * \return Pointer to register state.
197    */
198   l4_vcpu_regs_t const *r() const throw()
199   { return &(l4_vcpu_state_t::r); }
200
201   /**
202    * \brief Return pointer to IPC state.
203    * \return Pointer to IPC state.
204    */
205   l4_vcpu_ipc_regs_t *i() throw()
206   { return &(l4_vcpu_state_t::i); }
207
208   /**
209    * \brief Return pointer to IPC state.
210    * \return Pointer to IPC state.
211    */
212   l4_vcpu_ipc_regs_t const *i() const throw()
213   { return &(l4_vcpu_state_t::i); }
214
215   /**
216    * \brief Set vCPU entry stack pointer.
217    * \param sp  Stack pointer address to set.
218    *
219    * \note The value is only used when entering from a user-task.
220    */
221   void entry_sp(l4_umword_t sp)
222   { l4_vcpu_state_t::entry_sp = sp; }
223
224   /**
225    * \brief Set vCPU entry instruction pointer.
226    * \param ip  Instruction pointer address to set.
227    */
228   void entry_ip(l4_umword_t ip)
229   { l4_vcpu_state_t::entry_ip = ip; }
230
231   /**
232    * \brief Allocate state area for an extended vCPU.
233    *
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.
238    *
239    * \return 0 for success, error code otherwise
240    */
241   L4_CV static int
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();
246
247   /**
248    * \brief Cast a void pointer to a class pointer.
249    *
250    * \param x Pointer.
251    *
252    * \return Pointer to Vcpu class.
253    */
254   static inline Vcpu *cast(void *x) throw()
255   { return reinterpret_cast<Vcpu *>(x); }
256
257   /**
258    * \brief Cast an address to a class pointer.
259    *
260    * \param x Pointer.
261    *
262    * \return Pointer to Vcpu class.
263    */
264   static inline Vcpu *cast(l4_addr_t x) throw()
265   { return reinterpret_cast<Vcpu *>(x); }
266
267   /**
268    * \brief Print the state of the vCPU.
269    */
270   void print_state(const char *prefix = "") throw()
271   { l4vcpu_print_state(this, prefix); }
272 };
273
274
275 }