Still more stuff
This commit is contained in:
parent
d4be0f4fd5
commit
31702521b1
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -110,11 +92,69 @@ status_t DosChTermColor(terminal_t *kt, uchar color)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Writes a single character on the terminal (UNLOCKED version)
|
// Writes a single character on the terminal
|
||||||
//
|
//
|
||||||
// DEPRECATED:
|
status_t DosPutOnTerm(terminal_t *kt, char ch)
|
||||||
// - always use kterm_putch (LOCKED version)
|
{
|
||||||
// - doesn't check for NULL input
|
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)
|
||||||
//
|
//
|
||||||
void DosPutOnTerm_Unlocked(terminal_t *kt, char ch)
|
void DosPutOnTerm_Unlocked(terminal_t *kt, char ch)
|
||||||
{
|
{
|
||||||
|
@ -159,36 +199,14 @@ void DosPutOnTerm_Unlocked(terminal_t *kt, char ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Writes a single character on the terminal (LOCKED version)
|
// Print string on terminal (UNLOCKED version)
|
||||||
//
|
//
|
||||||
status_t DosPutOnTerm(terminal_t *kt, char ch)
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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,18 +24,16 @@ 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
|
||||||
|
@ -50,7 +46,10 @@ 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 DosClearTerm_Unlocked(terminal_t *);
|
||||||
void DosPutOnTerm_Unlocked(terminal_t *, char);
|
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
|
||||||
|
@ -60,9 +59,9 @@ extern terminal_t *stddbg;
|
||||||
# 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
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Locks //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include <kaleid/kernel/ke/lock.h>
|
||||||
|
|
||||||
|
// nothing to do here
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue