IDT is now really ready
This commit is contained in:
parent
74593f7f71
commit
e7d56a8550
18
Makefile
18
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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 <https://www.gnu.org/licenses/>. ;
|
||||
;=----------------------------------------------------------------------------=;
|
||||
|
||||
[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
|
|
@ -26,14 +26,8 @@
|
|||
#include <kernel/iomisc.h>
|
||||
#include <extras/buf.h>
|
||||
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -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 <https://www.gnu.org/licenses/>. ;
|
||||
;=----------------------------------------------------------------------------=;
|
||||
|
||||
[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
|
|
@ -27,17 +27,11 @@
|
|||
#include <extras/buf.h>
|
||||
#include <kernel/time.h>
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue