From 75ad9af5238a24e660bc023c1d587621baff040d Mon Sep 17 00:00:00 2001 From: Yann MAGNIN Date: Sun, 5 Jan 2020 10:35:44 +0100 Subject: [PATCH] Add kernel for each process --- $ | 41 ------ include/kernel/keybios.h | 158 ------------------------ include/kernel/opcode.h | 24 ---- include/kernel/process.h | 15 ++- src/kernel/bootstrap/start.c | 33 +---- src/kernel/hardware/ubc/handler.c | 1 - src/kernel/hardware/vbr/exception_pre.s | 77 ++++++++---- src/kernel/process/alloc.c | 2 +- src/kernel/process/create.c | 13 +- src/kernel/process/switch.c | 4 +- src/kernel/syscall/syscall_pre.s | 14 +++ 11 files changed, 98 insertions(+), 284 deletions(-) delete mode 100644 $ delete mode 100644 include/kernel/keybios.h delete mode 100644 include/kernel/opcode.h diff --git a/$ b/$ deleted file mode 100644 index c1b5fe1..0000000 --- a/$ +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include - -///TODO add flags and mode parameter. -FILE *vfs_file_open(char const *path) -{ - struct dentry *dentry; - FILE *new_file; - - // Get target inode. - dentry = vfs_dentry_resolve(path); - if (dentry == NULL) - { - printk(KERN_DEBUG, "vfs open: inode fault !\n"); - return (NULL); - } - - // Check directory. - // TODO return value ? - // TODO device handling ? - // FIXME: device error !! - //if (inode->type & VFS_INODE_TYPE_PARENT){ - // printk(KERN_DEBUG, "vfs open: file type error !\n"); - // return (NULL); - //} - - // Alloc new FILE. - new_file = pm_heap_alloc(sizeof(FILE)); - if (new_file == NULL) - { - printk(KERN_DEBUG, "vfs open: file alloc error !\n"); - return (NULL); - } - - // Fill new file. - new_file->private = dentry->inode; - new_file->permisssion = 0; //<-- TODO - new_file->cursor = 0; - return (new_file); -} diff --git a/include/kernel/keybios.h b/include/kernel/keybios.h deleted file mode 100644 index 24fe30e..0000000 --- a/include/kernel/keybios.h +++ /dev/null @@ -1,158 +0,0 @@ -/*****************************************************************/ -/* */ -/* CASIO fx-9860G SDK Library */ -/* */ -/* File name : keybios.h */ -/* */ -/* Copyright (c) 2006 CASIO COMPUTER CO., LTD. */ -/* */ -/*****************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __KEYBIOS_H__ -#define __KEYBIOS_H__ - - -// Defines - -// Character codes -#define KEY_CHAR_0 0x30 -#define KEY_CHAR_1 0x31 -#define KEY_CHAR_2 0x32 -#define KEY_CHAR_3 0x33 -#define KEY_CHAR_4 0x34 -#define KEY_CHAR_5 0x35 -#define KEY_CHAR_6 0x36 -#define KEY_CHAR_7 0x37 -#define KEY_CHAR_8 0x38 -#define KEY_CHAR_9 0x39 -#define KEY_CHAR_DP 0x2e -#define KEY_CHAR_EXP 0x0f -#define KEY_CHAR_PMINUS 0x87 -#define KEY_CHAR_PLUS 0x89 -#define KEY_CHAR_MINUS 0x99 -#define KEY_CHAR_MULT 0xa9 -#define KEY_CHAR_DIV 0xb9 -#define KEY_CHAR_FRAC 0xbb -#define KEY_CHAR_LPAR 0x28 -#define KEY_CHAR_RPAR 0x29 -#define KEY_CHAR_COMMA 0x2c -#define KEY_CHAR_STORE 0x0e -#define KEY_CHAR_LOG 0x95 -#define KEY_CHAR_LN 0x85 -#define KEY_CHAR_SIN 0x81 -#define KEY_CHAR_COS 0x82 -#define KEY_CHAR_TAN 0x83 -#define KEY_CHAR_SQUARE 0x8b -#define KEY_CHAR_POW 0xa8 -#define KEY_CHAR_IMGNRY 0x7f50 -#define KEY_CHAR_LIST 0x7f51 -#define KEY_CHAR_MAT 0x7f40 -#define KEY_CHAR_EQUAL 0x3d -#define KEY_CHAR_PI 0xd0 -#define KEY_CHAR_ANS 0xc0 -#define KEY_CHAR_LBRCKT 0x5b -#define KEY_CHAR_RBRCKT 0x5d -#define KEY_CHAR_LBRACE 0x7b -#define KEY_CHAR_RBRACE 0x7d -#define KEY_CHAR_CR 0x0d -#define KEY_CHAR_CUBEROOT 0x96 -#define KEY_CHAR_RECIP 0x9b -#define KEY_CHAR_ANGLE 0x7f54 -#define KEY_CHAR_EXPN10 0xb5 -#define KEY_CHAR_EXPN 0xa5 -#define KEY_CHAR_ASIN 0x91 -#define KEY_CHAR_ACOS 0x92 -#define KEY_CHAR_ATAN 0x93 -#define KEY_CHAR_ROOT 0x86 -#define KEY_CHAR_POWROOT 0xb8 -#define KEY_CHAR_SPACE 0x20 -#define KEY_CHAR_DQUATE 0x22 -#define KEY_CHAR_VALR 0xcd -#define KEY_CHAR_THETA 0xce -#define KEY_CHAR_A 0x41 -#define KEY_CHAR_B 0x42 -#define KEY_CHAR_C 0x43 -#define KEY_CHAR_D 0x44 -#define KEY_CHAR_E 0x45 -#define KEY_CHAR_F 0x46 -#define KEY_CHAR_G 0x47 -#define KEY_CHAR_H 0x48 -#define KEY_CHAR_I 0x49 -#define KEY_CHAR_J 0x4a -#define KEY_CHAR_K 0x4b -#define KEY_CHAR_L 0x4c -#define KEY_CHAR_M 0x4d -#define KEY_CHAR_N 0x4e -#define KEY_CHAR_O 0x4f -#define KEY_CHAR_P 0x50 -#define KEY_CHAR_Q 0x51 -#define KEY_CHAR_R 0x52 -#define KEY_CHAR_S 0x53 -#define KEY_CHAR_T 0x54 -#define KEY_CHAR_U 0x55 -#define KEY_CHAR_V 0x56 -#define KEY_CHAR_W 0x57 -#define KEY_CHAR_X 0x58 -#define KEY_CHAR_Y 0x59 -#define KEY_CHAR_Z 0x5a - - -// Control codes -#define KEY_CTRL_NOP 0 -#define KEY_CTRL_EXE 30004 //0x7534 -#define KEY_CTRL_DEL 30025 //0x7549 -#define KEY_CTRL_AC 30015 //0x753f -#define KEY_CTRL_FD 30046 //0x755e -#define KEY_CTRL_XTT 30001 //0x7531 -#define KEY_CTRL_EXIT 30002 //0x7532 -#define KEY_CTRL_SHIFT 30006 //0x7536 -#define KEY_CTRL_ALPHA 30007 //0x7537 -#define KEY_CTRL_OPTN 30008 //0x7538 -#define KEY_CTRL_VARS 30016 //0x7540 -#define KEY_CTRL_UP 30018 //0x7542 -#define KEY_CTRL_DOWN 30023 //0x7547 -#define KEY_CTRL_LEFT 30020 //0x7544 -#define KEY_CTRL_RIGHT 30021 //0x7545 -#define KEY_CTRL_F1 30009 -#define KEY_CTRL_F2 30010 -#define KEY_CTRL_F3 30011 -#define KEY_CTRL_F4 30012 -#define KEY_CTRL_F5 30013 -#define KEY_CTRL_F6 30014 -#define KEY_CTRL_CATALOG 30100 -#define KEY_CTRL_CAPTURE 30055 -#define KEY_CTRL_CLIP 30050 -#define KEY_CTRL_PASTE 30036 -#define KEY_CTRL_INS 30033 -#define KEY_CTRL_MIXEDFRAC 30054 -#define KEY_CTRL_FRACCNVRT 30026 -#define KEY_CTRL_QUIT 30029 -#define KEY_CTRL_PRGM 30028 -#define KEY_CTRL_SETUP 30037 -#define KEY_CTRL_PAGEUP 30052 -#define KEY_CTRL_PAGEDOWN 30053 -#define KEY_CTRL_MENU 30003 //0x7533 -#define KEY_CTRL_RESERVE1 30060 -#define KEY_CTRL_RESERVE2 30061 -#define KEY_CTRL_RESERVE3 30062 - - -// in Bkey_GetKeyWait function -#define KEYWAIT_HALTON_TIMEROFF 0 -#define KEYWAIT_HALTOFF_TIMEROFF 1 -#define KEYWAIT_HALTON_TIMERON 2 - -#define KEYREP_NOEVENT 0 -#define KEYREP_KEYEVENT 1 -#define KEYREP_TIMEREVENT 2 - - -#endif - -#ifdef __cplusplus -} -#endif diff --git a/include/kernel/opcode.h b/include/kernel/opcode.h deleted file mode 100644 index cad69ef..0000000 --- a/include/kernel/opcode.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __OPCODE_H__ -# define __OPCODE_H__ - -#include -#include - -// Define the number max of arguments -// for intrustions. -#define ARGUMENTS_MAX 3 - -/* opcode - instruction data part. */ -struct opcode_s -{ - const char *name; - uint16_t mask; - uint16_t code; - uint16_t arg_mask[ARGUMENTS_MAX]; - void (*special)(char *buffer, uint16_t *area); -}; - -// Opcode list. -extern const struct opcode_s opcode_list[]; - -#endif /*__OPCODE_H__*/ diff --git a/include/kernel/process.h b/include/kernel/process.h index 309c4ee..ae5dd6c 100644 --- a/include/kernel/process.h +++ b/include/kernel/process.h @@ -6,16 +6,23 @@ #include #include -#define PROCESS_STACK_SIZE (2048) -#define PROCESS_NAME_LENGHT (16) -#define PROCESS_MAX (3) +#define PROCESS_USER_STACK_SIZE (2048) +#define PROCESS_KERNEL_STACK_SIZE (512) +#define PROCESS_NAME_LENGHT (16) +#define PROCESS_MAX (3) -#define PROC_IDLE (0) +#define PROC_IDLE (0) // define process struct. //TODO: signal ! typedef struct process_s { + // Used when interrupt or exception occur + struct { + uint32_t kernel; + uint32_t user; + } stack; + // Process name. char name[PROCESS_NAME_LENGHT]; diff --git a/src/kernel/bootstrap/start.c b/src/kernel/bootstrap/start.c index 59536cc..3005fb0 100644 --- a/src/kernel/bootstrap/start.c +++ b/src/kernel/bootstrap/start.c @@ -85,27 +85,6 @@ static void section_execute(void *bsection, void *esection) } } -//TEST -void vfs_test(struct dentry *node, int level) -{ - // Check error - if (node == NULL) - return; - - // Space test - for (int i = 0 ; i < level ; i++) - tty_write(" ", 1); - - // display name - tty_write(node->name, strlen(node->name)); - tty_write("\n", 1); - - // Try child and sibling - vfs_test(vfs_dentry_find_first_child(node), level + 1); - vfs_test(vfs_dentry_find_next_sibling(node), level); -} - - /* start() - Kernel entry point */ __attribute__((section(".pretext"))) int start(void) @@ -163,15 +142,9 @@ int start(void) vfs_mount(NULL, NULL, "gladfs", VFS_MOUNT_ROOT, NULL); vfs_mkdir("/dev", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); vfs_mkdir("/mnt", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - vfs_mkdir("/mnt/smemfs", S_IRUSR | S_IRGRP | S_IROTH); + vfs_mkdir("/mnt/smemfs", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); vfs_mount(NULL, "/mnt/smemfs", "smemfs", /*MS_RDONLY*/0, NULL); -// extern struct dentry *vfs_root_node; -// tty_open(); -// vfs_test(vfs_root_node->child, 0); -// tty_write("FINI !", 6); -// while (1); - // Create first process: Vhex. pid_t vhex_pid = process_create("Vhex"); process_t *vhex_process = process_get(vhex_pid); @@ -206,6 +179,10 @@ int start(void) } } + // Set the first process + extern process_t *process_current; + process_current = vhex_process; + // Switch to first process. kernel_switch(&vhex_process->context); diff --git a/src/kernel/hardware/ubc/handler.c b/src/kernel/hardware/ubc/handler.c index 87eabf4..c5b74ad 100644 --- a/src/kernel/hardware/ubc/handler.c +++ b/src/kernel/hardware/ubc/handler.c @@ -1,7 +1,6 @@ #include #include #include -#include #include #include diff --git a/src/kernel/hardware/vbr/exception_pre.s b/src/kernel/hardware/vbr/exception_pre.s index 860065e..2a819a6 100644 --- a/src/kernel/hardware/vbr/exception_pre.s +++ b/src/kernel/hardware/vbr/exception_pre.s @@ -4,49 +4,80 @@ .type _exception_handler_pre, @function .extern _exception_handler +.extern _current_process .extern _syscall_pre .align 2 _exception_handler_pre: + ! Due to TRAPA syscall API we should + ! switch stack to avoid variodic argument + ! corruption. + mov.l .process_current, r2 ! get current_process address + mov.l @r2, r2 ! get current process adrress + tst r2, r2 ! if current process == NULL... + bt kernel_stack_switch_end ! ...if yes, jump at + mov.l r15, @(4, r2) ! save current stack (user) + mov.l @r2, r15 ! set kernel stack + +kernel_stack_switch_end: ! Save critical regsiter. - stc.l spc, @-r15 ! save SPC register. - stc.l ssr, @-r15 ! save SSR register. - sts.l pr, @-r15 ! save pr register. + stc.l spc, @-r15 ! save SPC register. + stc.l ssr, @-r15 ! save SSR register. + sts.l pr, @-r15 ! save pr register. + mov.l r8, @-r15 ! save r8 register. + + ! Save current process address + mov r2, r8 ! save current process address ! Check syscall (trapa) - mov.l .expevt, r0 ! r0 = EXPEVT address. - mov.l .trapa_code, r1 ! r1 = trapa exception code - mov.l @r0, r0 ! r0 = excecption code - cmp/eq r1, r0 ! if exception code == TRAPA CODE... - bt _trapa_entry ! ...if yes, jump at + mov.l .expevt, r0 ! r0 = EXPEVT address. + mov.l .trapa_code, r1 ! r1 = trapa exception code + mov.l @r0, r0 ! r0 = excecption code + cmp/eq r1, r0 ! if exception code == TRAPA CODE... + bt trapa_entry ! ...if yes, jump at ! Call high-level abstraction - mov.l .exception_handler, r0 ! get high-level aception abstraction - jsr @r0 ! call abstraction - nop ! (db) nop - bra _exception_handler_exit ! jump at <_exception_handler_exit> - nop ! (db) nop. + mov.l .exception_handler, r0 ! get high-level aception abstraction + jsr @r0 ! call abstraction + nop ! (db) nop + bra exception_handler_exit ! jump at + nop ! (db) nop. + +trapa_entry: + ! Check current process + tst r2, r2 ! if current process == NULL... + bt exception_handler_exit ! ...if yes, jump at -_trapa_entry: ! Call syscall pre handler - mov.l .syscall_pre, r0 ! get syscall pre handler address - jsr @r0 ! call pre handler - nop ! (db) nop + mov.l .syscall_pre, r0 ! get syscall pre handler address + jsr @r0 ! call pre handler + nop ! (db) nop +exception_handler_exit: + ! "Restore" current process address + mov r8, r2 ! restore current process address -_exception_handler_exit: ! Restore critical regsiter - lds.l @r15+, pr ! restore PR register. - ldc.l @r15+, ssr ! restore SSR regsiter. - ldc.l @r15+, spc ! restore SPC regsiter. + mov.l @r15+, r8 ! resotre r8 register. + lds.l @r15+, pr ! restore PR register. + ldc.l @r15+, ssr ! restore SSR regsiter. + ldc.l @r15+, spc ! restore SPC regsiter. + + ! Restore user stack + tst r2, r2 ! if current process == NULL... + bt exit_end ! ...if yes, jump at + mov.l r15, @r2 ! save kernel stack + mov.l @(4, r2), r15 ! restore user stack ! Exit properly - rte ! exit - nop ! (db) nop +exit_end: + rte ! exit + nop ! (db) nop .align 4 .expevt: .long 0xff000024 .trapa_code: .long 0x00000160 .exception_handler: .long _exception_handler .syscall_pre: .long _syscall_pre +.process_current: .long _process_current .end diff --git a/src/kernel/process/alloc.c b/src/kernel/process/alloc.c index 56eabfd..4ccf978 100644 --- a/src/kernel/process/alloc.c +++ b/src/kernel/process/alloc.c @@ -1,6 +1,6 @@ #include -// This function SHOULD not be called +// This function SHOULD NOT be called // without atomic operation !! pid_t process_alloc(process_t **process) { diff --git a/src/kernel/process/create.c b/src/kernel/process/create.c index ffca96e..cd33b9b 100644 --- a/src/kernel/process/create.c +++ b/src/kernel/process/create.c @@ -18,8 +18,8 @@ pid_t process_create(const char *name) if (process == NULL) return (-1); - // Initialize stack - process->memory.stack.size = PROCESS_STACK_SIZE; + // Initialize user stack + process->memory.stack.size = PROCESS_USER_STACK_SIZE; process->memory.stack.start = (uint32_t)pm_alloc(process->memory.stack.size); if (process->memory.stack.start == 0x00000000) { @@ -28,6 +28,15 @@ pid_t process_create(const char *name) return (-1); } + // Initialize kernel stack + process->stack.kernel = (uint32_t)pm_alloc(PROCESS_KERNEL_STACK_SIZE); + if (process->stack.kernel == 0x00000000) + { + //TODO: errno + //FIXME: free allocated process. + return (-1); + } + // initialize "exit" part. uint8_t callexit[6] = { 0b11000011, __NR_exit, // trapa #__NR_exit diff --git a/src/kernel/process/switch.c b/src/kernel/process/switch.c index 13f6128..3f2985d 100644 --- a/src/kernel/process/switch.c +++ b/src/kernel/process/switch.c @@ -1,4 +1,4 @@ -#include +/*#include //FIXME: atomic operation !! int process_switch(pid_t pid) @@ -24,4 +24,4 @@ int process_switch(pid_t pid) // TODO: SYSCALL !!!!! //context_switch(context_current, context_next); return (0); -} +}*/ diff --git a/src/kernel/syscall/syscall_pre.s b/src/kernel/syscall/syscall_pre.s index d3272d5..5c04542 100644 --- a/src/kernel/syscall/syscall_pre.s +++ b/src/kernel/syscall/syscall_pre.s @@ -3,12 +3,14 @@ .type _syscall_pre, @function .extern _sys_get_handler +.extern _process_current .align 2 _syscall_pre: ! save some used register. mov.l r8, @-r15 ! save r8 register mov.l r9, @-r15 ! save r9 register + mov.l r10, @-r15 ! save r10 register sts.l pr, @-r15 ! save PR register ! Call syscall high-level abstraction @@ -33,16 +35,27 @@ _syscall_pre: and r1, r0 ! set SR.BL = 0, SR.RB = 0 and SR.IMASK = 0b0000 ldc r0, sr ! update SR regsiter + ! We should restore the user stack + mov.l .process_current, r10 ! get current_process adress + mov.l @r10, r10 ! get current process + mov.l r15, @r10 ! save current kernel stack + mov.l @(4, r10), r15 ! restore user stack + ! Call kernel abstraction jsr @r9 ! call system handler nop ! (db) nop. + ! Switch stack + mov.l r15, @(4, r10) ! save user stack + mov.l @r10, r15 ! restore kernel stack + ! Restore SR regsiter ldc r8, sr ! SR.BL = 1, SR.RB = 1 and SR.IMASK = old mask. syscall_pre_exit: ! Restore used regsiter. lds.l @r15+, pr ! restore PR register + mov.l @r15+, r10 ! restore r10 register mov.l @r15+, r9 ! restore r9 register mov.l @r15+, r8 ! restore r8 register @@ -54,4 +67,5 @@ syscall_pre_exit: .tra: .long 0xff000020 .sr_mask: .long ~(0x300000f0) .sys_get_handler: .long _sys_get_handler +.process_current: .long _process_current .end