From 2bd42fd70108797eb5e47e928c3dd934754ef162 Mon Sep 17 00:00:00 2001 From: Ivan Baravy Date: Wed, 6 May 2020 17:53:15 +0300 Subject: [PATCH] umka_shell: add i40 command to call arbitrary sysfn. --- kolibri.h | 11 +++++++++++ syscalls.h | 27 +++++++++++++++++++++++---- umka_fuse.c | 10 +++++----- umka_shell.c | 26 ++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 9 deletions(-) diff --git a/kolibri.h b/kolibri.h index b1ada80..e965b92 100644 --- a/kolibri.h +++ b/kolibri.h @@ -228,6 +228,17 @@ typedef struct { uint8_t opaque[1024-HASH_SIZE]; } hash_context; +typedef struct { + uint32_t edi; + uint32_t esi; + uint32_t ebp; + uint32_t esp; + uint32_t ebx; + uint32_t edx; + uint32_t ecx; + uint32_t eax; +} pushad_t; + void kos_init(void); void i40(void); uint32_t kos_time_to_epoch(uint32_t *time); diff --git a/syscalls.h b/syscalls.h index 186c456..b31e2f1 100644 --- a/syscalls.h +++ b/syscalls.h @@ -4,6 +4,25 @@ #include #include "kolibri.h" +static inline void umka_i40(pushad_t *regs) { + + __asm__ __inline__ __volatile__ ( + "push ebp;" + "mov ebp, %[ebp];" + "call i40;" + "pop ebp" + : "=a"(regs->eax), + "=b"(regs->ebx) + : "a"(regs->eax), + "b"(regs->ebx), + "c"(regs->ecx), + "d"(regs->edx), + "S"(regs->esi), + "D"(regs->edi), + [ebp] "Rm"(regs->ebp) + : "memory"); +} + static inline void umka_sys_draw_window(size_t x, size_t xsize, size_t y, size_t ysize, uint32_t color, int has_caption, @@ -278,7 +297,7 @@ static inline int32_t umka_sys_set_skin(const char *path) { int32_t status; __asm__ __inline__ __volatile__ ( "call i40" - : "=a" (status) + : "=a"(status) : "a"(48), "b"(8), "c"(path) @@ -290,7 +309,7 @@ static inline int umka_sys_get_font_smoothing() { int type; __asm__ __inline__ __volatile__ ( "call i40" - : "=a" (type) + : "=a"(type) : "a"(48), "b"(9) : "memory"); @@ -311,7 +330,7 @@ static inline int umka_sys_get_font_size() { uint32_t size; __asm__ __inline__ __volatile__ ( "call i40" - : "=a" (size) + : "=a"(size) : "a"(48), "b"(11) : "memory"); @@ -366,7 +385,7 @@ static inline void umka_sys_lfn(void *f7080sXarg, f7080ret_t *r, f70or80_t f70or80) { __asm__ __inline__ __volatile__ ( "call i40" - : "=a" (r->status), + : "=a"(r->status), "=b" (r->count) : "a"(f70or80), "b"(f7080sXarg) diff --git a/umka_fuse.c b/umka_fuse.c index 45c43f4..e035286 100644 --- a/umka_fuse.c +++ b/umka_fuse.c @@ -53,14 +53,14 @@ static void bdfe_to_stat(bdfe_t *kf, struct stat *st) { } static void *umka_init(struct fuse_conn_info *conn, - struct fuse_config *cfg) { + struct fuse_config *cfg) { (void) conn; cfg->kernel_cache = 1; return NULL; } static int umka_getattr(const char *path, struct stat *stbuf, - struct fuse_file_info *fi) { + struct fuse_file_info *fi) { (void) fi; int res = 0; @@ -75,8 +75,8 @@ static int umka_getattr(const char *path, struct stat *stbuf, } static int umka_readdir(const char *path, void *buf, fuse_fill_dir_t filler, - off_t offset, struct fuse_file_info *fi, - enum fuse_readdir_flags flags) { + off_t offset, struct fuse_file_info *fi, + enum fuse_readdir_flags flags) { (void) offset; // TODO (void) fi; (void) flags; @@ -106,7 +106,7 @@ static int umka_open(const char *path, struct fuse_file_info *fi) { } static int umka_read(const char *path, char *buf, size_t size, off_t offset, - struct fuse_file_info *fi) { + struct fuse_file_info *fi) { (void) fi; f7080s0arg_t fX0 = {.sf = 0, .offset = offset, .count = size, .buf = buf, .u = {.f80 = {.path_encoding = UTF8, .path = path}}}; diff --git a/umka_shell.c b/umka_shell.c index 9d180f0..ea7bb78 100644 --- a/umka_shell.c +++ b/umka_shell.c @@ -199,6 +199,31 @@ int split_args(char *s, char **argv) { return argc; } +void shell_i40(int argc, char **argv) { + const char *usage = \ + "usage: i40 [ebx [ecx [edx [esi [edi [ebp]]]]]]...\n" + " see '/kernel/docs/sysfuncs.txt' for details"; + if (argc == 1 || argc > 8) { + puts(usage); + return; + } + pushad_t regs = {0, 0, 0, 0, 0, 0, 0, 0}; + if (argv[1]) regs.eax = strtoul(argv[1], NULL, 0); + if (argv[2]) regs.ebx = strtoul(argv[2], NULL, 0); + if (argv[3]) regs.ecx = strtoul(argv[3], NULL, 0); + if (argv[4]) regs.edx = strtoul(argv[4], NULL, 0); + if (argv[5]) regs.esi = strtoul(argv[5], NULL, 0); + if (argv[6]) regs.edi = strtoul(argv[6], NULL, 0); + if (argv[7]) regs.ebp = strtoul(argv[7], NULL, 0); + COVERAGE_ON(); + umka_i40(®s); + COVERAGE_OFF(); + printf("eax = %8.8x %" PRIu32 " %" PRIi32 "\n" + "ebx = %8.8x %" PRIu32 " %" PRIi32 "\n", + regs.eax, regs.eax, (int32_t)regs.eax, + regs.ebx, regs.ebx, (int32_t)regs.ebx); +} + void shell_disk_list_partitions(disk_t *d) { for (size_t i = 0; i < d->num_partitions; i++) { printf("/%s/%d: ", d->name, i+1); @@ -1023,6 +1048,7 @@ typedef struct { } func_table_t; func_table_t funcs[] = { + { "i40", shell_i40 }, { "disk_add", shell_disk_add }, { "disk_del", shell_disk_del }, { "ls70", shell_ls70 },