Still more stuff

This commit is contained in:
Julian Barathieu 2018-12-30 22:21:19 +01:00
parent d4be0f4fd5
commit 31702521b1
8 changed files with 226 additions and 94 deletions

View File

@ -21,7 +21,8 @@
// uses panic() in kernel, abort() in system // uses panic() in kernel, abort() in system
noreturn void ___assert_handler(const char *, const char *, int, const char *); noreturn void ___assert_handler(const char *, const char *, int, const char *);
#define assert(x) do{if(unlikely(!(x)))___assert_handler(#x, __FILE__, __LINE__, __func__);}while(0); #define DosAssert(x) do{if(unlikely(!(x)))___assert_handler(#x, __FILE__, __LINE__, __func__);}while(0);
#define assert DosAssert
#else // not debugging #else // not debugging

View File

@ -41,6 +41,10 @@
# define unlikely(x) __builtin_expect((x), 0) # define unlikely(x) __builtin_expect((x), 0)
#endif #endif
#ifndef INITOK
# define INITOK 0xCAFEBABE
#endif
#ifdef _KALEID_KERNEL #ifdef _KALEID_KERNEL
# include <kaleid/kernel/config.h> # include <kaleid/kernel/config.h>
#endif #endif

View File

@ -7,6 +7,7 @@
// Desc: Early terminal functions // // Desc: Early terminal functions //
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
#define _UNLOCKED_IO
#include <kaleid/kernel/io/terminal.h> #include <kaleid/kernel/io/terminal.h>
// //
@ -26,10 +27,8 @@ static terminal_t _vga_term = {
.kt_curr_x = 0, .kt_curr_x = 0,
.kt_curr_y = 0, .kt_curr_y = 0,
.kt_color = ComputeColorCode(KTERM_COLOR_LGREY, KTERM_COLOR_BLACK), .kt_color = ComputeColorCode(KTERM_COLOR_LGREY, KTERM_COLOR_BLACK),
.kt_lock = NULL, .kt_lock = INITLOCK(KLOCK_MUTEX),
#ifndef _NO_DEBUG
.kt_init = FALSE, .kt_init = FALSE,
#endif
}; };
// //
@ -37,24 +36,20 @@ static terminal_t _vga_term = {
// //
terminal_t *stdout; terminal_t *stdout;
#ifndef _NO_DEBUG
// //
// Debugging terminal // Debugging terminal
// //
terminal_t *stddbg; terminal_t *stddbg;
#endif
// //
// Initialize standard output // Initialize standard output
// //
void DosInitTerms(void) void DosInitTerms(void)
{ {
assert(!stdout && !_vga_term.kt_init && "DosInitTerms() called twice"); DosAssert(!stdout && _vga_term.kt_init != INITOK && "DosInitTerms() called twice");
#ifndef _NO_DEBUG _vga_term.kt_init = INITOK;
_vga_term.kt_init = TRUE;
stddbg = &_vga_term; stddbg = &_vga_term;
#endif
// to be switched to VESA // to be switched to VESA
stdout = &_vga_term; stdout = &_vga_term;
@ -63,29 +58,16 @@ void DosInitTerms(void)
// //
// Fills terminal with spaces // Fills terminal with spaces
// XXX would '\0' work too?
// //
status_t DosClearTerm(terminal_t *kt) status_t DosClearTerm(terminal_t *kt)
{ {
size_t i;
if (kt == NULL) if (kt == NULL)
return BAD_ARG_NULL; return BAD_ARG_NULL;
assert(kt->kt_init && "DosClearTerm called before initialization"); DosAssert(kt->kt_init == INITOK);
DosLockTerm(kt); DosLockTerm(kt);
DosClearTerm_Unlocked(kt);
const ushort filler = ComputeEntry(' ', kt->kt_color);
const size_t bufsize = kt->kt_width * kt->kt_height;
for (i = 0; i < bufsize; i++) {
// XXX implement memsetw()
kt->kt_buffer[i] = filler;
}
kt->kt_curr_x = kt->kt_curr_y = 0;
DosUnlockTerm(kt); DosUnlockTerm(kt);
return SUCCESS; return SUCCESS;
@ -102,20 +84,78 @@ status_t DosChTermColor(terminal_t *kt, uchar color)
if (kt == NULL) if (kt == NULL)
return BAD_ARG_NULL; return BAD_ARG_NULL;
DosLockTerm(kt); DosLockTerm(kt);
kt->kt_color = color; kt->kt_color = color;
DosUnlockTerm(kt); DosUnlockTerm(kt);
return SUCCESS; return SUCCESS;
} }
//
// Writes a single character on the terminal
//
status_t DosPutOnTerm(terminal_t *kt, char ch)
{
if (kt == NULL)
return BAD_ARG_NULL;
DosAssert(kt->kt_init == INITOK);
DosLockTerm(kt);
DosPutOnTerm_Unlocked(kt, ch);
DosUnlockTerm(kt);
return SUCCESS;
}
//
// Print string on terminal
//
status_t DosPrintOnTerm(terminal_t *kt, const char *str)
{
if (kt == NULL)
return BAD_ARG_NULL;
DosAssert(kt->kt_init == INITOK);
DosLockTerm(kt);
while (*str) {
DosPutOnTerm_Unlocked(kt, *str++);
}
DosUnlockTerm(kt);
return SUCCESS;
}
//----------------------------------------------------------//
// UNLOCKED VERSIONS //
// //
// Direct use is highly deprecated //
// Useful in rare instances //
//----------------------------------------------------------//
//
// Fills terminal with spaces
// XXX would '\0' work too?
//
void DosClearTerm_Unlocked(terminal_t *kt)
{
size_t i;
const ushort filler = ComputeEntry(' ', kt->kt_color);
const size_t bufsize = kt->kt_width * kt->kt_height;
for (i = 0; i < bufsize; i++) {
// XXX implement memsetw()
kt->kt_buffer[i] = filler;
}
kt->kt_curr_x = kt->kt_curr_y = 0;
}
// //
// Writes a single character on the terminal (UNLOCKED version) // Writes a single character on the terminal (UNLOCKED version)
// //
// DEPRECATED:
// - always use kterm_putch (LOCKED version)
// - doesn't check for NULL input
//
void DosPutOnTerm_Unlocked(terminal_t *kt, char ch) void DosPutOnTerm_Unlocked(terminal_t *kt, char ch)
{ {
int i; int i;
@ -158,37 +198,15 @@ void DosPutOnTerm_Unlocked(terminal_t *kt, char ch)
} }
} }
//
// Writes a single character on the terminal (LOCKED version)
// //
status_t DosPutOnTerm(terminal_t *kt, char ch) // Print string on terminal (UNLOCKED version)
//
void DosPrintOnTerm_Unlocked(terminal_t *kt, const char *str)
{ {
if (kt == NULL)
return BAD_ARG_NULL;
DosLockTerm(kt);
DosPutOnTerm_Unlocked(kt, ch);
DosUnlockTerm(kt);
return SUCCESS;
}
//
// Print string on terminal
//
status_t DosPrintOnTerm(terminal_t *kt, const char *str)
{
if (kt == NULL)
return BAD_ARG_NULL;
DosLockTerm(kt);
while (*str) { while (*str) {
DosPutOnTerm_Unlocked(kt, *str++); DosPutOnTerm_Unlocked(kt, *str++);
} }
DosUnlockTerm(kt);
return SUCCESS;
} }

View File

@ -10,12 +10,10 @@
#ifndef _KALKERN_IO_KTERM_H #ifndef _KALKERN_IO_KTERM_H
#define _KALKERN_IO_KTERM_H #define _KALKERN_IO_KTERM_H
#ifndef _KALCOMM_COMMON_H #include <kaleid/kernel/ke/lock.h>
#include <kaleid/common/common.h>
#endif
// all available colors // all available colors
enum kterm_colors { enum terminal_colors {
KTERM_COLOR_BLACK, KTERM_COLOR_BLUE, KTERM_COLOR_BLACK, KTERM_COLOR_BLUE,
KTERM_COLOR_GREEN, KTERM_COLOR_CYAN, KTERM_COLOR_GREEN, KTERM_COLOR_CYAN,
KTERM_COLOR_RED, KTERM_COLOR_MAGENTA, KTERM_COLOR_RED, KTERM_COLOR_MAGENTA,
@ -26,43 +24,44 @@ enum kterm_colors {
KTERM_COLOR_LBROWN, KTERM_COLOR_WHITE KTERM_COLOR_LBROWN, KTERM_COLOR_WHITE
}; };
typedef struct kterm { typedef struct {
void *kt_lock; lock_t kt_lock;
ushort *kt_buffer; ushort *kt_buffer;
uchar kt_color; uchar kt_color;
size_t kt_width; size_t kt_width;
size_t kt_height; size_t kt_height;
off_t kt_curr_x; off_t kt_curr_x;
off_t kt_curr_y; off_t kt_curr_y;
uint kt_init;
// XXX flags // XXX flags
#ifndef _NO_DEBUG
bool kt_init;
#endif
} terminal_t; } terminal_t;
// current "standard" terminal // current "standard" terminal
extern terminal_t *stdout; extern terminal_t *stdout;
void DosInitTerms(void); void DosInitTerms(void);
status_t DosClearTerm(terminal_t *); status_t DosClearTerm(terminal_t *);
status_t DosPutOnTerm(terminal_t *, char); status_t DosPutOnTerm(terminal_t *, char);
status_t DosPrintOnTerm(terminal_t *, const char *); status_t DosPrintOnTerm(terminal_t *, const char *);
status_t DosChTermColor(terminal_t *, uchar); status_t DosChTermColor(terminal_t *, uchar);
#ifdef _UNLOCKED_IO #ifdef _UNLOCKED_IO
void DosPutOnTerm_Unlocked(terminal_t *, char); void DosClearTerm_Unlocked(terminal_t *);
void DosPutOnTerm_Unlocked(terminal_t *, char);
void DosPrintOnTerm_Unlocked(terminal_t *kt, const char *str);
#define DosChTermColor_Unlocked(kt, col) ((kt)->kt_color = col)
#endif #endif
#ifndef _NO_DEBUG #ifndef _NO_DEBUG
extern terminal_t *stddbg; extern terminal_t *stddbg;
# define DebugLog(...) DosPutOnTerm(stddbg, __VA_ARGS__) # define DebugLog(...) DosPutOnTerm(stddbg, __VA_ARGS__)
#else #else
# define DebugLog(...) # define DebugLog(...)
#endif #endif
#define DosLockTerm(kt) #define DosLockTerm(kt) DosAquireLock(&kt->kt_lock)
#define DosTryLockTerm(kt) #define DosUnlockTerm(kt) DosReleaseLock(&kt->kt_lock)
#define DosUnlockTerm(kt) #define DosTryLockTerm(kt) DosAttemptLock(&kt->kt_lock)
#endif #endif

View File

@ -0,0 +1,13 @@
//----------------------------------------------------------------------------//
// GNU GPL OS/K //
// //
// Authors: spectral` //
// NeoX //
// //
// Desc: Locks //
//----------------------------------------------------------------------------//
#include <kaleid/kernel/ke/lock.h>
// nothing to do here

View File

@ -0,0 +1,96 @@
//----------------------------------------------------------------------------//
// GNU GPL OS/K //
// //
// Authors: spectral` //
// NeoX //
// //
// Desc: Locks //
//----------------------------------------------------------------------------//
#ifndef _KALKERN_KE_LOCK_H
#define _KALKERN_KE_LOCK_H
#ifndef _KALCOMM_COMMON_H
#include <kaleid/common/common.h>
#endif
enum lock_type {
//
// Mutex-type lock
// WARNING: DosLock() panics when used on a mutex while not running a process
//
KLOCK_MUTEX,
//
// Spinlock-type lock
// Turns into a Mutex-type lock when MULTIPROCESSOR is off
//
KLOCK_SPINLOCK,
};
typedef struct {
uchar lk_type; // lock type?
uint lk_lock; // is locked?
void *lk_owner; // unused
void *lk_waiting; // unused
uint lk_init; // unused if _NO_DEBUG
} lock_t;
//
// Initialize a lock
//
#define DosInitLock(lk, type) \
do { \
(lk)->lk_type = (type); \
(lk)->lk_lock = FALSE; \
(lk)->lk_owner = NULL; \
(lk)->lk_waiting = NULL; \
(lk)->lk_init = INITOK; \
} while (FALSE);
//
// Alternative way to initalize a lock
//
#define INITLOCK(type) { (type), FALSE, NULL, NULL, INITOK }
//
// Does nothing
//
#define DosDestroyLock(lk)
//
// Aquires the lock
// Panics on double aquisition since that should never happen
// until we have at least a basic scheduler
//
#define DosAquireLock(lk) \
do { \
DosDisableInterrupts(); \
DosAssert((lk)->lk_init == INITOK); \
if ((lk)->lk_lock++) \
DosPanic("DosAquireLock on an already locked object"); \
DosEnableInterrupts(); \
} while (FALSE);
//
// Releases an already aquired lock
// Panics if the lock was never aquired (this will change)
//
#define DosReleaseLock(lk) \
do { \
DosDisableInterrupts(); \
DosAssert((lk)->lk_init == INITOK); \
if ((lk)->lk_lock++) \
DosPanic("DosReleased on an unlocked object"); \
DosEnableInterrupts(); \
} while (FALSE);
//
// Tries to aquire lock
// Doesn't work at all for obvious reasons
//
#define DosAttemptLock(lk) ((lk)->lk_lock++)
#endif

View File

@ -9,12 +9,14 @@
#include <kaleid/kernel/ke/panic.h> #include <kaleid/kernel/ke/panic.h>
#include <kaleid/kernel/ke/state.h> #include <kaleid/kernel/ke/state.h>
#define _UNLOCKED_IO
#include <kaleid/kernel/io/terminal.h> #include <kaleid/kernel/io/terminal.h>
// //
// Panic message // Panic message
// //
const char *panicstr = NULL; const char *__panicmsg = NULL;
// //
// Failed assert() handler // Failed assert() handler
@ -39,22 +41,22 @@ void DosPanic(const char *str)
DosSetKernState(KSTATE_PANIC); DosSetKernState(KSTATE_PANIC);
DosClearTerm(stdout); DosClearTerm_Unlocked(stdout);
if (str == NULL) { if (str == NULL) {
str = "(no message given)"; str = "(no message given)";
} }
if (panicstr) { if (DosGetPanicStr()) {
// shouldn't be possible DosPrintOnTerm_Unlocked(stdout, "double panic!\n");
DosPrintOnTerm(stdout, "double panic!\n");
DosHaltCPU(); DosHaltCPU();
} }
panicstr = str; DosSetPanicStr(str);
DosPrintOnTerm(stdout, "panic! - "); // we cannot lock anything when panicking
DosPrintOnTerm(stdout, str); DosPrintOnTerm_Unlocked(stdout, "panic! - ");
DosPrintOnTerm_Unlocked(stdout, str);
while (TRUE) { while (TRUE) {
DosHaltCPU(); DosHaltCPU();

View File

@ -12,11 +12,10 @@
#include <kaleid/kernel/ke/state.h> #include <kaleid/kernel/ke/state.h>
extern const char *__panicstr;
noreturn void DosPanic(const char *); noreturn void DosPanic(const char *);
#define DosGetPanicStr() (__panicstr) extern const char *__panicmsg;
#define DosGetPanicStr() (__panicmsg)
#define panic DosPanic #define DosSetPanicStr(str) (__panicmsg = (str))
#endif #endif