Style update

This commit is contained in:
Julian Barathieu 2019-05-14 11:48:07 +02:00
parent 0dea84d86d
commit 1e200eea25
15 changed files with 286 additions and 282 deletions

View File

@ -99,7 +99,7 @@ KernSources = kernel/cpu/cpuid.c \
kernel/mm/heap.c kernel/mm/malloc.c \ kernel/mm/heap.c kernel/mm/malloc.c \
kernel/mm/gdt.c kernel/ps/sched.c \ kernel/mm/gdt.c kernel/ps/sched.c \
kernel/init/info.c kernel/init/ssp.c \ kernel/init/info.c kernel/init/ssp.c \
kernel/io/rtc.c kernel/io/keyb.c \ kernel/ke/rtc.c kernel/io/keyb.c \
kernel/io/spkr.c kernel/po/shtdwn.c \ kernel/io/spkr.c kernel/po/shtdwn.c \
kernel/sh/shell.c kernel/sh/shcmds.c kernel/sh/shell.c kernel/sh/shcmds.c

View File

@ -61,9 +61,9 @@ static inline ulong KePauseIRQs(void) {
return flags; return flags;
} }
extern void IoSendEOItoPIC(uchar isr); extern void KeSendEOItoPIC(uchar isr);
extern void IoEnableNMI(void); extern void KeEnableNMI(void);
extern void IoDisableNMI(void); extern void KeDisableNMI(void);
// //
// Restore IRQ flag to its state before KePauseIRQs // Restore IRQ flag to its state before KePauseIRQs

View File

@ -65,22 +65,14 @@ struct ISRList_t
} entry[255]; } entry[255];
}; };
typedef struct
{
} __attribute__((__packed__)) cpu_state_t;
extern char *IsrExceptions[32];
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
void IdtInit(void); void KeLoadIDT(void);
void IdtSetup(void); void KeSetupIDT(void);
void IoSendEOItoPIC(uchar isr); void KeSendEOItoPIC(uchar isr);
void IdtEarlyExceptionHandler(ISRFrame_t *regs); void KeSetIDTGate(uchar rank, ulong base, ushort selector, uchar flags);
void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags); error_t KeRegisterISR(void (*isr)(ISRFrame_t *regs), uchar isrNo);
error_t IdtRegisterIsr(void (*isr)(ISRFrame_t *regs), uchar isrNo);
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//

View File

@ -26,12 +26,12 @@
#include <kernel.h> #include <kernel.h>
#endif #endif
#ifndef _KALKERN_TIME_H #ifndef _KE_TIME_H
#define _KALKERN_TIME_H #define _KE_TIME_H
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
typedef struct struct Time_t
{ {
uchar sec; uchar sec;
uchar min; uchar min;
@ -41,16 +41,18 @@ typedef struct
uchar month; uchar month;
uchar year; uchar year;
uchar century; uchar century;
} __attribute__((packed)) Time_t; } __attribute__((packed));
void KeSetupRTC(void);
void KeEnableRTC(void);
ulong KeGetTimeStamp(void);
ulong KeGetClockTicks(void);
void KeDelayExecution(uint);
Time_t *KeGetCurTime(void);
char *KeFormatCurTime(void);
extern void IoSetupRtc(void);
extern void IoEnableRtc(void);
extern void IoPrintRtcTime(void);
extern ulong IoGetRtcTicks(void);
extern Time_t* IoGetRtcTime(void);
extern char* IoGetRtcTimeChar(void);
extern void IoRtcWait(uint time); // time in ms
//static char* WeekDays[7] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//

View File

@ -36,6 +36,7 @@ typedef volatile ulong Spinlock_t;
typedef Spinlock_t Lock_t; typedef Spinlock_t Lock_t;
//typedef struct Lock_t Lock_t; //typedef struct Lock_t Lock_t;
typedef struct Time_t Time_t;
typedef struct Buffer_t Buffer_t; typedef struct Buffer_t Buffer_t;
typedef struct ListHead_t ListHead_t; typedef struct ListHead_t ListHead_t;
typedef struct ListNode_t ListNode_t; typedef struct ListNode_t ListNode_t;
@ -124,8 +125,6 @@ struct ISRFrame_t {
ulong ss; ulong ss;
} __attribute__((__packed__)); } __attribute__((__packed__));
error_t IdtRegisterIsr(void (*isr)(ISRFrame_t *regs), uchar isrNo);
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
#ifndef NCPUS #ifndef NCPUS

View File

