Slighly better terminal stuff

This commit is contained in:
Julian Barathieu 2019-03-19 13:37:23 +01:00
parent 5b585e5b70
commit 08b4fa927d
10 changed files with 118 additions and 127 deletions

View File

@ -77,7 +77,7 @@ noreturn void __assert_handler(const char *, const char *, int, const char *);
// When debugging // // When debugging //
//------------------------------------------// //------------------------------------------//
#if !defined(_NO_DEBUG) && !defined(NDEBUG) && !defined(KalAssert) #if /*!defined(_NO_DEBUG) && !defined(NDEBUG) &&*/ !defined(KalAssert)
// //
// Check whether (x) holds, if not call __assert_handler // Check whether (x) holds, if not call __assert_handler

View File

@ -51,7 +51,7 @@ enum LockType_t
// Mutex-type lock // Mutex-type lock
// //
// WARNING // WARNING
// AquireLock() panics when used on a mutex while not running a process // AcquireLock() panics when used on a mutex while not running a process
KLOCK_MUTEX, KLOCK_MUTEX,
// Spinlock-type lock // Spinlock-type lock
@ -121,18 +121,18 @@ void DestroyLock(Lock_t *lock)
} }
// //
// Aquire the lock // Acquire the lock
// Panic on double aquisition since that should never happen // Panic on double acquisition since that should never happen
// until we have at least a basic scheduler // until we have at least a basic scheduler
// //
static inline static inline
void AquireLock(Lock_t *lock) void AcquireLock(Lock_t *lock)
{ {
KalAssert(lock->initDone == INITOK); KalAssert(lock->initDone == INITOK);
while (!__sync_bool_compare_and_swap(&lock->locked, 0, 1)) { while (!__sync_bool_compare_and_swap(&lock->locked, 0, 1)) {
#ifdef _KALEID_KERNEL #ifdef _KALEID_KERNEL
StartPanic("AquireLock on an already locked object"); StartPanic("AcquireLock on an already locked object");
#else #else
if likely (lock->type == KLOCK_SPINLOCK) continue; if likely (lock->type == KLOCK_SPINLOCK) continue;
#ifdef _OSK_SOURCE #ifdef _OSK_SOURCE
@ -146,8 +146,8 @@ void AquireLock(Lock_t *lock)
} }
// //
// Release an already aquired lock // Release an already acquired lock
// Panic if the lock was never aquired // Panic if the lock was never acquired
// //
static inline static inline
void ReleaseLock(Lock_t *lock) void ReleaseLock(Lock_t *lock)
@ -161,7 +161,7 @@ void ReleaseLock(Lock_t *lock)
} }
// //
// Tries to aquire lock // Tries to acquire lock
// //
static inline static inline
bool AttemptLock(Lock_t *lock) bool AttemptLock(Lock_t *lock)

View File

@ -31,9 +31,7 @@
//------------------------------------------// //------------------------------------------//
// Can't use the macro because panicStr is an array extern volatile char *PanicStr;
static inline char *GetPanicStr(void)
{ return GetCurCPU().panicStr; }
//------------------------------------------// //------------------------------------------//

View File

