PIT is now working !

This commit is contained in:
Adrien Bourmault 2019-11-14 00:54:34 +01:00
parent b3e82f0ac8
commit 0a428c6cad
6 changed files with 81 additions and 12 deletions

View File

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

View File

@ -58,6 +58,9 @@ void KeDelayExecution(uint);
Time_t *KeGetCurTime(void);
char *KeFormatCurTime(void);
void KeEnablePIT(void);
void KeSleep(uint);
//----------------------------------------------------------------------------//

View File

@ -73,6 +73,7 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg)
// Start drivers
KeEnableRTC();
KeEnablePIT();
IoEnableKeyb();
MmActivatePageHandler();

View File

@ -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);

View File

@ -27,21 +27,30 @@
#include <ke/idt.h>
#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();
}

View File

@ -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();
}
}