@ -27,11 +27,11 @@
#include <ke/idt.h> #include <ke/idt.h>
IdtEntry_t idt[256] = { 0 }; IdtEntry_t idt[256] = { 0 };
IdtPtr_t idtPtr; IdtPtr_t _KeIdtPtr;
ISRList_t isrList = { 0 }; static ISRList_t isrList = { 0 };
char *ExceptionsChar[32] = { static char *ExceptionsChar[32] = {
"Divide Error Fault", "Divide Error Fault",
"Debug Exception Trap", "Debug Exception Trap",
"Non-maskable Interrupt", "Non-maskable Interrupt",
@ -67,13 +67,14 @@ char *ExceptionsChar[32] = {
}; };
static void EnablePIC(void); static void EnablePIC(void);
static void EarlyExceptionHandler(ISRFrame_t *regs);
#define interrupt(n) asm volatile ("int %0" : : "N" (n) : "cc", "memory") #define interrupt(n) asm volatile ("int %0" : : "N" (n) : "cc", "memory")
// //
// Registers an isr with his IRQ to handle driver interrupts // Registers an isr with his IRQ to handle driver interrupts
// //
error_t IdtRegisterIsr(void (*isr)(ISRFrame_t *regs), uchar isrNo) error_t KeRegisterISR(void (*isr)(ISRFrame_t *regs), uchar isrNo)
{ {
uchar n = isrList.n; uchar n = isrList.n;
int OverWriting = 0; int OverWriting = 0;
@ -104,7 +105,7 @@ settingUp:
// //
// Installs the IDT in order to activate the interrupts handling // Installs the IDT in order to activate the interrupts handling
// //
void IdtSetup(void) void KeSetupIDT(void)
{ {
// XXX detect the APIC with cpuid ! // XXX detect the APIC with cpuid !
EnablePIC(); EnablePIC();
@ -112,75 +113,75 @@ void IdtSetup(void)
ushort codeSeg = (ushort)(ulong)BtLoaderInfo.codeSegment; ushort codeSeg = (ushort)(ulong)BtLoaderInfo.codeSegment;
// Set IDT ptr // Set IDT ptr
idtPtr.limit = (sizeof(IdtEntry_t) * 256) - 1; _KeIdtPtr.limit = (sizeof(IdtEntry_t) * 256) - 1;
idtPtr.base = &idt; _KeIdtPtr.base = &idt;
// Set IDT Exception Gates // Set IDT Exception Gates
IdtSetGate(0x00, (ulong)isr0, codeSeg, 0x8E); KeSetIDTGate(0x00, (ulong)isr0, codeSeg, 0x8E);
IdtSetGate(0x01, (ulong)isr1, codeSeg, 0x8E); KeSetIDTGate(0x01, (ulong)isr1, codeSeg, 0x8E);
IdtSetGate(0x02, (ulong)isr2, codeSeg, 0x8E); KeSetIDTGate(0x02, (ulong)isr2, codeSeg, 0x8E);
IdtSetGate(0x03, (ulong)isr3, codeSeg, 0x8E); KeSetIDTGate(0x03, (ulong)isr3, codeSeg, 0x8E);
IdtSetGate(0x04, (ulong)isr4, codeSeg, 0x8E); KeSetIDTGate(0x04, (ulong)isr4, codeSeg, 0x8E);
IdtSetGate(0x05, (ulong)isr5, codeSeg, 0x8E); KeSetIDTGate(0x05, (ulong)isr5, codeSeg, 0x8E);
IdtSetGate(0x06, (ulong)isr6, codeSeg, 0x8E); KeSetIDTGate(0x06, (ulong)isr6, codeSeg, 0x8E);
IdtSetGate(0x07, (ulong)isr7, codeSeg, 0x8E); KeSetIDTGate(0x07, (ulong)isr7, codeSeg, 0x8E);
IdtSetGate(0x08, (ulong)isr8, codeSeg, 0x8E); KeSetIDTGate(0x08, (ulong)isr8, codeSeg, 0x8E);
IdtSetGate(0x09, (ulong)isr9, codeSeg, 0x8E); KeSetIDTGate(0x09, (ulong)isr9, codeSeg, 0x8E);
IdtSetGate(0x0A, (ulong)isr10, codeSeg, 0x8E); KeSetIDTGate(0x0A, (ulong)isr10, codeSeg, 0x8E);
IdtSetGate(0x0B, (ulong)isr11, codeSeg, 0x8E); KeSetIDTGate(0x0B, (ulong)isr11, codeSeg, 0x8E);
IdtSetGate(0x0C, (ulong)isr12, codeSeg, 0x8E); KeSetIDTGate(0x0C, (ulong)isr12, codeSeg, 0x8E);
IdtSetGate(0x0D, (ulong)isr13, codeSeg, 0x8E); KeSetIDTGate(0x0D, (ulong)isr13, codeSeg, 0x8E);
IdtSetGate(0x0E, (ulong)isr14, codeSeg, 0x8E); KeSetIDTGate(0x0E, (ulong)isr14, codeSeg, 0x8E);
IdtSetGate(0x0F, (ulong)isr15, codeSeg, 0x8E); // INTEL RESERVED KeSetIDTGate(0x0F, (ulong)isr15, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(0x10, (ulong)isr16, codeSeg, 0x8E); KeSetIDTGate(0x10, (ulong)isr16, codeSeg, 0x8E);
IdtSetGate(0x11, (ulong)isr17, codeSeg, 0x8E); KeSetIDTGate(0x11, (ulong)isr17, codeSeg, 0x8E);
IdtSetGate(0x12, (ulong)isr18, codeSeg, 0x8E); KeSetIDTGate(0x12, (ulong)isr18, codeSeg, 0x8E);
IdtSetGate(0x13, (ulong)isr19, codeSeg, 0x8E); KeSetIDTGate(0x13, (ulong)isr19, codeSeg, 0x8E);
IdtSetGate(0x14, (ulong)isr20, codeSeg, 0x8E); KeSetIDTGate(0x14, (ulong)isr20, codeSeg, 0x8E);
IdtSetGate(0x15, (ulong)isr21, codeSeg, 0x8E); // INTEL RESERVED KeSetIDTGate(0x15, (ulong)isr21, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(0x16, (ulong)isr22, codeSeg, 0x8E); // INTEL RESERVED KeSetIDTGate(0x16, (ulong)isr22, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(0x17, (ulong)isr23, codeSeg, 0x8E); // INTEL RESERVED KeSetIDTGate(0x17, (ulong)isr23, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(0x18, (ulong)isr24, codeSeg, 0x8E); // INTEL RESERVED KeSetIDTGate(0x18, (ulong)isr24, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(0x19, (ulong)isr25, codeSeg, 0x8E); // INTEL RESERVED KeSetIDTGate(0x19, (ulong)isr25, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(0x1A, (ulong)isr26, codeSeg, 0x8E); // INTEL RESERVED KeSetIDTGate(0x1A, (ulong)isr26, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(0x1B, (ulong)isr27, codeSeg, 0x8E); // INTEL RESERVED KeSetIDTGate(0x1B, (ulong)isr27, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(0x1C, (ulong)isr28, codeSeg, 0x8E); // INTEL RESERVED KeSetIDTGate(0x1C, (ulong)isr28, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(0x1D, (ulong)isr29, codeSeg, 0x8E); // INTEL RESERVED KeSetIDTGate(0x1D, (ulong)isr29, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(0x1E, (ulong)isr30, codeSeg, 0x8E); // INTEL RESERVED KeSetIDTGate(0x1E, (ulong)isr30, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(0x1F, (ulong)isr31, codeSeg, 0x8E); // INTEL RESERVED KeSetIDTGate(0x1F, (ulong)isr31, codeSeg, 0x8E); // INTEL RESERVED
// Set IDT IRQs Gates // Set IDT IRQs Gates
IdtSetGate(0x20, (ulong)isr32, codeSeg, 0x8E); KeSetIDTGate(0x20, (ulong)isr32, codeSeg, 0x8E);
IdtSetGate(0x21, (ulong)isr33, codeSeg, 0x8E); KeSetIDTGate(0x21, (ulong)isr33, codeSeg, 0x8E);
IdtSetGate(0x22, (ulong)isr34, codeSeg, 0x8E); KeSetIDTGate(0x22, (ulong)isr34, codeSeg, 0x8E);
IdtSetGate(0x23, (ulong)isr35, codeSeg, 0x8E); KeSetIDTGate(0x23, (ulong)isr35, codeSeg, 0x8E);
IdtSetGate(0x24, (ulong)isr36, codeSeg, 0x8E); KeSetIDTGate(0x24, (ulong)isr36, codeSeg, 0x8E);
IdtSetGate(0x25, (ulong)isr37, codeSeg, 0x8E); KeSetIDTGate(0x25, (ulong)isr37, codeSeg, 0x8E);
IdtSetGate(0x26, (ulong)isr38, codeSeg, 0x8E); KeSetIDTGate(0x26, (ulong)isr38, codeSeg, 0x8E);
IdtSetGate(0x27, (ulong)isr39, codeSeg, 0x8E); KeSetIDTGate(0x27, (ulong)isr39, codeSeg, 0x8E);
IdtSetGate(0x28, (ulong)isr40, codeSeg, 0x8E); KeSetIDTGate(0x28, (ulong)isr40, codeSeg, 0x8E);
IdtSetGate(0x29, (ulong)isr41, codeSeg, 0x8E); KeSetIDTGate(0x29, (ulong)isr41, codeSeg, 0x8E);
IdtSetGate(0x2A, (ulong)isr42, codeSeg, 0x8E); KeSetIDTGate(0x2A, (ulong)isr42, codeSeg, 0x8E);
IdtSetGate(0x2B, (ulong)isr43, codeSeg, 0x8E); KeSetIDTGate(0x2B, (ulong)isr43, codeSeg, 0x8E);
IdtSetGate(0x2C, (ulong)isr44, codeSeg, 0x8E); KeSetIDTGate(0x2C, (ulong)isr44, codeSeg, 0x8E);
IdtSetGate(0x2D, (ulong)isr45, codeSeg, 0x8E); KeSetIDTGate(0x2D, (ulong)isr45, codeSeg, 0x8E);
IdtSetGate(0x2E, (ulong)isr46, codeSeg, 0x8E); KeSetIDTGate(0x2E, (ulong)isr46, codeSeg, 0x8E);
IdtSetGate(0x2F, (ulong)isr47, codeSeg, 0x8E); KeSetIDTGate(0x2F, (ulong)isr47, codeSeg, 0x8E);
//Setup Early Exception handler //Setup Early Exception handler
for (uchar i = 0 ; i < 0x20 ; i++) { for (uchar i = 0 ; i < 0x20 ; i++) {
IdtRegisterIsr(IdtEarlyExceptionHandler, i); KeRegisterISR(EarlyExceptionHandler, i);
} }
// Load IDT // Load IDT
IdtInit(); KeLoadIDT();
DebugLog("[IdtSetup] Initialized !\n"); DebugLog("[IdtSetup] Initialized !\n");
} }
// //
// Set an interrupt gate // Set an interrupt gate
// //
void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags) void KeSetIDTGate(uchar rank, ulong base, ushort selector, uchar flags)
{ {
// Set Base Address // Set Base Address
idt[rank].baseLow = base & 0xFFFF; idt[rank].baseLow = base & 0xFFFF;
@ -204,15 +205,19 @@ static void EnablePIC(void)
// Set ICW1 - begin init of the PIC // Set ICW1 - begin init of the PIC
IoWriteByteOnPort(0x20, 0x11); IoWriteByteOnPort(0x20, 0x11);
IoWriteByteOnPort(0xa0, 0x11); IoWriteByteOnPort(0xa0, 0x11);
// Set ICW2 (IRQ base offsets) // Set ICW2 (IRQ base offsets)
IoWriteByteOnPort(0x21, 0x20); //0x20 is the first free interrupt for IRQ0 IoWriteByteOnPort(0x21, 0x20); //0x20 is the first free interrupt for IRQ0
IoWriteByteOnPort(0xa1, 0x28); // PIC2 is offseted to 0x28 IoWriteByteOnPort(0xa1, 0x28); // PIC2 is offseted to 0x28
// Set ICW3 // Set ICW3
IoWriteByteOnPort(0x21, 0x4); IoWriteByteOnPort(0x21, 0x4);
IoWriteByteOnPort(0xa1, 0x2); IoWriteByteOnPort(0xa1, 0x2);
// Set ICW4 // Set ICW4
IoWriteByteOnPort(0x21, 0x1); IoWriteByteOnPort(0x21, 0x1);
IoWriteByteOnPort(0xa1, 0x1); IoWriteByteOnPort(0xa1, 0x1);
// Set OCW1 (interrupt masks) // Set OCW1 (interrupt masks)
IoWriteByteOnPort(0x21, 0xff); IoWriteByteOnPort(0x21, 0xff);
IoWriteByteOnPort(0xa1, 0xff); IoWriteByteOnPort(0xa1, 0xff);
@ -221,7 +226,7 @@ static void EnablePIC(void)
// //
// Ends the current interrupt handling // Ends the current interrupt handling
// //
void IoSendEOItoPIC(uchar isr) void KeSendEOItoPIC(uchar isr)
{ {
if(isr >= 8) if(isr >= 8)
IoWriteByteOnPort(0xa0,0x20); IoWriteByteOnPort(0xa0,0x20);
@ -229,12 +234,12 @@ void IoSendEOItoPIC(uchar isr)
IoWriteByteOnPort(0x20,0x20); IoWriteByteOnPort(0x20,0x20);
} }
void IoEnableNMI(void) void KeEnableNMI(void)
{ {
IoWriteByteOnPort(0x70, IoReadByteFromPort(0x70) & 0x7F); IoWriteByteOnPort(0x70, IoReadByteFromPort(0x70) & 0x7F);
} }
void IoDisableNMI(void) void KeDisableNMI(void)
{ {
IoWriteByteOnPort(0x70, IoReadByteFromPort(0x70) | 0x80); IoWriteByteOnPort(0x70, IoReadByteFromPort(0x70) | 0x80);
} }
@ -242,13 +247,14 @@ void IoDisableNMI(void)
// //
// The main ISR handler // The main ISR handler
// //
void IsrHandler(ISRFrame_t *regs) void _KeHandleISR(ISRFrame_t *regs)
{ {
if ((!regs) || (!regs->rip)) if ((!regs) || (!regs->rip))
KeStartPanic("[ISR ?] Unknown ISR Exception Abort\n"); KeStartPanic("[ISR ?] Unknown ISR Exception Abort\n");
if ((regs->intNo >= 0x15) && (regs->intNo <= 0x1F)) if ((regs->intNo >= 0x15) && (regs->intNo <= 0x1F))
return; // INTEL RESERVED return; // INTEL RESERVED
if (regs->intNo == 0x0F) if (regs->intNo == 0x0F)
return; // INTEL RESERVED return; // INTEL RESERVED
@ -261,14 +267,13 @@ void IsrHandler(ISRFrame_t *regs)
bprintf(BStdOut, "[ISR 0x%x] %s\n", regs->intNo, "Unknown ISR Exception"); bprintf(BStdOut, "[ISR 0x%x] %s\n", regs->intNo, "Unknown ISR Exception");
BStdOut->flusher(BStdOut); BStdOut->flusher(BStdOut);
IoSendEOItoPIC(regs->intNo); KeSendEOItoPIC(regs->intNo);
} }
// //
// Early CPU Exception handler // Early CPU Exception handler
// //
void IdtEarlyExceptionHandler(ISRFrame_t *regs) static void EarlyExceptionHandler(ISRFrame_t *regs)
{ {
int recoverable = 0; int recoverable = 0;
@ -309,7 +314,8 @@ void IdtEarlyExceptionHandler(ISRFrame_t *regs)
); );
} else { } else {
bprintf(BStdOut, "[ISR 0x%x] %s\n", regs->intNo, ExceptionsChar[regs->intNo]); bprintf(BStdOut, "[ISR %#x] %s\n",
regs->intNo, ExceptionsChar[regs->intNo]);
BStdOut->flusher(BStdOut); BStdOut->flusher(BStdOut);
} }
} }