@ -80,46 +80,35 @@ struct Terminal_t
TermColor_t bgColor; TermColor_t bgColor;
// Defined in driver // Defined in driver
error_t (*ClearTermUnlocked)(Terminal_t *); error_t (*clear)(Terminal_t *);
error_t (*PutOnTermUnlocked)(Terminal_t *, char); error_t (*putchar)(Terminal_t *, char);
error_t (*PrintOnTermUnlocked)(Terminal_t *, const char *);
}; };
//------------------------------------------// //------------------------------------------//
void InitTerms(void); void InitTerms(void);
error_t ClearTerm(Terminal_t *); error_t ClearTerm(Terminal_t *);
error_t PutOnTerm(Terminal_t *, char);
error_t PrintOnTerm(Terminal_t *, const char *);
error_t ChTermColor(Terminal_t *, TermColor_t, TermColor_t); error_t ChTermColor(Terminal_t *, TermColor_t, TermColor_t);
error_t PutOnTerm(Terminal_t *, char);
error_t PutOnTermUnlocked(Terminal_t *, char);
error_t PrintOnTerm(Terminal_t *, const char *);
error_t PrintOnTermUnlocked(Terminal_t *, const char *);
error_t KernLog(const char *, ...); error_t KernLog(const char *, ...);
//------------------------------------------// //------------------------------------------//
extern Terminal_t *stdOut; extern Terminal_t *StdOut;
#define GetStdOut() (stdOut) extern Terminal_t *StdDbg;
#define SetStdOut(x) (stdOut = (x))
// Debug purposes
volatile ushort *vga;
//------------------------------------------// //------------------------------------------//
#ifndef _NO_DEBUG #ifndef _NO_DEBUG
extern Terminal_t *stdDbg;
#define GetStdDbg() (stdDbg)
#define SetStdDbg(x) (stdDbg = (x))
error_t DebugLog(const char *, ...); error_t DebugLog(const char *, ...);
#else // _NO_DEBUG #else // _NO_DEBUG
#define GetStdDbg() NULL
#define SetStdDbg(x) ((void)0)
#define DebugLog(fmt, ...) EOK #define DebugLog(fmt, ...) EOK
#endif #endif
//------------------------------------------// //------------------------------------------//

View File

@ -27,5 +27,6 @@
int cpuCount = 1; int cpuCount = 1;
Processor_t cpuTable[NCPUS] = {0}; Processor_t cpuTable[NCPUS] = {0};
Terminal_t *stdOut = 0, *stdDbg = 0; Terminal_t *StdOut = 0, *StdDbg = 0;
volatile char *PanicStr = 0;

View File

