31 #include "prot-domains.h"
38 #include "gdt-layout.h"
39 #include "interrupt.h"
45 dom_id_t cur_dom = DOM_ID_app;
48 void prot_domains_sysret_dispatcher(
void);
51 #define MAX_INTER_DOM_CALL_STK_SZ 4
54 static volatile dom_id_t ATTR_BSS_KERN
55 inter_dom_call_stk[MAX_INTER_DOM_CALL_STK_SZ];
58 static int ATTR_BSS_KERN inter_dom_call_stk_ptr;
62 update_eflags(dom_id_t from_id, dom_id_t to_id, interrupt_stack_t *intr_stk)
64 if((to_id == DOM_ID_app) &&
65 (DT_SEL_GET_RPL(intr_stk->cs) == PRIV_LVL_USER)) {
69 intr_stk->eflags |= EFLAGS_IF;
71 intr_stk->eflags &= ~EFLAGS_IF;
76 dispatcher_tail(dom_id_t from_id, dom_id_t to_id, interrupt_stack_t *intr_stk)
80 prot_domains_switch(from_id, to_id, intr_stk);
82 prot_domains_set_wp(
true);
84 update_eflags(from_id, to_id, intr_stk);
89 syscall_dispatcher_tail(interrupt_stack_t *intr_stk,
95 volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE *from_dkd, *to_dkd;
97 uint32_t loc_call_stk_ptr;
99 to_dkd = prot_domains_kern_data + to_id;
107 KERN_READL(tmp, to_dkd->flags);
108 if((tmp & PROT_DOMAINS_FLAG_BUSY) == PROT_DOMAINS_FLAG_BUSY) {
111 tmp |= PROT_DOMAINS_FLAG_BUSY;
112 KERN_WRITEL(to_dkd->flags, tmp);
117 intr_stk->eip = syscall_eip;
119 KERN_READL(loc_call_stk_ptr, inter_dom_call_stk_ptr);
121 KERN_READL(from_id, inter_dom_call_stk[loc_call_stk_ptr - 1]);
122 from_dkd = prot_domains_kern_data + from_id;
128 KERN_WRITEL(from_dkd->orig_ret_addr, *(uintptr_t *)intr_stk->esp);
132 *((uintptr_t *)intr_stk->esp) = (uintptr_t)prot_domains_sysret_stub;
134 if(MAX_INTER_DOM_CALL_STK_SZ <= loc_call_stk_ptr) {
137 KERN_WRITEL(inter_dom_call_stk[loc_call_stk_ptr], to_id);
140 KERN_WRITEL(inter_dom_call_stk_ptr, loc_call_stk_ptr);
142 dispatcher_tail(from_id, to_id, intr_stk);
146 prot_domains_syscall_dispatcher_impl(interrupt_stack_t *intr_stk,
148 syscalls_entrypoint_t *syscall)
151 uint32_t syscall_eip;
153 if(PROT_DOMAINS_ACTUAL_CNT <= to_id) {
159 if(!((((uintptr_t)syscalls_entrypoints) <= (uintptr_t)syscall) &&
160 (((uintptr_t)syscall) < (uintptr_t)syscalls_entrypoints_end) &&
161 (((((uintptr_t)syscall) - (uintptr_t)syscalls_entrypoints)
162 %
sizeof(syscalls_entrypoint_t)) == 0))) {
167 KERN_READL(tmp, syscall->doms);
168 if((
BIT(to_id) & tmp) == 0) {
172 KERN_READL(syscall_eip, syscall->entrypoint);
174 prot_domains_set_wp(
false);
176 syscall_dispatcher_tail(intr_stk, to_id, syscall_eip);
181 prot_domains_launch_kernel_impl(interrupt_stack_t *intr_stk)
183 KERN_WRITEL(inter_dom_call_stk[0], DOM_ID_app);
185 KERN_WRITEL(inter_dom_call_stk_ptr, 1);
187 syscall_dispatcher_tail(intr_stk, DOM_ID_kern, (uint32_t)
main);
191 prot_domains_sysret_dispatcher_impl(interrupt_stack_t *intr_stk)
193 dom_id_t from_id, to_id;
194 uint32_t loc_call_stk_ptr;
197 KERN_READL(loc_call_stk_ptr, inter_dom_call_stk_ptr);
198 if(loc_call_stk_ptr <= 1) {
202 KERN_READL(from_id, inter_dom_call_stk[loc_call_stk_ptr - 1]);
203 KERN_READL(to_id, inter_dom_call_stk[loc_call_stk_ptr - 2]);
205 KERN_READL(intr_stk->eip,
206 prot_domains_kern_data[to_id].orig_ret_addr);
208 prot_domains_set_wp(
false);
210 KERN_READL(flags, prot_domains_kern_data[from_id].flags);
211 flags &= ~PROT_DOMAINS_FLAG_BUSY;
212 KERN_WRITEL(prot_domains_kern_data[from_id].flags, flags);
214 KERN_WRITEL(inter_dom_call_stk_ptr, loc_call_stk_ptr - 1);
216 dispatcher_tail(from_id, to_id, intr_stk);
223 static volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE *
224 get_current_domain(
void)
226 uint32_t loc_call_stk_ptr;
228 KERN_READL(loc_call_stk_ptr, inter_dom_call_stk_ptr);
229 KERN_READL(
id, inter_dom_call_stk[loc_call_stk_ptr - 1]);
230 return prot_domains_kern_data + id;
240 needs_port_io(
volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE *dkd)
243 KERN_READL(dkd_flags, dkd->flags);
244 return (dkd_flags & PROT_DOMAINS_FLAG_PIO) == PROT_DOMAINS_FLAG_PIO;
254 gp_fault_handler(
volatile struct interrupt_context
context)
259 volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE *dkd = get_current_domain();
260 if (needs_port_io(dkd)) {
261 __asm__ __volatile__ (
266 if (cs_lim < context.eip) {
271 __asm__ __volatile__ (
274 :
"m"(*(uint8_t *)context.eip));
278 context.eax = (context.eax & ~0xFF) | inb((uint16_t)context.edx);
281 context.eax = inl((uint16_t)context.edx);
284 outb((uint16_t)context.edx, (uint8_t)context.eax);
287 outl((uint16_t)context.edx, context.eax);
301 syscalls_int_init(
void)
305 SET_EXCEPTION_HANDLER(13, 1, gp_fault_handler);
309 idt_set_intr_gate_desc(PROT_DOMAINS_SYSCALL_DISPATCH_INT,
310 (uint32_t)prot_domains_syscall_dispatcher,
313 idt_set_intr_gate_desc(PROT_DOMAINS_SYSRET_DISPATCH_INT,
314 (uint32_t)prot_domains_sysret_dispatcher,
#define __attribute__(nothing)
Define attribute to nothing since it isn't handled by IAR.
#define BIT(x)
Useful to reference a single bit of a byte.
static struct sicslowpan_addr_context * context
Addresses contexts for IPHC.
int main(void)
This is main...