diff --git a/README b/README index bdeb8cd..db6738c 100644 --- a/README +++ b/README @@ -103,6 +103,11 @@ Testing Troubleshooting --------------- +# Build + + Install toolchain for the 32-bit target, e.g. gcc-multilib, lib32-glibc, + 32-bit and develop packages of libfuse and libsdl2, fasm. + # umka_os To create tap devices. diff --git a/TODO b/TODO index d03bff9..4d23595 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,10 @@ +make mkfs.* use config files (-c for mkfs.xfs) +export and initialize mouse_delay and mouse_speed_factor (test and cover func mouse_acceleration) lsstat to decrease tests size -separate dirs for each image and test +separate dirs for each image +include umka_os to tests +tests with writing to block devices (read-only base image + discardable image for writing) library loader -custom test runner -make mkfs.xfs use config file via -c option -writing tests -compare with reference XFS implementation -stressing via ref impl +validate against the reference XFS implementation +stressing via ref impl (how?) multithreaded: kofu one.t two.t diff --git a/makefile b/makefile index 8839124..abae03c 100644 --- a/makefile +++ b/makefile @@ -84,7 +84,7 @@ umka_os: umka_os.o umka.o shell.o deps/lodepng/lodepng.o vdisk.o vdisk/raw.o \ vnet/file.o vnet/null.o trace.o trace_lbr.o $(HOST)/pci.o \ $(HOST)/thread.o umkaio.o umkart.o deps/isocline/src/isocline.o \ deps/optparse/optparse.o - $(CC) $(LDFLAGS_32) `sdl2-config --libs` $^ -o $@ -T umka.ld + $(CC) $(LDFLAGS_32) $^ `sdl2-config --libs` -o $@ -T umka.ld umka_gen_devices_dat: umka_gen_devices_dat.o umka.o $(HOST)/pci.o \ $(HOST)/thread.o umkart.o diff --git a/shell.c b/shell.c index 2d8130a..73ae448 100644 --- a/shell.c +++ b/shell.c @@ -51,124 +51,12 @@ #define SHELL_CMD_BUF_LEN 0x10 -enum { - UMKA_CMD_NONE, - UMKA_CMD_SET_MOUSE_DATA, - UMKA_CMD_WAIT_FOR_IDLE, - UMKA_CMD_WAIT_FOR_OS_IDLE, - UMKA_CMD_WAIT_FOR_WINDOW, - UMKA_CMD_SYS_CSLEEP, - UMKA_CMD_SYS_PROCESS_INFO, - UMKA_CMD_SYS_GET_MOUSE_POS_SCREEN, - UMKA_CMD_SYS_LFN, -}; - enum { SHELL_CMD_STATUS_EMPTY, SHELL_CMD_STATUS_READY, SHELL_CMD_STATUS_DONE, }; -struct cmd_set_mouse_data_arg { - uint32_t btn_state; - int32_t xmoving; - int32_t ymoving; - int32_t vscroll; - int32_t hscroll; -}; - -struct cmd_set_mouse_data_ret { - char stub; -}; - -struct cmd_set_mouse_data { - struct cmd_set_mouse_data_arg arg; - struct cmd_set_mouse_data_ret ret; -}; - -struct cmd_sys_lfn_arg { - f70or80_t f70or80; - f7080s1arg_t *bufptr; - f7080ret_t *r; -}; - -struct cmd_sys_lfn_ret { - f7080ret_t status; -}; - -struct cmd_sys_lfn { - struct cmd_sys_lfn_arg arg; - struct cmd_sys_lfn_ret ret; -}; - -struct cmd_sys_process_info_arg { - int32_t pid; - void *param; -}; - -struct cmd_sys_process_info_ret { - char stub; -}; - -struct cmd_sys_process_info { - struct cmd_sys_process_info_arg arg; - struct cmd_sys_process_info_ret ret; -}; - -struct cmd_sys_get_mouse_pos_screen_arg { - char stub; -}; - -struct cmd_sys_get_mouse_pos_screen_ret { - struct point16s pos; -}; - -struct cmd_sys_get_mouse_pos_screen { - struct cmd_sys_get_mouse_pos_screen_arg arg; - struct cmd_sys_get_mouse_pos_screen_ret ret; -}; - -struct cmd_sys_csleep_arg { - uint32_t csec; -}; - -struct cmd_sys_csleep_ret { - char stub; -}; - -struct cmd_sys_csleep { - struct cmd_sys_csleep_arg arg; - struct cmd_sys_csleep_ret ret; -}; - -struct cmd_wait_for_window_arg { - char *wnd_title; -}; - -struct cmd_wait_for_window_ret { - char stub; -}; - -struct cmd_wait_for_window { - struct cmd_wait_for_window_arg arg; - struct cmd_wait_for_window_ret ret; -}; - -struct umka_cmd { - atomic_int status; - uint32_t type; - union { - // internal funcs - struct cmd_set_mouse_data set_mouse_data; - struct cmd_wait_for_window wait_for_window; - // syscalls - struct cmd_sys_csleep sys_csleep; - struct cmd_sys_process_info sys_process_info; - struct cmd_sys_lfn sys_lfn; - struct cmd_sys_get_mouse_pos_screen sys_get_mouse_pos_screen; - }; -}; - struct umka_cmd umka_cmd_buf[SHELL_CMD_BUF_LEN]; char prompt_line[PATH_MAX]; @@ -181,21 +69,6 @@ typedef struct { void (*func) (struct shell_ctx *, int, char **); } func_table_t; -void -shell_run_cmd_sync(struct shell_ctx *ctx); - -static void -shell_run_cmd(struct shell_ctx *ctx) { - struct umka_cmd *cmd = umka_cmd_buf; - atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY, - memory_order_release); - if (atomic_load_explicit(ctx->running, memory_order_acquire) == UMKA_RUNNING_YES) { - pthread_cond_wait(&ctx->cmd_done, &ctx->cmd_mutex); - } else { - shell_run_cmd_sync(ctx); - } -} - static uint32_t shell_run_cmd_wait_test(void /* struct appdata * with wait_param is in ebx */) { appdata_t *app; @@ -204,6 +77,9 @@ shell_run_cmd_wait_test(void /* struct appdata * with wait_param is in ebx */) { return (uint32_t)(atomic_load_explicit(&cmd->status, memory_order_acquire) == SHELL_CMD_STATUS_READY); } +static void +shell_run_cmd_sync(struct shell_ctx *ctx); + static void thread_cmd_runner(void *arg) { umka_sti(); @@ -1387,17 +1263,16 @@ cmd_mouse_move(struct shell_ctx *ctx, int argc, char **argv) { } uint32_t btn_state = lbheld + (rbheld << 1) + (mbheld << 2) + (yabs << 30) + (xabs << 31); - struct umka_cmd *cmd = umka_cmd_buf; - struct cmd_set_mouse_data_arg *c = &cmd->set_mouse_data.arg; + struct umka_cmd *cmd = shell_get_cmd(ctx); cmd->type = UMKA_CMD_SET_MOUSE_DATA; + struct cmd_set_mouse_data_arg *c = &cmd->set_mouse_data.arg; c->btn_state = btn_state; c->xmoving = xmoving; c->ymoving = ymoving; c->vscroll = vscroll; c->hscroll = hscroll; shell_run_cmd(ctx); - atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY, - memory_order_release); + shell_clear_cmd(cmd); } static void @@ -4330,7 +4205,7 @@ func_table_t cmd_cmds[] = { { NULL, NULL }, }; -void +static void shell_run_cmd_sync(struct shell_ctx *ctx) { struct umka_cmd *cmd = umka_cmd_buf; switch (cmd->type) { @@ -4384,6 +4259,30 @@ shell_run_cmd_sync(struct shell_ctx *ctx) { pthread_cond_signal(&ctx->cmd_done); } +struct umka_cmd * +shell_get_cmd(struct shell_ctx *shell) { + (void)shell; + return umka_cmd_buf; +} + +void +shell_run_cmd(struct shell_ctx *ctx) { + struct umka_cmd *cmd = umka_cmd_buf; + atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY, + memory_order_release); + if (atomic_load_explicit(ctx->running, memory_order_acquire) == UMKA_RUNNING_YES) { + pthread_cond_wait(&ctx->cmd_done, &ctx->cmd_mutex); + } else { + shell_run_cmd_sync(ctx); + } +} + +void +shell_clear_cmd(struct umka_cmd *cmd) { + atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY, + memory_order_release); +} + static void cmd_help(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ diff --git a/shell.h b/shell.h index ca02e26..e312717 100644 --- a/shell.h +++ b/shell.h @@ -59,7 +59,125 @@ shell_close(struct shell_ctx *shell); void * run_test(struct shell_ctx *ctx); +enum { + UMKA_CMD_NONE, + UMKA_CMD_SET_MOUSE_DATA, + UMKA_CMD_WAIT_FOR_IDLE, + UMKA_CMD_WAIT_FOR_OS_IDLE, + UMKA_CMD_WAIT_FOR_WINDOW, + UMKA_CMD_SYS_CSLEEP, + UMKA_CMD_SYS_PROCESS_INFO, + UMKA_CMD_SYS_GET_MOUSE_POS_SCREEN, + UMKA_CMD_SYS_LFN, +}; + +struct cmd_set_mouse_data_arg { + uint32_t btn_state; + int32_t xmoving; + int32_t ymoving; + int32_t vscroll; + int32_t hscroll; +}; + +struct cmd_set_mouse_data_ret { + char stub; +}; + +struct cmd_set_mouse_data { + struct cmd_set_mouse_data_arg arg; + struct cmd_set_mouse_data_ret ret; +}; + +struct cmd_sys_lfn_arg { + f70or80_t f70or80; + f7080s1arg_t *bufptr; + f7080ret_t *r; +}; + +struct cmd_sys_lfn_ret { + f7080ret_t status; +}; + +struct cmd_sys_lfn { + struct cmd_sys_lfn_arg arg; + struct cmd_sys_lfn_ret ret; +}; + +struct cmd_sys_process_info_arg { + int32_t pid; + void *param; +}; + +struct cmd_sys_process_info_ret { + char stub; +}; + +struct cmd_sys_process_info { + struct cmd_sys_process_info_arg arg; + struct cmd_sys_process_info_ret ret; +}; + +struct cmd_sys_get_mouse_pos_screen_arg { + char stub; +}; + +struct cmd_sys_get_mouse_pos_screen_ret { + struct point16s pos; +}; + +struct cmd_sys_get_mouse_pos_screen { + struct cmd_sys_get_mouse_pos_screen_arg arg; + struct cmd_sys_get_mouse_pos_screen_ret ret; +}; + +struct cmd_sys_csleep_arg { + uint32_t csec; +}; + +struct cmd_sys_csleep_ret { + char stub; +}; + +struct cmd_sys_csleep { + struct cmd_sys_csleep_arg arg; + struct cmd_sys_csleep_ret ret; +}; + +struct cmd_wait_for_window_arg { + char *wnd_title; +}; + +struct cmd_wait_for_window_ret { + char stub; +}; + +struct cmd_wait_for_window { + struct cmd_wait_for_window_arg arg; + struct cmd_wait_for_window_ret ret; +}; + +struct umka_cmd { + atomic_int status; + uint32_t type; + union { + // internal funcs + struct cmd_set_mouse_data set_mouse_data; + struct cmd_wait_for_window wait_for_window; + // syscalls + struct cmd_sys_csleep sys_csleep; + struct cmd_sys_process_info sys_process_info; + struct cmd_sys_lfn sys_lfn; + struct cmd_sys_get_mouse_pos_screen sys_get_mouse_pos_screen; + }; +}; + +struct umka_cmd * +shell_get_cmd(struct shell_ctx *shell); + void -umka_run_cmd_sync(struct shell_ctx *ctx); +shell_run_cmd(struct shell_ctx *ctx); + +void +shell_clear_cmd(struct umka_cmd *cmd); #endif // SHELL_H_INCLUDED diff --git a/umka_os.c b/umka_os.c index 72a7c26..f38a315 100644 --- a/umka_os.c +++ b/umka_os.c @@ -154,6 +154,17 @@ hw_int(int signo) { umka_sti(); } +void (*copy_display)(void *); + +static void +update_display(SDL_Surface *window_surface, SDL_Window *window) { + SDL_LockSurface(window_surface); + copy_display(window_surface->pixels); + SDL_UnlockSurface(window_surface); + SDL_UpdateWindowSurface(window); + return; +} + static void * umka_display(void *arg) { (void)arg; @@ -164,8 +175,8 @@ umka_display(void *arg) { } char title[64]; - sprintf(title, "umka0 %ux%u %ubpp", kos_display.width, kos_display.height, - kos_display.bits_per_pixel); + sprintf(title, "umka %ux%u %ubpp, press Ctrl-Alt-g to (un)grab input", + kos_display.width, kos_display.height, kos_display.bits_per_pixel); SDL_Window *window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, @@ -187,8 +198,6 @@ umka_display(void *arg) { return NULL; } - void (*copy_display)(void *) = NULL; - switch (window_surface->format->format) { case SDL_PIXELFORMAT_RGB888: copy_display = copy_display_to_rgb888; @@ -199,12 +208,109 @@ umka_display(void *arg) { break; } + bool input_grabbed = false; + + SDL_Event event; while (1) { - SDL_LockSurface(window_surface); - copy_display(window_surface->pixels); - SDL_UnlockSurface(window_surface); - SDL_UpdateWindowSurface(window); - sleep(1); + struct umka_cmd *cmd; + struct cmd_set_mouse_data_arg *c; + uint32_t btn_state; + update_display(window_surface, window); + if (SDL_WaitEventTimeout(&event, 1000 /* ms */)) { + switch (event.type) { + case SDL_QUIT: + break; + case SDL_WINDOWEVENT: + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + if (!input_grabbed) { + break; + } + cmd = shell_get_cmd(os->shell); + cmd->type = UMKA_CMD_SET_MOUSE_DATA; + c = &cmd->set_mouse_data.arg; + c->btn_state = event.button.state; + c->xmoving = 0; + c->ymoving = 0; + c->vscroll = 0; + c->hscroll = 0; + shell_run_cmd(os->shell); + shell_clear_cmd(cmd); + break; + case SDL_MOUSEMOTION: + if (!input_grabbed) { + break; + } + cmd = shell_get_cmd(os->shell); + cmd->type = UMKA_CMD_SET_MOUSE_DATA; + c = &cmd->set_mouse_data.arg; + c->btn_state = 0; + c->xmoving = event.motion.xrel; + c->ymoving = -event.motion.yrel; + c->vscroll = 0; + c->hscroll = 0; + shell_run_cmd(os->shell); + shell_clear_cmd(cmd); + break; + case SDL_MOUSEWHEEL: + if (!input_grabbed) { + break; + } + btn_state = SDL_GetMouseState(NULL, NULL); + cmd = shell_get_cmd(os->shell); + cmd->type = UMKA_CMD_SET_MOUSE_DATA; + c = &cmd->set_mouse_data.arg; + c->btn_state = 0; + if ((btn_state & SDL_BUTTON_LMASK)) { + c->btn_state |= 0x01; + } + /* + if ((btn_state & SDL_BUTTON_RMASK)) { + c->btn_state |= 0x02; + } + if ((btn_state & SDL_BUTTON_MMASK)) { + c->btn_state |= 0x04; + } + */ + c->xmoving = 0; + c->ymoving = 0; + c->vscroll = event.wheel.y; + c->hscroll = event.wheel.x; + shell_run_cmd(os->shell); + shell_clear_cmd(cmd); + break; + case SDL_KEYDOWN: + if ((event.key.keysym.scancode == SDL_SCANCODE_G) + && (event.key.keysym.mod & KMOD_CTRL) + && (event.key.keysym.mod & KMOD_ALT)) { + input_grabbed = !input_grabbed; + SDL_SetWindowMouseGrab(window, input_grabbed); + SDL_SetWindowKeyboardGrab(window, input_grabbed); + SDL_SetRelativeMouseMode(input_grabbed); + } + if (!input_grabbed) { + break; + } + break; + case SDL_KEYUP: + if (!input_grabbed) { + break; + } + break; + case SDL_TEXTINPUT: + if (!input_grabbed) { + break; + } + break; + default: + fprintf(stderr, "[sdl] unknown event type: 0x%x\n", event.type); + update_display(window_surface, window); + } + } else { + update_display(window_surface, window); + } +// sleep(1); } return NULL; }