@ -32,14 +32,14 @@ extern Terminal_t VGA_Terminal;
// //
void InitTerms(void) void InitTerms(void)
{ {
KalAssert(!GetStdOut() && !GetStdDbg()); KalAssert(!StdOut && !StdDbg);
VGA_Init(); VGA_Init();
SetStdDbg(&VGA_Terminal); StdDbg = &VGA_Terminal;
SetStdOut(&VGA_Terminal); StdOut = &VGA_Terminal;
ClearTerm(GetStdOut()); ClearTerm(StdOut);
} }
// //
@ -52,8 +52,8 @@ error_t ClearTerm(Terminal_t *term)
if (term == NULL) return EINVAL; if (term == NULL) return EINVAL;
KalAssert(term->initDone == INITOK); KalAssert(term->initDone == INITOK);
AquireLock(&term->lock); AcquireLock(&term->lock);
retcode = term->ClearTermUnlocked(term); retcode = term->clear(term);
ReleaseLock(&term->lock); ReleaseLock(&term->lock);
return retcode; return retcode;
@ -70,7 +70,7 @@ error_t ChTermColor(Terminal_t *term, TermColor_t fgColor, TermColor_t bgColor)
if (term == NULL) if (term == NULL)
return EINVAL; return EINVAL;
AquireLock(&term->lock); AcquireLock(&term->lock);
term->fgColor = fgColor; term->fgColor = fgColor;
term->bgColor = bgColor; term->bgColor = bgColor;
@ -81,39 +81,99 @@ error_t ChTermColor(Terminal_t *term, TermColor_t fgColor, TermColor_t bgColor)
} }
// //
// Writes a single character on the terminal // Writes a single character on the terminal (UNLOCKED version)
//
error_t PutOnTermUnlocked(Terminal_t *term, char ch)
{
uint i;
size_t prevY;
error_t rc = EOK;
if (ch == '\r') {
term->currentX = 0;
return EOK;
}
// Line feed first takes us to the very end of the line
// Later in this function we actually do the line feed
else if (ch == '\n') {
term->currentX = term->width - 1;
}
// Tabulations account for "term->tabSize" spaces
else if (ch == '\t') {
prevY = term->currentX;
for (i = 0; i < term->tabSize; i++) {
// Make sure tabulations can't spread over two lines
if (term->currentX == prevY) {
rc = term->putchar(term, ' ');
if (rc) return rc;
}
}
}
else rc = term->putchar(term, ch);
// Did we reach the end of line?
if (!rc && ++term->currentX == term->width) {
term->currentX = 0;
// Did we reach the buffer's end?
if (++term->currentY == term->height) {
term->currentY = 0;
}
}
return rc;
}
//
// Writes a single character on the terminal (LOCKED version)
// //
error_t PutOnTerm(Terminal_t *term, char ch) error_t PutOnTerm(Terminal_t *term, char ch)
{ {
error_t retcode; error_t rc;
if (term == NULL) return EINVAL; if (term == NULL) return EINVAL;
KalAssert(term->initDone == INITOK); KalAssert(term->initDone == INITOK);
AquireLock(&term->lock); AcquireLock(&term->lock);
retcode = term->PutOnTermUnlocked(term, ch); rc = PutOnTermUnlocked(term, ch);
ReleaseLock(&term->lock); ReleaseLock(&term->lock);
return retcode; return rc;
} }
// //
// Prints string on terminal // Prints string on terminal (UNLOCKED version)
//
error_t PrintOnTermUnlocked(Terminal_t *term, const char *str)
{
error_t rc = EOK;
while (*str && rc == EOK) {
rc = PutOnTermUnlocked(term, *str++);
}
return rc;
}
//
// Prints string on terminal (LOCKED version)
// //
error_t PrintOnTerm(Terminal_t *term, const char *str) error_t PrintOnTerm(Terminal_t *term, const char *str)
{ {
error_t retcode = EOK; error_t rc = EOK;
if (term == NULL) return EINVAL; if (term == NULL) return EINVAL;
KalAssert(term->initDone == INITOK); KalAssert(term->initDone == INITOK);
AquireLock(&term->lock); AcquireLock(&term->lock);
while (*str && retcode == EOK) { rc = PrintOnTermUnlocked(term, str);
retcode = term->PutOnTermUnlocked(term, *str++);
}
ReleaseLock(&term->lock); ReleaseLock(&term->lock);
return retcode; return rc;
} }
// //
@ -130,7 +190,7 @@ error_t KernLog(const char *fmt, ...)
vsnprintf(logbuf, KLOG_MAX_BUFSIZE, fmt, ap); vsnprintf(logbuf, KLOG_MAX_BUFSIZE, fmt, ap);
va_end(ap); va_end(ap);
return PrintOnTerm(GetStdOut(), logbuf); return PrintOnTerm(StdOut, logbuf);
} }
#ifndef _NO_DEBUG #ifndef _NO_DEBUG
@ -148,7 +208,7 @@ error_t DebugLog(const char *fmt, ...)
vsnprintf(logbuf, KLOG_MAX_BUFSIZE, fmt, ap); vsnprintf(logbuf, KLOG_MAX_BUFSIZE, fmt, ap);
va_end(ap); va_end(ap);
return PrintOnTerm(GetStdDbg(), logbuf); return PrintOnTerm(StdDbg, logbuf);
} }
#endif #endif

View File