View File

@ -26,27 +26,23 @@
%include "kaleid/kernel/cpu/cpuf.inc" %include "kaleid/kernel/cpu/cpuf.inc"
global IdtInit global KeLoadIDT
global divideByZero global divideByZero
extern idtPtr
extern IsrHandler extern _KeIdtPtr
extern label0 extern _KeHandleISR
extern KernLog
;; ;;
;; Loads the IDT ;; Loads the IDT
;; ;;
IdtInit: KeLoadIDT:
lidt [idtPtr] lidt [_KeIdtPtr]
ret ret
;; ;;
;; Bug test ;; Bug test
;; ;;
chain db "Salut", 0x0A, 0
divideByZero: divideByZero:
mov rdi, chain
call KernLog
ret ret
;; ;;
@ -71,7 +67,7 @@ isrPreHandler:
mov rdi, rsp ; First argument points to the processor state mov rdi, rsp ; First argument points to the processor state
mov rbp, 0 ; Terminate stack traces here mov rbp, 0 ; Terminate stack traces here
call IsrHandler call _KeHandleISR
; decrement mask count ; decrement mask count
dec qword [gs:8] dec qword [gs:8]

View File

@ -48,19 +48,16 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg)
MmInitMemoryMap(); MmInitMemoryMap();
// Interrupts launching // Interrupts launching
IdtSetup(); KeSetupIDT();
KeEnableIRQs(); KeEnableIRQs();
// Several inits // Several inits
MmInitHeap(); MmInitHeap();
// Start drivers // Start drivers
IoEnableRtc(); KeEnableRTC();
IoEnableKeyb(); IoEnableKeyb();
IoGetRtcTimeChar();
IoPrintRtcTime();
KeStartShell(); KeStartShell();
PoShutdown(); PoShutdown();

