2 * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
3 * economic rights: Technische Universität Dresden (Germany)
5 * This file is part of TUD:OS and distributed under the terms of the
6 * GNU General Public License 2.
7 * Please see the COPYING-GPL-2 file for details.
9 * As a special exception, you may use this file as part of a free software
10 * library without restriction. Specifically, if other files instantiate
11 * templates or use macros or inline functions from this file, or you compile
12 * this file and link it with other files to produce an executable, this
13 * file does not by itself cause the resulting executable to be covered by
14 * the GNU General Public License. This exception does not however
15 * invalidate any other reasons why the executable file might be covered by
16 * the GNU General Public License.
20 #include <l4/sys/vcpu.h>
25 * \defgroup api_libvcpu vCPU Support Library
26 * \brief vCPU handling functionality.
28 * This library provides convenience functionality on top of the l4sys vCPU
29 * interface to ease programming. It wraps commonly used code and abstracts
30 * architecture depends parts as far as reasonable.
34 * \brief IRQ/Event enable and disable flags.
35 * \ingroup api_libvcpu
37 typedef enum l4vcpu_irq_state_t
39 L4VCPU_IRQ_STATE_DISABLED = 0, ///< IRQ/Event delivery disabled
40 L4VCPU_IRQ_STATE_ENABLED = L4_VCPU_F_IRQ, ///< IRQ/Event delivery enabled
43 typedef l4_umword_t l4vcpu_state_t;
44 typedef void (*l4vcpu_event_hndl_t)(l4_vcpu_state_t *vcpu);
47 * \brief Return the state flags of a vCPU.
48 * \ingroup api_libvcpu
50 * \param vcpu Pointer to vCPU area.
54 l4vcpu_state(l4_vcpu_state_t const *vcpu) L4_NOTHROW;
57 * \brief Disable a vCPU for event delivery.
58 * \ingroup api_libvcpu
60 * \param vcpu Pointer to vCPU area.
64 l4vcpu_irq_disable(l4_vcpu_state_t *vcpu) L4_NOTHROW;
67 * \brief Disable a vCPU for event delivery and return previous state.
68 * \ingroup api_libvcpu
70 * \param vcpu Pointer to vCPU area.
72 * \return IRQ state before disabling IRQs.
76 l4vcpu_irq_disable_save(l4_vcpu_state_t *vcpu) L4_NOTHROW;
79 * \brief Enable a vCPU for event delivery.
80 * \ingroup api_libvcpu
82 * \param vcpu Pointer to vCPU area.
83 * \param do_event_work_cb Call-back function that is called in case an
84 * event (such as an interrupt) is pending.
88 l4vcpu_irq_enable(l4_vcpu_state_t *vcpu,
89 l4vcpu_event_hndl_t do_event_work_cb) L4_NOTHROW;
92 * \brief Restore a previously saved IRQ/event state.
93 * \ingroup api_libvcpu
95 * \param vcpu Pointer to vCPU area.
96 * \param s IRQ state to be restored.
97 * \param do_event_work_cb Call-back function that is called in case an
98 * event (such as an interrupt) is pending after
103 l4vcpu_irq_restore(l4_vcpu_state_t *vcpu, l4vcpu_irq_state_t s,
104 l4vcpu_event_hndl_t do_event_work_cb) L4_NOTHROW;
107 * \brief Halt the vCPU (sleep).
108 * \ingroup api_libvcpu
110 * \param vcpu Pointer to vCPU area.
111 * \param do_event_work_cb Call-back function that is called when the vCPU
112 * awakes and needs to handle an event/IRQ.
116 l4vcpu_halt(l4_vcpu_state_t *vcpu,
117 l4vcpu_event_hndl_t do_event_work_cb) L4_NOTHROW;
121 * \brief Print the state of a vCPU.
122 * \ingroup api_libvcpu
124 * \param vcpu Pointer to vCPU area.
125 * \param prefix A prefix for each line printed.
128 l4vcpu_print_state(l4_vcpu_state_t *vcpu, const char *prefix) L4_NOTHROW;
134 l4vcpu_print_state_arch(l4_vcpu_state_t *vcpu, const char *prefix) L4_NOTHROW;
138 * \brief Return whether the entry reason was an IRQ/IPC message.
139 * \ingroup api_libvcpu
141 * \param vcpu Pointer to vCPU area.
143 * return 0 if not, !=0 otherwise.
147 l4vcpu_is_irq_entry(l4_vcpu_state_t *vcpu) L4_NOTHROW;
150 * \brief Return whether the entry reason was a page fault.
151 * \ingroup api_libvcpu
153 * \param vcpu Pointer to vCPU area.
155 * return 0 if not, !=0 otherwise.
159 l4vcpu_is_page_fault_entry(l4_vcpu_state_t *vcpu) L4_NOTHROW;
162 /* ===================================================================== */
163 /* Implementations */
165 #include <l4/sys/ipc.h>
166 #include <l4/vcpu/vcpu_arch.h>
170 l4vcpu_state(l4_vcpu_state_t const *vcpu) L4_NOTHROW
177 l4vcpu_irq_disable(l4_vcpu_state_t *vcpu) L4_NOTHROW
179 vcpu->state &= ~L4_VCPU_F_IRQ;
185 l4vcpu_irq_disable_save(l4_vcpu_state_t *vcpu) L4_NOTHROW
187 l4vcpu_irq_state_t s = (l4vcpu_irq_state_t)l4vcpu_state(vcpu);
188 l4vcpu_irq_disable(vcpu);
194 l4vcpu_irq_enable(l4_vcpu_state_t *vcpu,
195 void (*do_event_work_cb)(l4_vcpu_state_t *vcpu)) L4_NOTHROW
199 vcpu->state |= L4_VCPU_F_IRQ;
202 if (!(vcpu->sticky_flags & L4_VCPU_SF_IRQ_PENDING))
205 l4vcpu_irq_disable(vcpu);
206 vcpu->i.tag = l4_ipc_wait(l4_utcb(), &vcpu->i.label, L4_IPC_NEVER);
207 if (!l4_msgtag_has_error(vcpu->i.tag))
208 do_event_work_cb(vcpu);
214 l4vcpu_irq_restore(l4_vcpu_state_t *vcpu, l4vcpu_irq_state_t s,
215 l4vcpu_event_hndl_t do_event_work_cb) L4_NOTHROW
217 if (s & L4_VCPU_F_IRQ)
218 l4vcpu_irq_enable(vcpu, do_event_work_cb);
223 l4vcpu_halt(l4_vcpu_state_t *vcpu,
224 l4vcpu_event_hndl_t do_event_work_cb) L4_NOTHROW
226 l4vcpu_irq_disable(vcpu);
227 vcpu->i.tag = l4_ipc_wait(l4_utcb(), &vcpu->i.label, L4_IPC_NEVER);
228 if (!l4_msgtag_has_error(vcpu->i.tag))
229 do_event_work_cb(vcpu);
230 l4vcpu_irq_enable(vcpu, do_event_work_cb);