diff --git a/include/cm/cm.h b/include/cm/cm.h index ef4577e..e6a235e 100644 --- a/include/cm/cm.h +++ b/include/cm/cm.h @@ -10,6 +10,13 @@ #include #include +#ifdef KERNEL + #include + #include +#else + #include + #include +#endif #define INVALID_HANDLE (-1) #define HALT() for (;;) @@ -23,3 +30,30 @@ INT vsnprintf (CHAR* dest, size_t size, const CHAR* fmt, va_list l); * @return Nothing **************************************************************************************************/ void cm_delay (UINT ms); + +/*************************************************************************************************** + * Process management + ***************************************************************************************************/ +INT cm_thread_create (void (*startLocation)(), bool isKernelMode); +INT cm_process_create (void* startLocation, SIZE binaryLengthBytes, bool isKernelMode); +bool cm_process_is_yield_requested(); + +static inline void cm_process_yield() +{ + syscall (OSIF_SYSCALL_YIELD_PROCESS, 0, 0, 0, 0, 0); +} + +static inline void cm_process_kill (UINT code) +{ + syscall (OSIF_SYSCALL_KILL_PROCESS, code, 0, 0, 0, 0); +} + +static inline U32 cm_process_get_pid() +{ + return (U32)syscall (OSIF_SYSCALL_PROCESS_GETPID, 0, 0, 0, 0, 0); +} + +static inline void* cm_process_get_datamem_start() +{ + return (void*)syscall (OSIF_SYSCALL_PROCESS_GET_DATAMEM_START, 0, 0, 0, 0, 0); +} diff --git a/include/cm/err.h b/include/cm/err.h new file mode 100644 index 0000000..a6a37a1 --- /dev/null +++ b/include/cm/err.h @@ -0,0 +1,44 @@ +/* + * --------------------------------------------------------------------------- + * Megha Operating System V2 - C MOS App library - Library errors + * --------------------------------------------------------------------------- + */ + +#include +#ifdef KERNEL + #include + #include + #include +#else + #include + #include + #include +#endif + +#define CM_FAILURE (-1) + +typedef enum CMErrors { + // OS Errors start from 0 and must end before the start of library errors + LIBRARY_ERRORS_START = 100, + CM_ERR_INVALID_INPUT = 100, +} CMErrors; + +extern uint32_t cm_error_num__; + +static inline uint32_t cm_get_lib_error() +{ + return cm_error_num__; +} + +static inline uint32_t cm_get_os_error() +{ + return (uint32_t)syscall (OSIF_SYSCALL_GET_OS_ERROR, 0, 0, 0, 0, 0); +} + +/* Can be used to store an error code and return from a function */ +#define CM_RETURN_ERROR__(errno, rval) \ + do { \ + ERROR ("Error %x.", errno); \ + cm_error_num__ = errno; \ + return rval; \ + } while (0) diff --git a/include/cm/osif.h b/include/cm/osif.h index fc8d2a6..2a116bf 100644 --- a/include/cm/osif.h +++ b/include/cm/osif.h @@ -31,6 +31,7 @@ typedef enum OSIF_SYSCALLS { OSIF_SYSCALL_WINDOW_DESTORY = 11, OSIF_SYSCALL_WINDOW_GET_WINDOW_FB = 12, OSIF_SYSCALL_WINDOW_FLUSH_GRAPHICS = 13, + OSIF_SYSCALL_GET_OS_ERROR = 14, } OSIF_SYSCALLS; typedef enum OSIF_ProcessEvents { diff --git a/include/cm/syscall.h b/include/cm/syscall.h index f053c23..50c3d21 100644 --- a/include/cm/syscall.h +++ b/include/cm/syscall.h @@ -17,37 +17,18 @@ #endif S32 syscall (OSIF_SYSCALLS fn, U32 arg1, U32 arg2, U32 arg3, U32 arg4, U32 arg5); -INT cm_thread_create (void (*startLocation)(), bool isKernelMode); -INT cm_process_create (void* startLocation, SIZE binaryLengthBytes, bool isKernelMode); UINT cm_get_tick_period_us(); -bool cm_process_is_yield_requested(); -bool cm_process_is_child_exited (UINT* exitCode); static inline UINT cm_tickcount_to_microsec(UINT tick) { return ((tick)*cm_get_tick_period_us()); } -static inline void cm_process_yield() -{ - syscall (OSIF_SYSCALL_YIELD_PROCESS, 0, 0, 0, 0, 0); -} - -static inline void cm_process_kill(UINT code) -{ - syscall (OSIF_SYSCALL_KILL_PROCESS, code, 0, 0, 0, 0); -} - static inline void cm_putstr (char* text) { syscall (OSIF_SYSCALL_CONSOLE_WRITELN, (PTR)text, 0, 0, 0, 0); } -static inline U32 cm_process_get_pid() -{ - return (U32)syscall (OSIF_SYSCALL_PROCESS_GETPID, 0, 0, 0, 0, 0); -} - static inline U32 cm_get_tickcount() { return (U32)syscall (OSIF_SYSCALL_TIMER_GET_TICKCOUNT, 0, 0, 0, 0, 0); @@ -63,11 +44,6 @@ static inline U32 cm_window_destory (Handle h) return (U32)syscall (OSIF_SYSCALL_WINDOW_DESTORY, (U32)h, 0, 0, 0, 0); } -static inline void* cm_process_get_datamem_start() -{ - return (void*)syscall (OSIF_SYSCALL_PROCESS_GET_DATAMEM_START, 0, 0, 0, 0, 0); -} - static inline void* cm_window_flush_graphics() { return (void*)syscall (OSIF_SYSCALL_WINDOW_FLUSH_GRAPHICS, 0, 0, 0, 0, 0); diff --git a/src/cm/CMakeLists.txt b/src/cm/CMakeLists.txt index ddcf66b..5b7f021 100644 --- a/src/cm/CMakeLists.txt +++ b/src/cm/CMakeLists.txt @@ -21,6 +21,7 @@ compile_lib( # C library to talk to the OS and helpful/common functions for use by application programs. # ------------------------------------------------------------------------ set(APPLIB_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/process.c ${CMAKE_CURRENT_SOURCE_DIR}/syscalls.c ${CMAKE_CURRENT_SOURCE_DIR}/printf.c ${CMAKE_CURRENT_SOURCE_DIR}/debug.c diff --git a/src/cm/cm.c b/src/cm/cm.c index 6f433d1..e30443c 100644 --- a/src/cm/cm.c +++ b/src/cm/cm.c @@ -9,6 +9,9 @@ #include #include +/* Variable to store Library error*/ +uint32_t cm_error_num__; + #define cm_MICRODEC_TO_TICK_COUNT(us) ((us) / cm_get_tick_period_us()) void event_handler_NDU_() diff --git a/src/cm/process.c b/src/cm/process.c new file mode 100644 index 0000000..a517822 --- /dev/null +++ b/src/cm/process.c @@ -0,0 +1,53 @@ +/* + * ------------------------------------------------------------------------------------------------- + * Megha Operating System V2 - C MOS App Library - Process management + * ------------------------------------------------------------------------------------------------- + */ + +#include +#include +#include + +INT cm_process_create (void* startLocation, SIZE binaryLengthBytes, bool isKernelMode) +{ + if (!startLocation || binaryLengthBytes == 0) { + CM_RETURN_ERROR__ (CM_ERR_INVALID_INPUT, CM_FAILURE); + } + + KProcessFlags flags = PROCESS_FLAGS_NONE; + if (isKernelMode) { + flags |= PROCESS_FLAGS_KERNEL_PROCESS; + } + + INT pid = syscall (OSIF_SYSCALL_CREATE_PROCESS, (U32)startLocation, binaryLengthBytes, + (U32)flags, 0, 0); + if (pid < 0) { + CM_RETURN_ERROR__ (cm_get_os_error(), CM_FAILURE); + } + return pid; +} + +INT cm_thread_create (void (*startLocation)(), bool isKernelMode) +{ + if (!startLocation) { + CM_RETURN_ERROR__ (CM_ERR_INVALID_INPUT, CM_FAILURE); + } + + KProcessFlags flags = PROCESS_FLAGS_THREAD; + if (isKernelMode) { + flags |= PROCESS_FLAGS_KERNEL_PROCESS; + } + + INT pid = syscall (OSIF_SYSCALL_CREATE_PROCESS, (U32)startLocation, 0, (U32)flags, 0, 0); + if (pid < 0) { + CM_RETURN_ERROR__ (cm_get_os_error(), CM_FAILURE); + } + return pid; +} + +bool cm_process_is_yield_requested() +{ + volatile OSIF_ProcessEvent e = { 0 }; + cm_process_pop_event ((OSIF_ProcessEvent*)&e); + return (e.event == OSIF_PROCESS_EVENT_PROCCESS_YIELD_REQ); +} diff --git a/src/cm/syscalls.c b/src/cm/syscalls.c index 91c0396..902a9a5 100644 --- a/src/cm/syscalls.c +++ b/src/cm/syscalls.c @@ -16,8 +16,6 @@ #include #include -#include -#include S32 syscall (OSIF_SYSCALLS fn, U32 arg1, U32 arg2, U32 arg3, U32 arg4, U32 arg5) { @@ -30,33 +28,6 @@ S32 syscall (OSIF_SYSCALLS fn, U32 arg1, U32 arg2, U32 arg3, U32 arg4, U32 arg5) return retval; } -INT cm_process_create (void* startLocation, SIZE binaryLengthBytes, bool isKernelMode) -{ - KProcessFlags flags = PROCESS_FLAGS_NONE; - if (isKernelMode) { - flags |= PROCESS_FLAGS_KERNEL_PROCESS; - } - - return syscall (OSIF_SYSCALL_CREATE_PROCESS, (U32)startLocation, binaryLengthBytes, (U32)flags, - 0, 0); -} - -INT cm_thread_create (void (*startLocation)(), bool isKernelMode) -{ - KProcessFlags flags = PROCESS_FLAGS_THREAD; - if (isKernelMode) { - flags |= PROCESS_FLAGS_KERNEL_PROCESS; - } - return syscall (OSIF_SYSCALL_CREATE_PROCESS, (U32)startLocation, 0, (U32)flags, 0, 0); -} - -bool cm_process_is_yield_requested() -{ - volatile OSIF_ProcessEvent e = { 0 }; - cm_process_pop_event ((OSIF_ProcessEvent*)&e); - return (e.event == OSIF_PROCESS_EVENT_PROCCESS_YIELD_REQ); -} - UINT cm_get_tick_period_us() { return CONFIG_TICK_PERIOD_MICROSEC; diff --git a/src/kernel/x86/syscalls.c b/src/kernel/x86/syscalls.c index e801fc1..b341306 100644 --- a/src/kernel/x86/syscalls.c +++ b/src/kernel/x86/syscalls.c @@ -42,6 +42,7 @@ bool ksys_processPopEvent (SystemcallFrame frame, OSIF_ProcessEvent* const e); U32 ksys_process_getPID (SystemcallFrame frame); U32 ksys_get_tickcount (SystemcallFrame frame); PTR ksys_process_getDataMemoryStart (SystemcallFrame frame); +U32 sys_get_os_error (SystemcallFrame frame); #ifdef GRAPHICS_MODE_ENABLED Handle ksys_window_createWindow (SystemcallFrame frame, const char* winTitle); @@ -57,14 +58,17 @@ static INT s_handleInvalidSystemCall(); #pragma GCC diagnostic ignored "-Wincompatible-pointer-types" #pragma GCC diagnostic ignored "-Wpedantic" void* g_syscall_table[] = { + //--------------------------- #if defined(DEBUG) &ksys_console_writeln, // 0 #else &s_handleInvalidSystemCall, // 0 #endif + //--------------------------- &ksys_createProcess, // 1 &ksys_yieldProcess, // 2 &ksys_killProcess, // 3 + //--------------------------- #if defined(DEBUG) && !defined(GRAPHICS_MODE_ENABLED) &ksys_console_setcolor, // 4 &ksys_console_setposition, // 5 @@ -72,10 +76,12 @@ void* g_syscall_table[] = { &s_handleInvalidSystemCall, // 4 &s_handleInvalidSystemCall, // 5 #endif + //--------------------------- &ksys_processPopEvent, // 6 &ksys_process_getPID, // 7 &ksys_get_tickcount, // 8 &ksys_process_getDataMemoryStart, // 9 + //--------------------------- #ifdef GRAPHICS_MODE_ENABLED &ksys_window_createWindow, // 10 &ksys_window_destoryWindow, // 11 @@ -87,6 +93,8 @@ void* g_syscall_table[] = { &s_handleInvalidSystemCall, // 12 &s_handleInvalidSystemCall, // 13 #endif + //--------------------------- + &sys_get_os_error, // 14 }; #pragma GCC diagnostic pop