diff --git a/Makefile b/Makefile
index ca027a2..77a0081 100644
--- a/Makefile
+++ b/Makefile
@@ -148,24 +148,6 @@ $(KOBJDIR)/kernel/cpu/idt.o: $(KALEIDDIR)/kernel/cpu/idt.c \
@rm -f $@.1 $@.2
@echo ${CL2}[$@] ${CL}Compiled.${CL3}
-$(KOBJDIR)/kernel/io/keyb.o: $(KALEIDDIR)/kernel/io/keyb.c \
- $(KALEIDDIR)/kernel/io/keyb.asm $(INCLUDEDIR)/*/*.h | $(KOBJDIR)
- @mkdir -p $(shell dirname $@)
- @$(ASM) $(ASMFLAGS) $(KALEIDDIR)/kernel/io/keyb.asm -o $@.1
- @$(KCC) $< -o $@.2
- @$(LD) $(LDFLAGS) -r $@.1 $@.2 -o $@
- @rm -f $@.1 $@.2
- @echo ${CL2}[$@] ${CL}Compiled.${CL3}
-
-$(KOBJDIR)/kernel/io/rtc.o: $(KALEIDDIR)/kernel/io/rtc.c \
- $(KALEIDDIR)/kernel/io/rtc.asm $(INCLUDEDIR)/*/*.h | $(KOBJDIR)
- @mkdir -p $(shell dirname $@)
- @$(ASM) $(ASMFLAGS) $(KALEIDDIR)/kernel/io/rtc.asm -o $@.1
- @$(KCC) $< -o $@.2
- @$(LD) $(LDFLAGS) -r $@.1 $@.2 -o $@
- @rm -f $@.1 $@.2
- @echo ${CL2}[$@] ${CL}Compiled.${CL3}
-
## MAIN MAKEFILE ------------------------------------------------------------- #
$(KOBJDIR)/%.o: %.c $(INCLUDEDIR)/*/*.h | $(KOBJDIR)
diff --git a/include/kernel/base.h b/include/kernel/base.h
index 2fbec68..4778a54 100644
--- a/include/kernel/base.h
+++ b/include/kernel/base.h
@@ -43,8 +43,7 @@ typedef struct BootInfo_t BootInfo_t;
typedef struct ListHead_t ListHead_t;
typedef struct ListNode_t ListNode_t;
typedef struct Processor_t Processor_t;
-typedef struct IRQList_t IRQList_t;
-
+typedef struct ISRFrame_t ISRFrame_t;
typedef enum ProcState_t ProcState_t;
//------------------------------------------//
@@ -89,6 +88,23 @@ struct Processor_t
ListHead_t *timeCritProcs;
};
+struct ISRFrame_t {
+/* the register file */
+ ulong regs[15];
+
+ /* the error code and interrupt id */
+ ulong intNo;
+ ulong ErrorCode;
+
+ /* these are pushed automatically by the CPU */
+ ulong rip;
+ ulong cs;
+ ulong rflags;
+ ulong rsp;
+ ulong ss;
+} __attribute__((__packed__));
+
+
//------------------------------------------//
#ifndef NCPUS
diff --git a/include/kernel/idt.h b/include/kernel/idt.h
index 7b00530..d59e31c 100644
--- a/include/kernel/idt.h
+++ b/include/kernel/idt.h
@@ -13,7 +13,7 @@ typedef struct ISRFrame_t ISRFrame_t;
// -------------------------------------------------------------------------- //
-#define interrupt(n) asm volatile ("int %0" : : "N" (n) : "cc", "memory") \
+#define interrupt(n) asm volatile ("int %0" : : "N" (n) : "cc", "memory")
// -------------------------------------------------------------------------- //
@@ -44,28 +44,12 @@ struct IRQList_t
uchar n; //number of entries in the list
struct entry {
- void (*isr)(void);
+ void (*isr)(ISRFrame_t *regs);
uchar irq;
uchar flags;
} entry[224];
};
-struct ISRFrame_t {
-/* the register file */
- uint64_t regs[15];
-
- /* the error code and interrupt id */
- uint64_t id;
- uint64_t error;
-
- /* these are pushed automatically by the CPU */
- uint64_t rip;
- uint64_t cs;
- uint64_t rflags;
- uint64_t rsp;
- uint64_t ss;
-} __attribute__((__packed__));
-
typedef struct
{
@@ -108,10 +92,10 @@ static char *IsrExceptions[32] = {
// -------------------------------------------------------------------------- //
-void IdtRegisterIrq(void (*isr)(void), uchar irq, uchar flags);
+void IdtRegisterIrq(void (*isr)(ISRFrame_t *regs), uchar irq, uchar flags);
void IdtSetup(void);
void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags);
-//void IdtHandler(ulong intNo);
+void IdtExceptionHandler(ISRFrame_t *regs);
static void EnablePIC(void);
void SendEOItoPIC(uchar isr);
@@ -148,5 +132,34 @@ extern void isr28();
extern void isr29();
extern void isr30();
extern void isr31();
+extern void isr32();
+extern void isr33();
+extern void isr34();
+extern void isr35();
+extern void isr36();
+extern void isr37();
+extern void isr38();
+extern void isr39();
+extern void isr40();
+extern void isr41();
+extern void isr42();
+extern void isr43();
+extern void isr44();
+extern void isr45();
+extern void isr46();
+extern void isr47();
+extern void isr48();
+extern void isr49();
+extern void isr50();
+extern void isr51();
+extern void isr52();
+extern void isr53();
+extern void isr54();
+extern void isr55();
+extern void isr56();
+extern void isr57();
+extern void isr58();
+extern void isr59();
+extern void isr60();
#endif
diff --git a/include/kernel/iomisc.h b/include/kernel/iomisc.h
index 5c9da8e..3bb9f64 100644
--- a/include/kernel/iomisc.h
+++ b/include/kernel/iomisc.h
@@ -64,7 +64,7 @@ static inline ulong KePauseIRQs(void) {
extern void IoSendEOItoPIC(uchar isr);
extern void IoEnableNMI(void);
extern void IoDisableNMI(void);
-extern void IdtRegisterIrq(void (*isr)(void), uchar irq, uchar flags);
+extern void IdtRegisterIrq(void (*isr)(ISRFrame_t *regs), uchar irq, uchar flags);
//
// Restore IRQ flag to its state before KePauseIRQs
diff --git a/kaleid/kernel/cpu/idt.c b/kaleid/kernel/cpu/idt.c
index 6f083dd..6264dfa 100644
--- a/kaleid/kernel/cpu/idt.c
+++ b/kaleid/kernel/cpu/idt.c
@@ -37,11 +37,11 @@ IRQList_t irqList = { 0 };
//
// Registers an isr with his IRQ to handle driver interrupts
//
-void IdtRegisterIrq(void (*isr)(void), uchar irq, uchar flags)
+void IdtRegisterIrq(void (*isr)(ISRFrame_t *regs), uchar irq, uchar flags)
{
uchar n = irqList.n;
- KalAssert(idt[0].flags==0); // IDT uninitialized
+ KalAssert(idt[0].flags!=0); // IDT initialized
if ((n == 224)) // IRQs not filled
KeStartPanic("[IdtRegisterIrq] Cannot register IRQ %c function %p !",
@@ -103,15 +103,36 @@ void IdtSetup(void)
IdtSetGate(30, (ulong)isr30, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(31, (ulong)isr31, codeSeg, 0x8E); // INTEL RESERVED
- // Set the IRQ Driver Gates
- for (int i = 0 ; i < irqList.n ; i++) {
- IdtSetGate(
- irqList.entry[i].irq,
- (ulong)irqList.entry[i].isr,
- codeSeg,
- irqList.entry[i].flags
- );
- }
+ // Set IDT IRQs Gates
+ IdtSetGate(32, (ulong)isr32, codeSeg, 0x8E);
+ IdtSetGate(33, (ulong)isr33, codeSeg, 0x8E);
+ IdtSetGate(34, (ulong)isr34, codeSeg, 0x8E);
+ IdtSetGate(35, (ulong)isr35, codeSeg, 0x8E);
+ IdtSetGate(36, (ulong)isr36, codeSeg, 0x8E);
+ IdtSetGate(37, (ulong)isr37, codeSeg, 0x8E);
+ IdtSetGate(38, (ulong)isr38, codeSeg, 0x8E);
+ IdtSetGate(39, (ulong)isr39, codeSeg, 0x8E);
+ IdtSetGate(40, (ulong)isr40, codeSeg, 0x8E);
+ IdtSetGate(41, (ulong)isr41, codeSeg, 0x8E);
+ IdtSetGate(42, (ulong)isr42, codeSeg, 0x8E);
+ IdtSetGate(43, (ulong)isr43, codeSeg, 0x8E);
+ IdtSetGate(44, (ulong)isr44, codeSeg, 0x8E);
+ IdtSetGate(45, (ulong)isr45, codeSeg, 0x8E);
+ IdtSetGate(46, (ulong)isr46, codeSeg, 0x8E);
+ IdtSetGate(47, (ulong)isr47, codeSeg, 0x8E);
+ IdtSetGate(48, (ulong)isr48, codeSeg, 0x8E);
+ IdtSetGate(49, (ulong)isr49, codeSeg, 0x8E);
+ IdtSetGate(50, (ulong)isr50, codeSeg, 0x8E);
+ IdtSetGate(51, (ulong)isr51, codeSeg, 0x8E);
+ IdtSetGate(52, (ulong)isr52, codeSeg, 0x8E);
+ IdtSetGate(53, (ulong)isr53, codeSeg, 0x8E);
+ IdtSetGate(54, (ulong)isr54, codeSeg, 0x8E);
+ IdtSetGate(55, (ulong)isr55, codeSeg, 0x8E);
+ IdtSetGate(56, (ulong)isr56, codeSeg, 0x8E);
+ IdtSetGate(57, (ulong)isr57, codeSeg, 0x8E);
+ IdtSetGate(58, (ulong)isr58, codeSeg, 0x8E);
+ IdtSetGate(59, (ulong)isr59, codeSeg, 0x8E);
+ IdtSetGate(60, (ulong)isr60, codeSeg, 0x8E);
// Load IDT
IdtInit();
@@ -185,21 +206,57 @@ void IoDisableNMI(void)
}
//
-// The main exception handler
+// The main ISR handler
//
-void IdtHandler(ulong intNo)
+void IsrHandler(ISRFrame_t *regs)
+{
+ if ((!regs) || (!regs->rip))
+ KeStartPanic("[ISR ?] Unknown ISR Exception Abort\n");
+
+ if (regs->intNo < 32) {
+ IdtExceptionHandler(regs);
+ return;
+ }
+
+ for (int i = 0; i < irqList.n; i++) {
+ if (regs->intNo == irqList.entry[i].irq) {
+ irqList.entry[i].isr(regs);
+ return;
+ }
+ }
+
+ KeStartPanic("[ISR 0x%x] Unknown ISR Exception Abort\n", regs->intNo);
+}
+
+
+//
+// CPU Exception handler
+//
+void IdtExceptionHandler(ISRFrame_t *regs)
{
int recoverable = 0;
char *exceptionMsg = "Unhandled ISR exception";
- if (intNo >= 32) recoverable++;
-
- if (intNo < 32) exceptionMsg = IsrExceptions[intNo];
+ exceptionMsg = IsrExceptions[regs->intNo];
if (!recoverable) {
- KeStartPanic("[ISR 0x%x] Irrecoverable %s\n", intNo, exceptionMsg);
+ KeStartPanic("[ISR 0x%x] Irrecoverable Kernel %s\n"
+ " Error code : 0x%x\n"
+ " RIP:\t\t%p\n"
+ " CS:\t\t%p\n"
+ " RFLAGS:\t%022b\n"
+ " RSP:\t\t%p\n"
+ " SS:\t\t%p\n",
+ regs->intNo,
+ exceptionMsg,
+ regs->ErrorCode,
+ regs->rip,
+ regs->cs,
+ regs->rflags,
+ regs->rsp,
+ regs->ss
+ );
} else {
- bprintf(BStdOut, "[ISR 0x%x] %s\n", intNo, exceptionMsg);
- //IoSendEOItoPIC(intNo);
+ bprintf(BStdOut, "[ISR 0x%x] %s\n", regs->intNo, exceptionMsg);
}
}
diff --git a/kaleid/kernel/cpu/isr.asm b/kaleid/kernel/cpu/isr.asm
index 59247f9..58b897c 100644
--- a/kaleid/kernel/cpu/isr.asm
+++ b/kaleid/kernel/cpu/isr.asm
@@ -27,7 +27,7 @@
global IdtInit
global divideByZero
extern idtPtr
-extern IdtHandler
+extern IsrHandler
extern label0
;;
@@ -41,16 +41,14 @@ IdtInit:
;; Bug test
;;
divideByZero:
- pushAll
mov eax, 17
mov ebx, 0
xor edx, edx
div ebx
- popAll
ret
;;
-;; ISR handler
+;; ISR Exception pre-handler
;;
isrPreHandler:
pushAll
@@ -71,7 +69,7 @@ isrPreHandler:
mov rdi, rsp ; First argument points to the processor state
mov rbp, 0 ; Terminate stack traces here
- call IdtHandler
+ call IsrHandler
; decrement mask count
dec qword [gs:8]
@@ -81,7 +79,7 @@ isrPreHandler:
and rax, 0x3000
jz .SExit
- swapgs
+ swapgs ; XXX need TSS
.SExit:
popAll
@@ -164,3 +162,11 @@ IsrWithoutErrCode 29
IsrWithoutErrCode 30
IsrWithoutErrCode 31
+
+;; IRQs
+%assign i 32
+%rep 225
+ IsrWithoutErrCode i
+%assign i i+1
+%endrep
+
diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c
index 706f03d..90da5e4 100644
--- a/kaleid/kernel/init/init.c
+++ b/kaleid/kernel/init/init.c
@@ -38,7 +38,6 @@ extern void BtInitBootInfo(multiboot_info_t *mbi, void *codeSeg);
extern error_t IoInitVGABuffer(void);
//io/keyb.c
-extern void IoSetupKeyb(void);
extern void IoEnableKeyb(void);
// cpu/idt.c
@@ -82,9 +81,6 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg)
MmInitHeap();
PsInitSched();
- // Drivers ISR inits
- IoSetupRtc();
- IoSetupKeyb();
// Interrupts launching
IdtSetup();
KeEnableIRQs();
@@ -95,12 +91,14 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg)
IoPrintRtcTime();
KernLog("There was %d ticks\n", IoGetRtcTicks());
- for (uint i = 1; i < 20000 ; i++) {
+ for (uint i = 1; i < 2 ; i++) {
while (IoGetRtcTicks() < i * 10000) {
}
IoPrintRtcTime();
}
+ divideByZero();
+
KernLog("Goodbye after %d ticks\n", IoGetRtcTicks());
// End this machine's suffering
BFlushBuf(BStdOut);
diff --git a/kaleid/kernel/io/keyb.asm b/kaleid/kernel/io/keyb.asm
deleted file mode 100644
index 5872003..0000000
--- a/kaleid/kernel/io/keyb.asm
+++ /dev/null
@@ -1,68 +0,0 @@
-;=----------------------------------------------------------------------------=;
-; GNU GPL OS/K ;
-; ;
-; Desc: Basic Read Only Keyboard Driver ;
-; (x86_64 architecture only) ;
-; ;
-; ;
-; Copyright © 2018-2019 The OS/K Team ;
-; ;
-; This file is part of OS/K. ;
-; ;
-; OS/K is free software: you can redistribute it and/or modify ;
-; it under the terms of the GNU General Public License as published by ;
-; the Free Software Foundation, either version 3 of the License, or ;
-; (at your option) any later version. ;
-; ;
-; OS/K is distributed in the hope that it will be useful, ;
-; but WITHOUT ANY WARRANTY; without even the implied warranty of ;
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;
-; GNU General Public License for more details. ;
-; ;
-; You should have received a copy of the GNU General Public License ;
-; along with OS/K. If not, see . ;
-;=----------------------------------------------------------------------------=;
-
-[BITS 64]
-
-global KeybIsr
-extern KeybHandler
-
-%macro pushAll 0
- push rax
- push rcx
- push rdx
- push rbx
- push rbp
- push rsi
- push rdi
-%endmacro
-
-%macro popAll 0
- pop rdi
- pop rsi
- pop rbp
- pop rbx
- pop rdx
- pop rcx
- pop rax
-%endmacro
-
-;;
-;; Keyboard handler
-;;
-KeybIsr:
- cli
- pushAll
-
- xor rax, rax
- mov ax, ds
- push rax
-
- call KeybHandler
-
- pop rax
- mov ds, ax
-
- popAll
- iretq
diff --git a/kaleid/kernel/io/keyb.c b/kaleid/kernel/io/keyb.c
index cbb2aaf..d631e0b 100644
--- a/kaleid/kernel/io/keyb.c
+++ b/kaleid/kernel/io/keyb.c
@@ -26,14 +26,8 @@
#include
#include
-extern void KeybIsr(void);
char ScanCodes[100] = { 0 };
-void IoSetupKeyb(void)
-{
- IdtRegisterIrq(KeybIsr, 0x21, 0x8E);
-}
-
void KeybPrint(char code)
{
if (code) {
@@ -88,17 +82,7 @@ void ScanCodesInit(void)
ScanCodes[0x39] = ' ';
}
-void IoEnableKeyb(void)
-{
- ulong flags = KePauseIRQs();
- char readedInterruptConfig = IoReadByteFromPort(0x21);
- IoWriteByteOnPort(0x21, 0xFD & readedInterruptConfig);
- KeRestoreIRQs(flags);
- IoEnableNMI();
- ScanCodesInit();
-}
-
-void KeybHandler(void)
+void KeybHandler(ISRFrame_t *regs)
{
char status;
char code = 0;
@@ -116,3 +100,14 @@ void KeybHandler(void)
KeybPrint((int)code);
IoSendEOItoPIC(0x21);
}
+
+void IoEnableKeyb(void)
+{
+ ulong flags = KePauseIRQs();
+ IdtRegisterIrq(KeybHandler, 0x21, 0x8E);
+ char readedInterruptConfig = IoReadByteFromPort(0x21);
+ IoWriteByteOnPort(0x21, 0xFD & readedInterruptConfig);
+ KeRestoreIRQs(flags);
+ IoEnableNMI();
+ ScanCodesInit();
+}
diff --git a/kaleid/kernel/io/rtc.asm b/kaleid/kernel/io/rtc.asm
deleted file mode 100644
index 214af07..0000000
--- a/kaleid/kernel/io/rtc.asm
+++ /dev/null
@@ -1,68 +0,0 @@
-;=----------------------------------------------------------------------------=;
-; GNU GPL OS/K ;
-; ;
-; Desc: Basic Read Only Keyboard Driver ;
-; (x86_64 architecture only) ;
-; ;
-; ;
-; Copyright © 2018-2019 The OS/K Team ;
-; ;
-; This file is part of OS/K. ;
-; ;
-; OS/K is free software: you can redistribute it and/or modify ;
-; it under the terms of the GNU General Public License as published by ;
-; the Free Software Foundation, either version 3 of the License, or ;
-; (at your option) any later version. ;
-; ;
-; OS/K is distributed in the hope that it will be useful, ;
-; but WITHOUT ANY WARRANTY; without even the implied warranty of ;
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;
-; GNU General Public License for more details. ;
-; ;
-; You should have received a copy of the GNU General Public License ;
-; along with OS/K. If not, see . ;
-;=----------------------------------------------------------------------------=;
-
-[BITS 64]
-
-global RtcIsr
-extern RtcHandler
-
-%macro pushAll 0
- push rax
- push rcx
- push rdx
- push rbx
- push rbp
- push rsi
- push rdi
-%endmacro
-
-%macro popAll 0
- pop rdi
- pop rsi
- pop rbp
- pop rbx
- pop rdx
- pop rcx
- pop rax
-%endmacro
-
-;;
-;; Keyboard handler
-;;
-RtcIsr:
- cli
- pushAll
-
- xor rax, rax
- mov ax, ds
- push rax
-
- call RtcHandler
-
- pop rax
- mov ds, ax
-
- popAll
- iretq
diff --git a/kaleid/kernel/io/rtc.c b/kaleid/kernel/io/rtc.c
index b752ab5..b76e322 100644
--- a/kaleid/kernel/io/rtc.c
+++ b/kaleid/kernel/io/rtc.c
@@ -27,17 +27,11 @@
#include
#include
-extern void RtcIsr(void);
-
static ulong IoRtcTicks = 0;
static uchar RtcRate = 0x05; //2048Hz
static Time_t IoRtcOriginTime;
static Time_t IoRtcTime;
static char time24or12Mode;
-void IoSetupRtc(void)
-{
- IdtRegisterIrq(RtcIsr, 0x28, 0x8E);
-}
static void GetTimeFromRtc(void)
{
@@ -143,45 +137,7 @@ static void GetTimeFromRtc(void)
IoRtcTime.century = IoRtcOriginTime.century;
}
-void IoEnableRtc(void)
-{
- ulong flags = KePauseIRQs();
- char readedInterruptConfig;
- char readedRegister;
- char readedIrqs;
-
- // Setting up the register control and interrupt rates
- DebugLog("[RTC Time] Interrupt frequency set to %d Hz\n",
- 32768 >> (RtcRate-1));
-
- IoWriteByteOnPort(0x70, 0x8B);
- readedRegister = IoReadByteFromPort(0x71);
- IoWriteByteOnPort(0x70, 0x8B); // Because reading flushes
- IoWriteByteOnPort(0x71, readedRegister | 0x40);
-
- IoWriteByteOnPort(0x70, 0x8A);
- readedInterruptConfig = IoReadByteFromPort(0x71);
- IoWriteByteOnPort(0x70, 0x8A); // Because reading flushes
- IoWriteByteOnPort(0x71, (readedInterruptConfig & 0xF0) | RtcRate);
- IoWriteByteOnPort(0x70, 0x0C);
- IoReadByteFromPort(0x71); // Flush
-
- // Setting up the IRQs
- readedIrqs = IoReadByteFromPort(0xA1);
- IoWriteByteOnPort(0xA1, 0xFE & readedIrqs); // Enables IRQ on PIC 2
- readedIrqs = IoReadByteFromPort(0x21);
- IoWriteByteOnPort(0x21, 0xFB & readedIrqs); // Enables IRQ on PIC 1
-
- // Clean-up
- IoWriteByteOnPort(0x70, 0x0C); // Select status reg C
- IoReadByteFromPort(0x71); // Flush
-
- GetTimeFromRtc();
- KeRestoreIRQs(flags);
- IoEnableNMI();
-}
-
-void RtcHandler(void)
+void RtcHandler(ISRFrame_t *regs)
{
//bprintf(BStdOut, " *RTC - ");
IoWriteByteOnPort(0x70, 0x0C); // Selects status reg C
@@ -258,4 +214,44 @@ ulong IoGetRtcTicks(void)
return IoRtcTicks;
}
+void IoEnableRtc(void)
+{
+ ulong flags = KePauseIRQs();
+ char readedInterruptConfig;
+ char readedRegister;
+ char readedIrqs;
+
+ IdtRegisterIrq(RtcHandler, 0x28, 0x8E);
+
+ // Setting up the register control and interrupt rates
+ DebugLog("[RTC Time] Interrupt frequency set to %d Hz\n",
+ 32768 >> (RtcRate-1));
+
+ IoWriteByteOnPort(0x70, 0x8B);
+ readedRegister = IoReadByteFromPort(0x71);
+ IoWriteByteOnPort(0x70, 0x8B); // Because reading flushes
+ IoWriteByteOnPort(0x71, readedRegister | 0x40);
+
+ IoWriteByteOnPort(0x70, 0x8A);
+ readedInterruptConfig = IoReadByteFromPort(0x71);
+ IoWriteByteOnPort(0x70, 0x8A); // Because reading flushes
+ IoWriteByteOnPort(0x71, (readedInterruptConfig & 0xF0) | RtcRate);
+ IoWriteByteOnPort(0x70, 0x0C);
+ IoReadByteFromPort(0x71); // Flush
+
+ // Setting up the IRQs
+ readedIrqs = IoReadByteFromPort(0xA1);
+ IoWriteByteOnPort(0xA1, 0xFE & readedIrqs); // Enables IRQ on PIC 2
+ readedIrqs = IoReadByteFromPort(0x21);
+ IoWriteByteOnPort(0x21, 0xFB & readedIrqs); // Enables IRQ on PIC 1
+
+ // Clean-up
+ IoWriteByteOnPort(0x70, 0x0C); // Select status reg C
+ IoReadByteFromPort(0x71); // Flush
+
+ GetTimeFromRtc();
+ KeRestoreIRQs(flags);
+ IoEnableNMI();
+}
+