From 0a428c6cad339261dcb2136362ca0aa790f68be9 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Thu, 14 Nov 2019 00:54:34 +0100 Subject: [PATCH] PIT is now working ! --- include/ke/idt.h | 2 ++ include/ke/time.h | 3 +++ kaleid/kernel/init/init.c | 1 + kaleid/kernel/ke/idt.c | 35 +++++++++++++++++++++++++++++++++++ kaleid/kernel/ke/pit.c | 34 +++++++++++++++++++++++++++++++++- kaleid/kernel/ke/rtc.c | 18 +++++++----------- 6 files changed, 81 insertions(+), 12 deletions(-) diff --git a/include/ke/idt.h b/include/ke/idt.h index 80ae7ca..6e705bf 100644 --- a/include/ke/idt.h +++ b/include/ke/idt.h @@ -69,6 +69,8 @@ struct ISRList_t void KeLoadIDT(void); void KeSetupIDT(void); +void KeUnmaskIRQ(uchar IRQline); +void KeMaskIRQ(uchar IRQline); void KeSendEOItoPIC(uchar isr); void KeSetIDTGate(uchar rank, diff --git a/include/ke/time.h b/include/ke/time.h index 0486dd6..c96c9fc 100644 --- a/include/ke/time.h +++ b/include/ke/time.h @@ -58,6 +58,9 @@ void KeDelayExecution(uint); Time_t *KeGetCurTime(void); char *KeFormatCurTime(void); +void KeEnablePIT(void); +void KeSleep(uint); + //----------------------------------------------------------------------------// diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index e29259e..cf2f92f 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -73,6 +73,7 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg) // Start drivers KeEnableRTC(); + KeEnablePIT(); IoEnableKeyb(); MmActivatePageHandler(); diff --git a/kaleid/kernel/ke/idt.c b/kaleid/kernel/ke/idt.c index 9a4f63c..d5dc7e2 100644 --- a/kaleid/kernel/ke/idt.c +++ b/kaleid/kernel/ke/idt.c @@ -230,6 +230,9 @@ static void EnablePIC(void) // Set OCW1 (interrupt masks) IoWriteByteOnPort(0x21, 0xff); IoWriteByteOnPort(0xa1, 0xff); + + char readIrqs = IoReadByteFromPort(0x21); + IoWriteByteOnPort(0x21, 0xFB & readIrqs); // Enables IRQ forwarding from PIC2 to PIC 1 } // @@ -243,6 +246,38 @@ void KeSendEOItoPIC(uchar isr) IoWriteByteOnPort(0x20,0x20); } +void KeMaskIRQ(uchar isr) +{ + uchar port; + uchar value; + + if(isr < 0x8) { + port = 0x21; + } else { + port = 0xA1; + isr -= 8; + } + + value = IoReadByteFromPort(port) | (1 << isr); + IoWriteByteOnPort(port, value); +} + +void KeUnmaskIRQ(uchar isr) +{ + uchar port; + uchar value; + + if(isr < 0x8) { + port = 0x21; + } else { + port = 0xA1; + isr -= 8; + } + + value = IoReadByteFromPort(port) & ~(1 << isr); + IoWriteByteOnPort(port, value); +} + void KeEnableNMI(void) { IoWriteByteOnPort(0x70, IoReadByteFromPort(0x70) & 0x7F); diff --git a/kaleid/kernel/ke/pit.c b/kaleid/kernel/ke/pit.c index 7b50c61..3e11afa 100644 --- a/kaleid/kernel/ke/pit.c +++ b/kaleid/kernel/ke/pit.c @@ -27,21 +27,30 @@ #include #define COUNTDONE 1 +#define PIT_FREQUENCY 100 // Hz = 10ms static TimerFilo_t timerFilo[20]; //20 concurrent sleep max +static ulong Ticks = 0; // // ISR handler for the Programmable Interval Timer // -static void HandleTimer(ISRFrame_t *regs) +static void HandlePIT(ISRFrame_t *regs) { for (uchar i = 0; i < 20; i++) { + + // debug + //DebugLog("Hello world of PIT ticks !\n"); + // + if (timerFilo[i].countDown > 0) { timerFilo[i].countDown--; if (timerFilo[i].countDown == 0) i; //XXX SendMessage a message to timerFifo[i].sema that COUNTDONE; } + + KeSendEOItoPIC(0x28); } } @@ -65,3 +74,26 @@ void KeSleep(uint delay) timerBlock->countDown = delay; // wait for a message on timerFifo[i].sema } + + +void KeEnablePIT(void) +{ + ulong flags = KePauseIRQs(); + char readIrqs; + uint divisor = 1193180 / PIT_FREQUENCY; + + KeRegisterISR(HandlePIT, 0x20); + + IoWriteByteOnPort(0x43, 0x36); // 0x34 = 00110100 for rate gen + + IoWriteByteOnPort(0x40, (char)(divisor & 0xFF )); // low byte of freq + IoWriteByteOnPort(0x40, (char)((divisor >> 8)& 0xFF)); // high byte of freq + + // Setting up the IRQs + KeUnmaskIRQ(0); + + DebugLog("\tPIT activated with rate generator mode 10ms\n"); + + KeRestoreIRQs(flags); + KeEnableNMI(); +} diff --git a/kaleid/kernel/ke/rtc.c b/kaleid/kernel/ke/rtc.c index b1cd20f..a6f1bdf 100644 --- a/kaleid/kernel/ke/rtc.c +++ b/kaleid/kernel/ke/rtc.c @@ -218,9 +218,9 @@ static void UpdateCurTime(void) dayRemain = (uchar)(((ulong)OriginTime.hour + hourRemain) / 24); - if (dayRemain) { - KeStartPanic("[RTC] We must shutdown this computer for your safety.\n"); - } + CurTime.day = + (uchar)(((ulong)OriginTime.day + dayRemain) % 30); + } Time_t* KeGetCurTime(void) @@ -273,7 +273,6 @@ void KeEnableRTC(void) ulong flags = KePauseIRQs(); char readInterruptConfig; char readRegister; - char readIrqs; KeRegisterISR(HandleRTC, 0x28); @@ -294,10 +293,8 @@ void KeEnableRTC(void) IoReadByteFromPort(0x71); // Flush // Setting up the IRQs - readIrqs = IoReadByteFromPort(0xA1); - IoWriteByteOnPort(0xA1, 0xFE & readIrqs); // Enables IRQ on PIC 2 - readIrqs = IoReadByteFromPort(0x21); - IoWriteByteOnPort(0x21, 0xFB & readIrqs); // Enables IRQ on PIC 1 + KeUnmaskIRQ(8); + // Clean-up IoWriteByteOnPort(0x70, 0x0C); // Select status reg C @@ -306,8 +303,8 @@ void KeEnableRTC(void) GetTimeFromRTC(); KeRestoreIRQs(flags); KeEnableNMI(); - - srand(KeGetTimeStamp()); + + srand(KeGetTimeStamp()); // Initializes the kernel number generator } void KeDelayExecution(uint time) @@ -318,5 +315,4 @@ void KeDelayExecution(uint time) while (KeGetClockTicks() < beginTick + (frequency/1000) * time) { KeRelaxCPU(); } - }