View File

@ -22,14 +22,16 @@
// along with OS/K. If not, see <https://www.gnu.org/licenses/>. // // along with OS/K. If not, see <https://www.gnu.org/licenses/>. //
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
#include <lib/buf.h>
#include <io/cursor.h>
#include <init/mboot.h> #include <init/mboot.h>
#include <lib/buf.h>
#include <ke/time.h>
#include <ke/idt.h>
#include <io/spkr.h>
#include <io/keyb.h>
#include <io/cursor.h>
#include <po/shtdwn.h>
#include <mm/heap.h> #include <mm/heap.h>
#include <mm/mm.h> #include <mm/mm.h>
#include <ke/time.h>
#include <io/spkr.h>
#include <po/shtdwn.h>
// info.c // info.c
extern void BtDoSanityChecks(uint mbMagic); extern void BtDoSanityChecks(uint mbMagic);
@ -41,12 +43,6 @@ extern error_t IoInitVGABuffer(void);
// ke/shell.c // ke/shell.c
extern void KeStartShell(void); extern void KeStartShell(void);
// io/keyb.c
extern void IoEnableKeyb(void);
// cpu/idt.c
extern void IdtSetup(void);
// ps/proc.c test function // ps/proc.c test function
extern void pstest(void); extern void pstest(void);

View File

