From 53683cf1469b77e52f9de4563e56146aa6b501b6 Mon Sep 17 00:00:00 2001 From: Ivan Baravy Date: Wed, 18 Jan 2023 02:58:09 +0000 Subject: [PATCH] umka_os: route virtual device IRQs via IDT --- apps/readdir.asm | 15 +++++++++++++++ umka.asm | 18 ++++++++++++++++-- umka.h | 46 +++++++++++++++++++++++++++++++++++++--------- umka_os.c | 39 ++++++++++++++++++++++++++++++++++++--- umka_os.us | 3 ++- 5 files changed, 106 insertions(+), 15 deletions(-) diff --git a/apps/readdir.asm b/apps/readdir.asm index 3ec49a4..2e903a4 100644 --- a/apps/readdir.asm +++ b/apps/readdir.asm @@ -17,6 +17,19 @@ start: btr dword[esp], BSF EFLAGS.ID popfd + mcall 12, 1 + mcall 0, <100,200>, <100,100>, 0x34888888, , window_title + mcall 12, 2 + mcall 18, 19, 4, 0 +.next: + mcall 37, 0 + add eax, 0x00030003 + mov edx, eax + mcall 18, 19, 4 + mcall 5, 1 +; mov ecx, 0x1000000 +; loopnz $ + jmp .next DEBUGF 1, "abcde\n" mcall 70, fs70 DEBUGF 1, "files in dir: %d\n", ebx @@ -37,6 +50,8 @@ fs70: dd dir_name dir_name db '/hd0/1/',0 +window_title db 'readdir test',0 + i_end: dir_buf: rb 0x10000 diff --git a/umka.asm b/umka.asm index fb5dbf8..199a0b2 100644 --- a/umka.asm +++ b/umka.asm @@ -85,6 +85,7 @@ UMKA_OS = 3 UMKA_MEMORY_BYTES = 256 SHL 20 pubsym irq_serv.irq_10, 'kos_irq_serv_irq10' +pubsym idts, 'kos_idts' pubsym attach_int_handler, 'kos_attach_int_handler', 12 pubsym fs_execute, 'kos_fs_execute', 4 pubsym set_keyboard_data, 'kos_set_keyboard_data' @@ -188,6 +189,9 @@ pubsym BOOT, 'kos_boot' EFLAGS.ID = 1 SHL 21 +macro lidt x { +} + macro invlpg addr { } @@ -264,6 +268,15 @@ page_tabs equ page_tabs_pew ;macro OS_BASE [x] { ; OS_BASE equ os_base ;} +struct idt_entry + addr_lo dw ? + seg dw ? + flags dw ? + addr_hi dw ? +ends + +NUM_EXCEPTIONS = 32 + macro tss pew {} include 'const.inc' purge tss @@ -630,6 +643,8 @@ proc kos_init uses ebx esi edi ebp mov [pg_data.kernel_pages], eax shr eax, 10 mov [pg_data.kernel_tables], eax + + call build_interrupt_table call init_kernel_heap call init_malloc @@ -948,7 +963,6 @@ mtrr_validate: ;unprotect_from_terminate: ;lock_application_table: ;unlock_application_table: -;build_interrupt_table: ;sys_resize_app_memory: ;request_terminate: v86_exc_c: @@ -1073,7 +1087,7 @@ align 64 os_base: rb PAGE_SIZE window_data: rb sizeof.WDATA * 256 CDDataBuf: rb 0x1000 -idts rb IRQ_RESERVED * 8 ; IDT descriptor is 8 bytes long +idts rb (NUM_EXCEPTIONS + IRQ_RESERVED) * sizeof.idt_entry WIN_STACK rw 0x200 ; why not 0x100? WIN_POS rw 0x200 FDD_BUFF: rb 0x400 diff --git a/umka.h b/umka.h index e56a155..69d6db6 100644 --- a/umka.h +++ b/umka.h @@ -591,8 +591,19 @@ umka_mouse_move(int lbheld, int mbheld, int rbheld, int xabs, int32_t xmoving, STDCALL net_buff_t * kos_net_buff_alloc(size_t size); +struct idt_entry { + uint16_t addr_lo; + uint16_t segment; + uint16_t flags; + uint16_t addr_hi; +}; + +typedef int (*hw_int_handler_t)(void*); + +extern struct idt_entry kos_idts[]; + STDCALL void -kos_attach_int_handler(int irq, int (*handler)(void*), void *user_data); +kos_attach_int_handler(int irq, hw_int_handler_t handler, void *userdata); void kos_irq_serv_irq10(void); @@ -621,23 +632,34 @@ static inline void* kos_destroy_event(void *event, uint32_t uid) { void *ret; __asm__ __inline__ __volatile__ ( - "push ebx esi edi ebp;" + "push ebx;" + "push esi;" + "push edi;" + "push ebp;" "call _kos_destroy_event;" - "pop ebp edi esi ebx" + "pop ebp;" + "pop edi;" + "pop esi;" + "pop ebx" : "=a"(ret) : "a"(event), "b"(uid) : "memory", "cc"); return ret; - } static inline void kos_wait_event(void *event, uint32_t uid) { __asm__ __inline__ __volatile__ ( - "push ebx esi edi ebp;" + "push ebx;" + "push esi;" + "push edi;" + "push ebp;" "call _kos_wait_event;" - "pop ebp edi esi ebx" + "pop ebp;" + "pop edi;" + "pop esi;" + "pop ebx" : : "a"(event), "b"(uid) @@ -646,13 +668,19 @@ kos_wait_event(void *event, uint32_t uid) { typedef uint32_t (*wait_test_t)(void *); -static inline void* +static inline void * kos_wait_events(wait_test_t wait_test, void *wait_param) { void *res; __asm__ __inline__ __volatile__ ( - "push ebx esi edi ebp;" + "push %%ebx;" + "push %%esi;" + "push %%edi;" + "push %%ebp;" "call _kos_wait_events;" - "pop ebp edi esi ebx" + "pop %%ebp;" + "pop %%edi;" + "pop %%esi;" + "pop %%ebx" : "=a"(res) : "c"(wait_param), "d"(wait_test) diff --git a/umka_os.c b/umka_os.c index 62e4c6d..37dbdd3 100644 --- a/umka_os.c +++ b/umka_os.c @@ -42,6 +42,13 @@ struct umka_os_ctx { char history_filename[PATH_MAX]; +static int +hw_int_mouse(void *arg) { + (void)arg; + kos_set_mouse_data(0, -50, 50, 0, 0); + return 1; // our interrupt +} + struct umka_os_ctx * umka_os_init() { struct umka_os_ctx *ctx = malloc(sizeof(struct umka_os_ctx)); @@ -115,15 +122,18 @@ load_app_host(const char *fname, void *base) { return 0; } -int +/* +static int load_app(const char *fname) { int32_t result = umka_fs_execute(fname); printf("result: %" PRIi32 "\n", result); return result; } +*/ -void handle_i40(int signo, siginfo_t *info, void *context) { +static void +handle_i40(int signo, siginfo_t *info, void *context) { (void)signo; (void)info; ucontext_t *ctx = context; @@ -136,13 +146,25 @@ void handle_i40(int signo, siginfo_t *info, void *context) { umka_i40((pushad_t*)(ctx->uc_mcontext.__gregs + REG_EDI)); } -void handle_irq_net(int signo, siginfo_t *info, void *context) { +static void +handle_irq_net(int signo, siginfo_t *info, void *context) { (void)signo; (void)info; (void)context; kos_irq_serv_irq10(); } +static void +hw_int(int signo, siginfo_t *info, void *context) { + (void)signo; + (void)context; + struct idt_entry *e = kos_idts + info->si_value.sival_int + 0x20; + void (*handler)(void) = (void(*)(void)) (((uintptr_t)e->addr_hi << 16) + + e->addr_lo); + handler(); + umka_sti(); +} + int main(int argc, char *argv[]) { (void)argc; @@ -214,6 +236,15 @@ main(int argc, char *argv[]) { return 1; } + sa.sa_sigaction = hw_int; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + + if (sigaction(SIGUSR2, &sa, NULL) == -1) { + fprintf(stderr, "Can't install SIGUSR2 handler!\n"); + return 1; + } + struct app_hdr *app = mmap(KOS_APP_BASE, 16*0x100000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (app == MAP_FAILED) { @@ -274,6 +305,8 @@ main(int argc, char *argv[]) { } */ + kos_attach_int_handler(14, hw_int_mouse, NULL); + // thread_start(0, monitor, THREAD_STACK_SIZE); kos_thread_t start = (kos_thread_t)(KOS_APP_BASE + app->menuet.start); thread_start(0, start, THREAD_STACK_SIZE); diff --git a/umka_os.us b/umka_os.us index 0ed1c8e..4fbb5d0 100644 --- a/umka_os.us +++ b/umka_os.us @@ -1,3 +1,4 @@ -umka_init umka_os +umka_init os ramdisk_init ../img/kolibri.raw +set_skin /sys/DEFAULT.SKN disk_add ../img/xfs_samehash_s05k.raw hd0 -c 0