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
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

View File

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

View File

@ -7,6 +7,7 @@
// Desc: Early terminal functions //
//----------------------------------------------------------------------------//
#define _UNLOCKED_IO
#include <kaleid/kernel/io/terminal.h>
//
@ -26,10 +27,8 @@ static terminal_t _vga_term = {
.kt_curr_x = 0,
.kt_curr_y = 0,
.kt_color = ComputeColorCode(KTERM_COLOR_LGREY, KTERM_COLOR_BLACK),
.kt_lock = NULL,
#ifndef _NO_DEBUG
.kt_lock = INITLOCK(KLOCK_MUTEX),
.kt_init = FALSE,
#endif
};
//
@ -37,24 +36,20 @@ static terminal_t _vga_term = {
//
terminal_t *stdout;
#ifndef _NO_DEBUG
//
// Debugging terminal
//
terminal_t *stddbg;
#endif
//
// Initialize standard output
//
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 = TRUE;
_vga_term.kt_init = INITOK;
stddbg = &_vga_term;
#endif
// to be switched to VESA
stdout = &_vga_term;
@ -63,29 +58,16 @@ void DosInitTerms(void)
//
// Fills terminal with spaces
// XXX would '\0' work too?
//
status_t DosClearTerm(terminal_t *kt)
{
size_t i;
if (kt == NULL)
return BAD_ARG_NULL;
assert(kt->kt_init && "DosClearTerm called before initialization");
DosAssert(kt->kt_init == INITOK);
DosLockTerm(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;
DosClearTerm_Unlocked(kt);
DosUnlockTerm(kt);
return SUCCESS;
@ -102,20 +84,78 @@ status_t DosChTermColor(terminal_t *kt, uchar color)
if (kt == NULL)
return BAD_ARG_NULL;
DosLockTerm(kt);
DosLockTerm(kt);
kt->kt_color = color;
DosUnlockTerm(kt);
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)
//
// DEPRECATED:
// - always use kterm_putch (LOCKED version)
// - doesn't check for NULL input
//
void DosPutOnTerm_Unlocked(terminal_t *kt, char ch)
{
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) {
DosPutOnTerm_Unlocked(kt, *str++);
}
DosUnlockTerm(kt);
return SUCCESS;
}

View File

@ -10,12 +10,10 @@
#ifndef _KALKERN_IO_KTERM_H
#define _KALKERN_IO_KTERM_H
#ifndef _KALCOMM_COMMON_H
#include <kaleid/common/common.h>
#endif
#include <kaleid/kernel/ke/lock.h>
// all available colors
enum kterm_colors {
enum terminal_colors {
KTERM_COLOR_BLACK, KTERM_COLOR_BLUE,
KTERM_COLOR_GREEN, KTERM_COLOR_CYAN,
KTERM_COLOR_RED, KTERM_COLOR_MAGENTA,
@ -26,43 +24,44 @@ enum kterm_colors {
KTERM_COLOR_LBROWN, KTERM_COLOR_WHITE
};
typedef struct kterm {
void *kt_lock;
ushort *kt_buffer;
uchar kt_color;
size_t kt_width;
size_t kt_height;
off_t kt_curr_x;
off_t kt_curr_y;
typedef struct {
lock_t kt_lock;
ushort *kt_buffer;
uchar kt_color;
size_t kt_width;
size_t kt_height;
off_t kt_curr_x;
off_t kt_curr_y;
uint kt_init;
// XXX flags
#ifndef _NO_DEBUG
bool kt_init;
#endif
} terminal_t;
// current "standard" terminal
extern terminal_t *stdout;
void DosInitTerms(void);
status_t DosClearTerm(terminal_t *);
status_t DosPutOnTerm(terminal_t *, char);
status_t DosPrintOnTerm(terminal_t *, const char *);
status_t DosChTermColor(terminal_t *, uchar);
void DosInitTerms(void);
status_t DosClearTerm(terminal_t *);
status_t DosPutOnTerm(terminal_t *, char);
status_t DosPrintOnTerm(terminal_t *, const char *);
status_t DosChTermColor(terminal_t *, uchar);
#ifdef _UNLOCKED_IO
void DosPutOnTerm_Unlocked(terminal_t *, char);
#ifdef _UNLOCKED_IO
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
#ifndef _NO_DEBUG
extern terminal_t *stddbg;
# define DebugLog(...) DosPutOnTerm(stddbg, __VA_ARGS__)
# define DebugLog(...) DosPutOnTerm(stddbg, __VA_ARGS__)
#else
# define DebugLog(...)
#endif
#define DosLockTerm(kt)
#define DosTryLockTerm(kt)
#define DosUnlockTerm(kt)
#define DosLockTerm(kt) DosAquireLock(&kt->kt_lock)
#define DosUnlockTerm(kt) DosReleaseLock(&kt->kt_lock)
#define DosTryLockTerm(kt) DosAttemptLock(&kt->kt_lock)
#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/state.h>
#define _UNLOCKED_IO
#include <kaleid/kernel/io/terminal.h>
//
// Panic message
//
const char *panicstr = NULL;
const char *__panicmsg = NULL;
//
// Failed assert() handler
@ -39,22 +41,22 @@ void DosPanic(const char *str)
DosSetKernState(KSTATE_PANIC);
DosClearTerm(stdout);
DosClearTerm_Unlocked(stdout);
if (str == NULL) {
str = "(no message given)";
}
if (panicstr) {
// shouldn't be possible
DosPrintOnTerm(stdout, "double panic!\n");
if (DosGetPanicStr()) {
DosPrintOnTerm_Unlocked(stdout, "double panic!\n");
DosHaltCPU();
}
panicstr = str;
DosSetPanicStr(str);
DosPrintOnTerm(stdout, "panic! - ");
DosPrintOnTerm(stdout, str);
// we cannot lock anything when panicking
DosPrintOnTerm_Unlocked(stdout, "panic! - ");
DosPrintOnTerm_Unlocked(stdout, str);
while (TRUE) {
DosHaltCPU();

View File

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