aboutsummaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/dev/v86.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/src/kernel/dev/v86.c b/src/kernel/dev/v86.c
index 9498eaf..68bc375 100644
--- a/src/kernel/dev/v86.c
+++ b/src/kernel/dev/v86.c
@@ -19,11 +19,14 @@ void* v86_alloc_addr;
bool v86_retval;
thread_t *v86_caller_thread = 0;
+thread_t *v86_thread = 0;
+uint32_t v86_int_no;
+
pagedir_t *v86_prev_pagedir = 0;
// ---- Setup code
-void v86_run_bios_int(void*);
+void v86_thread_main(void*);
void v86_ex_handler(registers_t *regs);
void v86_pf_handler(void*, registers_t *regs, void* addr);
void v86_asm_enter_v86(v86_regs_t*);
@@ -47,6 +50,17 @@ bool v86_begin_session() {
pd_map_page(0, 0, true);
}
+ if (v86_thread == 0) {
+ v86_thread = new_thread(v86_thread_main, (void*)1);
+ if (v86_thread == 0) return false;
+
+ v86_thread->user_ex_handler = v86_ex_handler;
+
+ v86_retval = false;
+ start_thread(v86_thread);
+ while (!v86_retval) yield();
+ }
+
v86_alloc_addr = (void*)V86_ALLOC_ADDR;
memset(&v86_regs, 0, sizeof(v86_regs));
@@ -73,24 +87,19 @@ void* v86_alloc(size_t size) {
bool v86_bios_int(uint8_t int_no) {
v86_caller_thread = current_thread;
- uint32_t int_no_32 = int_no;
-
- thread_t *v86t = new_thread(v86_run_bios_int, (void*)int_no_32);
- v86t->user_ex_handler = v86_ex_handler;
+ v86_int_no = int_no;
int st = enter_critical(CL_NOSWITCH);
- start_thread(v86t);
+ resume_on(v86_thread);
wait_on(current_thread);
exit_critical(st);
return v86_retval;
}
-void v86_run_bios_int(void* x) {
+void v86_run_bios_int(uint32_t int_no) {
switch_pagedir(v86_pagedir);
- uint32_t int_no = (uint32_t)x;
-
uint16_t *ivt = (uint16_t*)0;
v86_regs.cs = ivt[2 * int_no + 1];
@@ -103,11 +112,19 @@ void v86_run_bios_int(void* x) {
v86_asm_enter_v86(&v86_regs);
}
+void v86_thread_main(void* z) {
+ if (z) v86_retval = true;
+ wait_on(current_thread);
+
+ v86_run_bios_int(v86_int_no);
+}
+
void v86_exit_thread(bool status) {
v86_retval = status;
resume_on(v86_caller_thread);
- exit();
+
+ v86_thread_main(0);
}
bool v86_gpf_handler(registers_t *regs) {