diff options
author | Alex Auvolat <alex@adnab.me> | 2015-03-09 21:17:59 +0100 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2015-03-09 21:17:59 +0100 |
commit | 380fd19521dd5205ef3da5248899244b5b29dc27 (patch) | |
tree | 717269d68027e1b41b1e110dd4c4348259a25ee1 /src/kernel/dev | |
parent | f6acdfb863038a45709f0dc57884742c51fa6f07 (diff) | |
download | kogata-380fd19521dd5205ef3da5248899244b5b29dc27.tar.gz kogata-380fd19521dd5205ef3da5248899244b5b29dc27.zip |
Use single thread for V86 interrupts.
Diffstat (limited to 'src/kernel/dev')
-rw-r--r-- | src/kernel/dev/v86.c | 37 |
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) { |