@ -24,6 +24,7 @@
#include <lib/buf.h> #include <lib/buf.h>
#include <io/keyb.h> #include <io/keyb.h>
#include <ke/idt.h>
static char EarlyScanCodes[100] = { 0 }; static char EarlyScanCodes[100] = { 0 };
static char Invisible[100] = { 0 }; static char Invisible[100] = { 0 };
@ -119,7 +120,7 @@ void ScanCodesInit(void)
Invisible[0x4D] = 1; Invisible[0x4D] = 1;
} }
void KeybHandler(ISRFrame_t *regs) static void KeybHandler(ISRFrame_t *regs)
{ {
char status; char status;
char code = 0; char code = 0;
@ -135,7 +136,7 @@ void KeybHandler(ISRFrame_t *regs)
if(code < 0) code = 0; if(code < 0) code = 0;
} }
KeybPrint((int)code); KeybPrint((int)code);
IoSendEOItoPIC(0x21); KeSendEOItoPIC(0x21);
} }
void IoCreateInputBuffer(void) void IoCreateInputBuffer(void)
@ -154,13 +155,13 @@ void IoEnableKeyb(void)
{ {
ulong flags = KePauseIRQs(); ulong flags = KePauseIRQs();
IdtRegisterIsr(KeybHandler, 0x21); KeRegisterISR(KeybHandler, 0x21);
char readedInterruptConfig = IoReadByteFromPort(0x21); char readedInterruptConfig = IoReadByteFromPort(0x21);
IoWriteByteOnPort(0x21, 0xFD & readedInterruptConfig); IoWriteByteOnPort(0x21, 0xFD & readedInterruptConfig);
KeRestoreIRQs(flags); KeRestoreIRQs(flags);
IoEnableNMI(); KeEnableNMI();
ScanCodesInit(); ScanCodesInit();
IoCreateInputBuffer(); IoCreateInputBuffer();

View File

@ -49,24 +49,16 @@ void IoQuietSpeaker(void)
void IoDoBeep(void) void IoDoBeep(void)
{ {
IoStartSpeaker(1000); IoStartSpeaker(1000);
KeDelayExecution(100);
IoRtcWait(100);
IoQuietSpeaker(); IoQuietSpeaker();
} }
void IoDoTone(uint tone, uint time) void IoDoTone(uint tone, uint time)
{ {
IoStartSpeaker(tone); IoStartSpeaker(tone);
KeDelayExecution(time);
IoRtcWait(time);
IoQuietSpeaker(); IoQuietSpeaker();
} }
void IoDoStarWars(void) void IoDoStarWars(void)

View File

@ -24,145 +24,162 @@
#include <lib/buf.h> #include <lib/buf.h>
#include <ke/time.h> #include <ke/time.h>
#include <ke/idt.h>
static ulong IoRtcTicks = 0; static ulong Ticks = 0;
static char IoTimeChar[22] = { 0 }; static Time_t OriginTime;
static uchar RtcRate = 0x05; //2048Hz static Time_t CurTime;
static Time_t IoRtcOriginTime;
static Time_t IoRtcTime; // TODO asnprintf()
static char TimeFmtBuf[22] = { 0 };
static uchar RTC_RATE = 0x05; //2048Hz
static char time24or12Mode; static char time24or12Mode;
static void GetTimeFromRtc(void) static void GetTimeFromRTC(void)
{ {
Time_t lastTime; Time_t lastTime;
char updateInProgress = 1; char updateInProgress = 1;
while(updateInProgress) { // wait while the RTC updates its value // Wait while the RTC updates its value
while (updateInProgress) {
IoWriteByteOnPort(0x70, 0x0A); IoWriteByteOnPort(0x70, 0x0A);
updateInProgress = (IoReadByteFromPort(0x71) & 0x80); updateInProgress = (IoReadByteFromPort(0x71) & 0x80);
} }
IoWriteByteOnPort(0x70, 0x0); IoWriteByteOnPort(0x70, 0x0);
IoRtcOriginTime.sec = IoReadByteFromPort(0x71); OriginTime.sec = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x02); IoWriteByteOnPort(0x70, 0x02);
IoRtcOriginTime.min = IoReadByteFromPort(0x71); OriginTime.min = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x04); IoWriteByteOnPort(0x70, 0x04);
IoRtcOriginTime.hour = IoReadByteFromPort(0x71); OriginTime.hour = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x06); IoWriteByteOnPort(0x70, 0x06);
IoRtcOriginTime.weekday = IoReadByteFromPort(0x71); OriginTime.weekday = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x07); IoWriteByteOnPort(0x70, 0x07);
IoRtcOriginTime.day = IoReadByteFromPort(0x71); OriginTime.day = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x08); IoWriteByteOnPort(0x70, 0x08);
IoRtcOriginTime.month = IoReadByteFromPort(0x71); OriginTime.month = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x09); IoWriteByteOnPort(0x70, 0x09);
IoRtcOriginTime.year = IoReadByteFromPort(0x71); OriginTime.year = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x32); IoWriteByteOnPort(0x70, 0x32);
IoRtcOriginTime.century = IoReadByteFromPort(0x71); OriginTime.century = IoReadByteFromPort(0x71);
// Now while we don't get the same value, read the registers (ensure data are valid) // Now while we don't get the same value, read the registers (ensure data are valid)
do { do {
lastTime.sec = IoRtcOriginTime.sec; lastTime.sec = OriginTime.sec;
lastTime.min = IoRtcOriginTime.min; lastTime.min = OriginTime.min;
lastTime.hour = IoRtcOriginTime.hour; lastTime.hour = OriginTime.hour;
lastTime.weekday = IoRtcOriginTime.weekday; lastTime.weekday = OriginTime.weekday;
lastTime.day = IoRtcOriginTime.day; lastTime.day = OriginTime.day;
lastTime.month = IoRtcOriginTime.month; lastTime.month = OriginTime.month;
lastTime.year = IoRtcOriginTime.year; lastTime.year = OriginTime.year;
lastTime.century = IoRtcOriginTime.century; lastTime.century = OriginTime.century;
while(updateInProgress) { // wait while the RTC updates its value while (updateInProgress) {
IoWriteByteOnPort(0x70, 0x0A); IoWriteByteOnPort(0x70, 0x0A);
updateInProgress = (IoReadByteFromPort(0x71) & 0x80); updateInProgress = (IoReadByteFromPort(0x71) & 0x80);
} }
IoWriteByteOnPort(0x70, 0x0); IoWriteByteOnPort(0x70, 0x0);
IoRtcOriginTime.sec = IoReadByteFromPort(0x71); OriginTime.sec = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x02);
IoRtcOriginTime.min = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x04);
IoRtcOriginTime.hour = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x06);
IoRtcOriginTime.weekday = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x07);
IoRtcOriginTime.day = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x08);
IoRtcOriginTime.month = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x09);
IoRtcOriginTime.year = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x32);
IoRtcOriginTime.century = IoReadByteFromPort(0x71);
} while ( (lastTime.sec != IoRtcOriginTime.sec) || (lastTime.min != IoRtcOriginTime.min) || IoWriteByteOnPort(0x70, 0x02);
(lastTime.hour != IoRtcOriginTime.hour) || (lastTime.weekday != IoRtcOriginTime.weekday) || OriginTime.min = IoReadByteFromPort(0x71);
(lastTime.day != IoRtcOriginTime.day) || (lastTime.month != IoRtcOriginTime.month) ||
(lastTime.year != IoRtcOriginTime.year) || (lastTime.century != IoRtcOriginTime.century) IoWriteByteOnPort(0x70, 0x04);
OriginTime.hour = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x06);
OriginTime.weekday = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x07);
OriginTime.day = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x08);
OriginTime.month = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x09);
OriginTime.year = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x32);
OriginTime.century = IoReadByteFromPort(0x71);
} while ((lastTime.sec != OriginTime.sec)
|| (lastTime.min != OriginTime.min)
|| (lastTime.hour != OriginTime.hour)
|| (lastTime.weekday != OriginTime.weekday)
|| (lastTime.day != OriginTime.day)
|| (lastTime.month != OriginTime.month)
|| (lastTime.year != OriginTime.year)
|| (lastTime.century != OriginTime.century)
); );
IoWriteByteOnPort(0x70, 0x0B); IoWriteByteOnPort(0x70, 0x0B);
time24or12Mode = IoReadByteFromPort(0x71); time24or12Mode = IoReadByteFromPort(0x71);
// Convert to binary if it is necessary // Convert to binary if it is necessary
if (!(time24or12Mode & 0x04)) { if (!(time24or12Mode & 0x04)) {
IoRtcOriginTime.sec = (IoRtcOriginTime.sec & 0x0F) OriginTime.sec = (OriginTime.sec & 0x0F)
+ ((IoRtcOriginTime.sec / 16) * 10); + ((OriginTime.sec / 16) * 10);
IoRtcOriginTime.min = (IoRtcOriginTime.min & 0x0F)
+ ((IoRtcOriginTime.min / 16) * 10); OriginTime.min = (OriginTime.min & 0x0F)
IoRtcOriginTime.hour = ( (IoRtcOriginTime.hour & 0x0F) + ((OriginTime.min / 16) * 10);
+ (((IoRtcOriginTime.hour & 0x70) / 16) * 10) )
| (IoRtcOriginTime.hour & 0x80); OriginTime.hour = ( (OriginTime.hour & 0x0F)
IoRtcOriginTime.day = (IoRtcOriginTime.day & 0x0F) + ((IoRtcOriginTime.day / 16) * 10); + (((OriginTime.hour & 0x70) / 16) * 10) )
IoRtcOriginTime.month = (IoRtcOriginTime.month & 0x0F) | (OriginTime.hour & 0x80);
+ ((IoRtcOriginTime.month / 16) * 10);
IoRtcOriginTime.year = (IoRtcOriginTime.year & 0x0F) OriginTime.day = (OriginTime.day & 0x0F)
+ ((IoRtcOriginTime.year / 16) * 10); + ((OriginTime.day / 16) * 10);
IoRtcOriginTime.century = (IoRtcOriginTime.century & 0x0F)
+ ((IoRtcOriginTime.century / 16) * 10); OriginTime.month = (OriginTime.month & 0x0F)
IoRtcOriginTime.weekday = (IoRtcOriginTime.weekday & 0x0F) + ((OriginTime.month / 16) * 10);
+ ((IoRtcOriginTime.weekday / 16) * 10);
OriginTime.year = (OriginTime.year & 0x0F)
+ ((OriginTime.year / 16) * 10);
OriginTime.century = (OriginTime.century & 0x0F)
+ ((OriginTime.century / 16) * 10);
OriginTime.weekday = (OriginTime.weekday & 0x0F)
+ ((OriginTime.weekday / 16) * 10);
} }
// Convert 12 to 24 hour if necessary // Convert 12 to 24 hour if necessary
if (!(time24or12Mode & 0x02) && (IoRtcOriginTime.hour & 0x80)) { if (!(time24or12Mode & 0x02) && (OriginTime.hour & 0x80)) {
IoRtcOriginTime.hour = ((IoRtcOriginTime.hour & 0x7)+ 10) % 24; OriginTime.hour = ((OriginTime.hour & 0x7)+ 10) % 24;
} }
IoRtcTime.sec = IoRtcOriginTime.sec; CurTime.sec = OriginTime.sec;
IoRtcTime.min = IoRtcOriginTime.min; CurTime.min = OriginTime.min;
IoRtcTime.hour = IoRtcOriginTime.hour; CurTime.hour = OriginTime.hour;
IoRtcTime.weekday = IoRtcOriginTime.weekday; CurTime.weekday = OriginTime.weekday;
IoRtcTime.day = IoRtcOriginTime.day; CurTime.day = OriginTime.day;
IoRtcTime.month = IoRtcOriginTime.month; CurTime.month = OriginTime.month;
IoRtcTime.year = IoRtcOriginTime.year; CurTime.year = OriginTime.year;
IoRtcTime.century = IoRtcOriginTime.century; CurTime.century = OriginTime.century;
} }
void RtcHandler(ISRFrame_t *regs) static void HandleRTC(ISRFrame_t *regs)
{ {
//bprintf(BStdOut, " *RTC - ");
IoWriteByteOnPort(0x70, 0x0C); // Selects status reg C IoWriteByteOnPort(0x70, 0x0C); // Selects status reg C
IoReadByteFromPort(0x71); // Flush IoReadByteFromPort(0x71); // Flush
IoRtcTicks++; Ticks++;
IoSendEOItoPIC(0x28); KeSendEOItoPIC(0x28);
//bprintf(BStdOut, " - EOI* ");
} }
void IoPrintRtcTime(void) char *KeFormatCurTime(void)
{ {
Time_t* RtcTime = IoGetRtcTime(); Time_t *RtcTime = KeGetCurTime();
KernLog("[RTC Time] %02d/%02d/%04d ; %02d:%02d:%02d \n", snprintf(TimeFmtBuf, sizeof(TimeFmtBuf),
RtcTime->day,
RtcTime->month,
RtcTime->year + RtcTime->century*100,
RtcTime->hour,
RtcTime->min,
RtcTime->sec
);
}
char* IoGetRtcTimeChar(void)
{
Time_t *RtcTime = IoGetRtcTime();
snprintf(IoTimeChar, sizeof(IoTimeChar),
"%02d/%02d/%02d ; %02d:%02d:%02d", "%02d/%02d/%02d ; %02d:%02d:%02d",
RtcTime->day, RtcTime->day,
RtcTime->month, RtcTime->month,
@ -171,39 +188,42 @@ char* IoGetRtcTimeChar(void)
RtcTime->min, RtcTime->min,
RtcTime->sec RtcTime->sec
); );
return IoTimeChar; return TimeFmtBuf;
} }
static void UpdateRtcTime(void) static void UpdateCurTime(void)
{ {
ulong frequency = 32768 >> (RtcRate-1); ulong frequency = 32768 >> (RTC_RATE - 1);
uchar minRemain, hourRemain, dayRemain; uchar minRemain, hourRemain, dayRemain;
IoRtcTime.sec = CurTime.sec =
(uchar)(((ulong)IoRtcOriginTime.sec + (IoRtcTicks / frequency)) % 60); (uchar)(((ulong)OriginTime.sec + (Ticks / frequency)) % 60);
minRemain = minRemain =
(uchar)(((ulong)IoRtcOriginTime.sec + (IoRtcTicks / frequency)) / 60); (uchar)(((ulong)OriginTime.sec + (Ticks / frequency)) / 60);
CurTime.min =
(uchar)(((ulong)OriginTime.min + minRemain) % 60);
IoRtcTime.min =
(uchar)(((ulong)IoRtcOriginTime.min + minRemain) % 60);
hourRemain = hourRemain =
(uchar)(((ulong)IoRtcOriginTime.min + minRemain) / 60); (uchar)(((ulong)OriginTime.min + minRemain) / 60);
CurTime.hour =
(uchar)(((ulong)OriginTime.hour + hourRemain) % 24);
IoRtcTime.hour =
(uchar)(((ulong)IoRtcOriginTime.hour + hourRemain) % 24);
dayRemain = dayRemain =
(uchar)(((ulong)IoRtcOriginTime.hour + hourRemain) / 24); (uchar)(((ulong)OriginTime.hour + hourRemain) / 24);
if (dayRemain) { if (dayRemain) {
KeStartPanic("[RTC Time] We must shutdown this computer for your safety.\n"); KeStartPanic("[RTC] We must shutdown this computer for your safety.\n");
} }
} }
Time_t* IoGetRtcTime(void) Time_t* KeGetCurTime(void)
{ {
UpdateRtcTime(); UpdateCurTime();
return &IoRtcTime; return &CurTime;
} }
static uint IsLeapYear(uint year) static uint IsLeapYear(uint year)
@ -224,9 +244,9 @@ static uint DaysInMonth(uint month, uint year)
: 31 - (month - 1) % 7 % 2; : 31 - (month - 1) % 7 % 2;
} }
ulong IoGetTimeStamp(void) ulong KeGetTimeStamp(void)
{ {
Time_t *time = IoGetRtcTime(); Time_t *time = KeGetCurTime();
uint dpy = 365 + IsLeapYear(time->year); uint dpy = 365 + IsLeapYear(time->year);
uint dim = DaysInMonth(time->month, time->year + time->century * 100); uint dim = DaysInMonth(time->month, time->year + time->century * 100);
@ -240,23 +260,23 @@ ulong IoGetTimeStamp(void)
* dpy * 24 * 60 * 60; * dpy * 24 * 60 * 60;
} }
ulong IoGetRtcTicks(void) ulong KeGetClockTicks(void)
{ {
return IoRtcTicks; return Ticks;
} }
void IoEnableRtc(void) void KeEnableRTC(void)
{ {
ulong flags = KePauseIRQs(); ulong flags = KePauseIRQs();
char readInterruptConfig; char readInterruptConfig;
char readRegister; char readRegister;
char readIrqs; char readIrqs;
IdtRegisterIsr(RtcHandler, 0x28); KeRegisterISR(HandleRTC, 0x28);
// Setting up the register control and interrupt rates // Setting up the register control and interrupt rates
DebugLog("[RTC Time] Interrupt frequency set to %d Hz\n", DebugLog("[RTC Time] Interrupt frequency set to %d Hz\n",
32768 >> (RtcRate-1)); 32768 >> (RTC_RATE - 1));
IoWriteByteOnPort(0x70, 0x8B); IoWriteByteOnPort(0x70, 0x8B);
readRegister = IoReadByteFromPort(0x71); readRegister = IoReadByteFromPort(0x71);
@ -266,7 +286,7 @@ void IoEnableRtc(void)
IoWriteByteOnPort(0x70, 0x8A); IoWriteByteOnPort(0x70, 0x8A);
readInterruptConfig = IoReadByteFromPort(0x71); readInterruptConfig = IoReadByteFromPort(0x71);
IoWriteByteOnPort(0x70, 0x8A); // Because reading flushes IoWriteByteOnPort(0x70, 0x8A); // Because reading flushes
IoWriteByteOnPort(0x71, (readInterruptConfig & 0xF0) | RtcRate); IoWriteByteOnPort(0x71, (readInterruptConfig & 0xF0) | RTC_RATE);
IoWriteByteOnPort(0x70, 0x0C); IoWriteByteOnPort(0x70, 0x0C);
IoReadByteFromPort(0x71); // Flush IoReadByteFromPort(0x71); // Flush
@ -280,19 +300,20 @@ void IoEnableRtc(void)
IoWriteByteOnPort(0x70, 0x0C); // Select status reg C IoWriteByteOnPort(0x70, 0x0C); // Select status reg C
IoReadByteFromPort(0x71); // Flush IoReadByteFromPort(0x71); // Flush
GetTimeFromRtc(); GetTimeFromRTC();
KeRestoreIRQs(flags); KeRestoreIRQs(flags);
IoEnableNMI(); KeEnableNMI();
srand(IoGetTimeStamp()); srand(KeGetTimeStamp());
} }
void IoRtcWait(uint time) // time in ms void KeDelayExecution(uint time)
{ {
ulong frequency = 32768 >> (RtcRate-1); ulong frequency = 32768 >> (RTC_RATE - 1);
ulong beginTick = IoGetRtcTicks(); ulong beginTick = KeGetClockTicks();
while(IoGetRtcTicks() < beginTick + (frequency/1000) * time) {
KePauseCPU(); while (KeGetClockTicks() < beginTick + (frequency/1000) * time) {
KeRelaxCPU();
} }
} }