@ -59,69 +59,15 @@ error_t VGA_ClearTermUnlocked(Terminal_t *term)
// //
error_t VGA_PutOnTermUnlocked(Terminal_t *term, char ch) error_t VGA_PutOnTermUnlocked(Terminal_t *term, char ch)
{ {
uint i; ushort *buffer = (ushort *)term->data;
size_t prevY; const size_t offset = VGA_ComputeOffset(term, term->currentX, term->currentY);
buffer[offset] = VGA_ComputeEntry(ch, VGA_ComputeColorCode(term->fgColor, term->bgColor));
if (ch == '\r') {
term->currentX = 0;
return EOK;
}
// Line feed first takes us to the very end of the line
// Later in this function we actually do the line feed
else if (ch == '\n') {
term->currentX = term->width - 1;
}
// Tabulations account for "term->tabSize" spaces
else if (ch == '\t') {
prevY = term->currentX;
for (i = 0; i < term->tabSize; i++) {
// Make sure tabulations can't spread over two lines
if (term->currentX == prevY) {
VGA_PutOnTermUnlocked(term, ' ');
}
}
}
else {
ushort *buffer = (ushort *)term->data;
const size_t offset = VGA_ComputeOffset(term, term->currentX, term->currentY);
buffer[offset] = VGA_ComputeEntry(ch, VGA_ComputeColorCode(term->fgColor, term->bgColor));
}
// Did we reach the end of line?
if (++term->currentX == term->width) {
term->currentX = 0;
// Did we reach the buffer's end?
if (++term->currentY == term->height) {
// XXX scroll up
term->currentY = 0;
}
}
// Nothing can go wrong
return EOK; return EOK;
} }
//
// Prints string on terminal
//
error_t VGA_PrintOnTermUnlocked(Terminal_t *term, const char *str)
{
error_t retcode = EOK;
while (*str && retcode == EOK) {
retcode = term->PutOnTermUnlocked(term, *str++);
}
return retcode;
}
// //
// VGA output // VGA output
// XXX custom sizes
// //
Terminal_t VGA_Terminal = { Terminal_t VGA_Terminal = {
.initDone = FALSE, .initDone = FALSE,
@ -140,9 +86,8 @@ Terminal_t VGA_Terminal = {
.fgColor = KTERM_COLOR_LGREY, .fgColor = KTERM_COLOR_LGREY,
.bgColor = KTERM_COLOR_BLACK, .bgColor = KTERM_COLOR_BLACK,
.ClearTermUnlocked = VGA_ClearTermUnlocked, .clear = VGA_ClearTermUnlocked,
.PutOnTermUnlocked = VGA_PutOnTermUnlocked, .putchar = VGA_PutOnTermUnlocked,
.PrintOnTermUnlocked = VGA_PrintOnTermUnlocked,
}; };

View File

@ -37,7 +37,7 @@ noreturn void __assert_handler(const char *msg,
(void)file; (void)line; (void)func; (void)file; (void)line; (void)func;
StartPanic("cpu%d: In function '%s', from %s line %d - assert() failed: '%s'", StartPanic("cpu%d: In function '%s', from %s line %d - assertion failed: '%s'",
_GetCurCPU(), func, file, line, msg); _GetCurCPU(), func, file, line, msg);
} }
@ -52,25 +52,23 @@ noreturn void StartPanic(const char *fmt, ...)
DisableIRQs(); DisableIRQs();
if (GetCurProc()) _SetCurProc(NULL); if (GetCurProc()) _SetCurProc(NULL);
if (GetStdOut() == NULL) CrashSystem(); if (StdOut == NULL) CrashSystem();
GetStdOut()->ClearTermUnlocked(GetStdOut());
if (fmt == NULL) { if (fmt == NULL) {
fmt = "(no message given)"; fmt = "(no message given)";
} }
if (*GetPanicStr()) { if (PanicStr[0] != 0) {
GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "\nDouble panic!"); PrintOnTermUnlocked(StdOut, "\nDouble panic!");
HaltCPU(); HaltCPU();
} }
va_start(ap, fmt); va_start(ap, fmt);
vsnprintf(GetPanicStr(), PANICSTR_SIZE, fmt, ap); vsnprintf(PanicStr, PANICSTR_SIZE, fmt, ap);
va_end(ap); va_end(ap);
GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "\nPanic!\n\n"); PrintOnTermUnlocked(StdOut, "\nPanic!\n\n");
GetStdOut()->PrintOnTermUnlocked(GetStdOut(), GetPanicStr()); PrintOnTermUnlocked(StdOut, PanicStr);
HaltCPU(); HaltCPU();
} }

View File

@ -47,11 +47,11 @@ void InitHeap(void)
} }
// //
// Aquires control of the heap's lock // Acquires control of the heap's lock
// //
void LockHeap(void) void LockHeap(void)
{ {
AquireLock(&_heap_lock); AcquireLock(&_heap_lock);
} }
// //

View File

@ -46,7 +46,7 @@ error_t KalAllocMemory(void **ptr, size_t req, int flags, size_t align)
UnlockHeap(); UnlockHeap();
if (rc) { if (rc) {
if ((flags & M_CANFAIL) == 0) if ((flags & M_CANFAIL) != 0)
return rc; return rc;
StartPanic("Out of memory"); StartPanic("Out of memory");
} }