View File

@ -27,9 +27,9 @@
noreturn void PoShutdownQemu(void) noreturn void PoShutdownQemu(void)
{ {
KernLog("\nShutdown QEMU at %s...\n", IoGetRtcTimeChar()); KernLog("\nShutdown QEMU at %s...\n", KeFormatCurTime());
IoRtcWait(1000); KeDelayExecution(1000);
IoWriteWordOnPort(0x604, 0x2000); IoWriteWordOnPort(0x604, 0x2000);
@ -39,9 +39,9 @@ noreturn void PoShutdownQemu(void)
noreturn void PoShutdownVirtualbox(void) noreturn void PoShutdownVirtualbox(void)
{ {
KernLog("\nShutdown VirtualBox at %s...\n", IoGetRtcTimeChar()); KernLog("\nShutdown VirtualBox at %s...\n", KeFormatCurTime());
IoRtcWait(1000); KeDelayExecution(1000);
IoWriteWordOnPort(0x4004, 0x3400); IoWriteWordOnPort(0x4004, 0x3400);
@ -51,9 +51,9 @@ noreturn void PoShutdownVirtualbox(void)
noreturn void PoShutdownBochs(void) noreturn void PoShutdownBochs(void)
{ {
KernLog("\nShutdown Bochs at %s...\n", IoGetRtcTimeChar()); KernLog("\nShutdown Bochs at %s...\n", KeFormatCurTime());
IoRtcWait(1000); KeDelayExecution(1000);
IoWriteWordOnPort(0xB004, 0x2000); IoWriteWordOnPort(0xB004, 0x2000);

View File

@ -70,7 +70,7 @@ error_t CmdHelp(int argc, char **argv, char *cmdline)
error_t CmdDate(int argc, char **argv, char *cmdline) error_t CmdDate(int argc, char **argv, char *cmdline)
{ {
IoPrintRtcTime(); KernLog("%s\n", KeFormatCurTime());
return EOK; return EOK;
} }
@ -213,9 +213,9 @@ error_t CmdPF(int argc, char **argv, char *cmdline)
return EOK; return EOK;
} }
extern void KeStartShell(void);
error_t CmdShell(int argc, char **argv, char *cmdline) error_t CmdShell(int argc, char **argv, char *cmdline)
{ {
extern void KeStartShell(void);
KeStartShell(); KeStartShell();
return EOK; return EOK;
} }
@ -224,18 +224,20 @@ error_t CmdShell(int argc, char **argv, char *cmdline)
Command_t cmdtable[] = Command_t cmdtable[] =
{ {
{ "beep", CmdBeep, "Make a beep" }, { "beep", CmdBeep, "Make a beep" },
{ "date", CmdDate, "Print date" }, { "cls", CmdClear, "Clears standard output" },
{ "die", CmdDie, "Die painfully" }, { "date", CmdDate, "Print date" },
{ "exit", CmdQuit, "Initiate shutdown" }, { "die", CmdDie, "Die painfully" },
{ "help", CmdHelp, "Show this message" }, { "exit", CmdQuit, "Initiate shutdown" },
{ "march", CmdStarWars, "Play the Imperial March"}, { "help", CmdHelp, "Show this message" },
{ "mmap", CmdMemMap, "Show memory map" }, { "march", CmdStarWars, "Play the Imperial March"},
{ "musage", CmdMemUsage, "Show memory statistics" }, { "mmap", CmdMemMap, "Show memory map" },
{ "pfault", CmdPF, "Provokes a PF" }, { "musage", CmdMemUsage, "Show memory statistics" },
{ "pstest", CmdPsTest, "Scheduler test routine" }, { "pfault", CmdPF, "Provokes a PF" },
{ "shell", CmdShell, "New shell instance" }, { "pstest", CmdPsTest, "Scheduler test routine" },
{ "quit", CmdQuit, "Alias for 'exit'" }, { "quit", CmdQuit, "Alias for 'exit'" },
{ "shell", CmdShell, "New shell instance" },
{ "time", CmdTime, "Print time" },
{ NULL, NULL, NULL } { NULL, NULL, NULL }
}; };

View File

@ -72,7 +72,7 @@ error_t bgetc(Buffer_t *buf, uchar *ch)
// (so that BStdIn works; don't make anything else) // (so that BStdIn works; don't make anything else)
while (buf->rp >= buf->wp) { while (buf->rp >= buf->wp) {
#ifdef _KALEID_KERNEL #ifdef _KALEID_KERNEL
IoRtcWait(1); KeDelayExecution(1);
#endif #endif
} }