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
|
@rm -f $@.1 $@.2
|
||||||
@echo ${CL2}[$@] ${CL}Compiled.${CL3}
|
@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 ------------------------------------------------------------- #
|
## MAIN MAKEFILE ------------------------------------------------------------- #
|
||||||
|
|
||||||
$(KOBJDIR)/%.o: %.c $(INCLUDEDIR)/*/*.h | $(KOBJDIR)
|
$(KOBJDIR)/%.o: %.c $(INCLUDEDIR)/*/*.h | $(KOBJDIR)
|
||||||
|
|
|
@ -43,8 +43,7 @@ typedef struct BootInfo_t BootInfo_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;
|
||||||
typedef struct Processor_t Processor_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;
|
typedef enum ProcState_t ProcState_t;
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
@ -89,6 +88,23 @@ struct Processor_t
|
||||||
ListHead_t *timeCritProcs;
|
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
|
#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
|
uchar n; //number of entries in the list
|
||||||
|
|
||||||
struct entry {
|
struct entry {
|
||||||
void (*isr)(void);
|
void (*isr)(ISRFrame_t *regs);
|
||||||
uchar irq;
|
uchar irq;
|
||||||
uchar flags;
|
uchar flags;
|
||||||
} entry[224];
|
} 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
|
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 IdtSetup(void);
|
||||||
void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags);
|
void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags);
|
||||||
//void IdtHandler(ulong intNo);
|
void IdtExceptionHandler(ISRFrame_t *regs);
|
||||||
static void EnablePIC(void);
|
static void EnablePIC(void);
|
||||||
void SendEOItoPIC(uchar isr);
|
void SendEOItoPIC(uchar isr);
|
||||||
|
|
||||||
|
@ -148,5 +132,34 @@ extern void isr28();
|
||||||
extern void isr29();
|
extern void isr29();
|
||||||
extern void isr30();
|
extern void isr30();
|
||||||
extern void isr31();
|
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
|
#endif
|
||||||
|
|
|
@ -64,7 +64,7 @@ static inline ulong KePauseIRQs(void) {
|
||||||
extern void IoSendEOItoPIC(uchar isr);
|
extern void IoSendEOItoPIC(uchar isr);
|
||||||
extern void IoEnableNMI(void);
|
extern void IoEnableNMI(void);
|
||||||
extern void IoDisableNMI(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
|
// 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
|
// 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;
|
uchar n = irqList.n;
|
||||||
|
|
||||||
KalAssert(idt[0].flags==0); // IDT uninitialized
|
KalAssert(idt[0].flags!=0); // IDT initialized
|
||||||
|
|
||||||
if ((n == 224)) // IRQs not filled
|
if ((n == 224)) // IRQs not filled
|
||||||
KeStartPanic("[IdtRegisterIrq] Cannot register IRQ %c function %p !",
|
KeStartPanic("[IdtRegisterIrq] Cannot register IRQ %c function %p !",
|
||||||
|
@ -103,15 +103,36 @@ void IdtSetup(void)
|
||||||
IdtSetGate(30, (ulong)isr30, codeSeg, 0x8E); // INTEL RESERVED
|
IdtSetGate(30, (ulong)isr30, codeSeg, 0x8E); // INTEL RESERVED
|
||||||
IdtSetGate(31, (ulong)isr31, codeSeg, 0x8E); // INTEL RESERVED
|
IdtSetGate(31, (ulong)isr31, codeSeg, 0x8E); // INTEL RESERVED
|
||||||
|
|
||||||
// Set the IRQ Driver Gates
|
// Set IDT IRQs Gates
|
||||||
for (int i = 0 ; i < irqList.n ; i++) {
|
IdtSetGate(32, (ulong)isr32, codeSeg, 0x8E);
|
||||||
IdtSetGate(
|
IdtSetGate(33, (ulong)isr33, codeSeg, 0x8E);
|
||||||
irqList.entry[i].irq,
|
IdtSetGate(34, (ulong)isr34, codeSeg, 0x8E);
|
||||||
(ulong)irqList.entry[i].isr,
|
IdtSetGate(35, (ulong)isr35, codeSeg, 0x8E);
|
||||||
codeSeg,
|
IdtSetGate(36, (ulong)isr36, codeSeg, 0x8E);
|
||||||
irqList.entry[i].flags
|
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
|
// Load IDT
|
||||||
IdtInit();
|
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;
|
int recoverable = 0;
|
||||||
char *exceptionMsg = "Unhandled ISR exception";
|
char *exceptionMsg = "Unhandled ISR exception";
|
||||||
|
|
||||||
if (intNo >= 32) recoverable++;
|
exceptionMsg = IsrExceptions[regs->intNo];
|
||||||
|
|
||||||
if (intNo < 32) exceptionMsg = IsrExceptions[intNo];
|
|
||||||
|
|
||||||
if (!recoverable) {
|
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 {
|
} else {
|
||||||
bprintf(BStdOut, "[ISR 0x%x] %s\n", intNo, exceptionMsg);
|
bprintf(BStdOut, "[ISR 0x%x] %s\n", regs->intNo, exceptionMsg);
|
||||||
//IoSendEOItoPIC(intNo);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
global IdtInit
|
global IdtInit
|
||||||
global divideByZero
|
global divideByZero
|
||||||
extern idtPtr
|
extern idtPtr
|
||||||
extern IdtHandler
|
extern IsrHandler
|
||||||
extern label0
|
extern label0
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
@ -41,16 +41,14 @@ IdtInit:
|
||||||
;; Bug test
|
;; Bug test
|
||||||
;;
|
;;
|
||||||
divideByZero:
|
divideByZero:
|
||||||
pushAll
|
|
||||||
mov eax, 17
|
mov eax, 17
|
||||||
mov ebx, 0
|
mov ebx, 0
|
||||||
xor edx, edx
|
xor edx, edx
|
||||||
div ebx
|
div ebx
|
||||||
popAll
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; ISR handler
|
;; ISR Exception pre-handler
|
||||||
;;
|
;;
|
||||||
isrPreHandler:
|
isrPreHandler:
|
||||||
pushAll
|
pushAll
|
||||||
|
@ -71,7 +69,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 IdtHandler
|
call IsrHandler
|
||||||
|
|
||||||
; decrement mask count
|
; decrement mask count
|
||||||
dec qword [gs:8]
|
dec qword [gs:8]
|
||||||
|
@ -81,7 +79,7 @@ isrPreHandler:
|
||||||
and rax, 0x3000
|
and rax, 0x3000
|
||||||
jz .SExit
|
jz .SExit
|
||||||
|
|
||||||
swapgs
|
swapgs ; XXX need TSS
|
||||||
|
|
||||||
.SExit:
|
.SExit:
|
||||||
popAll
|
popAll
|
||||||
|
@ -164,3 +162,11 @@ IsrWithoutErrCode 29
|
||||||
IsrWithoutErrCode 30
|
IsrWithoutErrCode 30
|
||||||
IsrWithoutErrCode 31
|
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);
|
extern error_t IoInitVGABuffer(void);
|
||||||
|
|
||||||
//io/keyb.c
|
//io/keyb.c
|
||||||
extern void IoSetupKeyb(void);
|
|
||||||
extern void IoEnableKeyb(void);
|
extern void IoEnableKeyb(void);
|
||||||
|
|
||||||
// cpu/idt.c
|
// cpu/idt.c
|
||||||
|
@ -82,9 +81,6 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg)
|
||||||
MmInitHeap();
|
MmInitHeap();
|
||||||
PsInitSched();
|
PsInitSched();
|
||||||
|
|
||||||
// Drivers ISR inits
|
|
||||||
IoSetupRtc();
|
|
||||||
IoSetupKeyb();
|
|
||||||
// Interrupts launching
|
// Interrupts launching
|
||||||
IdtSetup();
|
IdtSetup();
|
||||||
KeEnableIRQs();
|
KeEnableIRQs();
|
||||||
|
@ -95,12 +91,14 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg)
|
||||||
IoPrintRtcTime();
|
IoPrintRtcTime();
|
||||||
|
|
||||||
KernLog("There was %d ticks\n", IoGetRtcTicks());
|
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) {
|
while (IoGetRtcTicks() < i * 10000) {
|
||||||
}
|
}
|
||||||
IoPrintRtcTime();
|
IoPrintRtcTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
divideByZero();
|
||||||
|
|
||||||
KernLog("Goodbye after %d ticks\n", IoGetRtcTicks());
|
KernLog("Goodbye after %d ticks\n", IoGetRtcTicks());
|
||||||
// End this machine's suffering
|
// End this machine's suffering
|
||||||
BFlushBuf(BStdOut);
|
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 <kernel/iomisc.h>
|
||||||
#include <extras/buf.h>
|
#include <extras/buf.h>
|
||||||
|
|
||||||
extern void KeybIsr(void);
|
|
||||||
char ScanCodes[100] = { 0 };
|
char ScanCodes[100] = { 0 };
|
||||||
|
|
||||||
void IoSetupKeyb(void)
|
|
||||||
{
|
|
||||||
IdtRegisterIrq(KeybIsr, 0x21, 0x8E);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeybPrint(char code)
|
void KeybPrint(char code)
|
||||||
{
|
{
|
||||||
if (code) {
|
if (code) {
|
||||||
|
@ -88,17 +82,7 @@ void ScanCodesInit(void)
|
||||||
ScanCodes[0x39] = ' ';
|
ScanCodes[0x39] = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
void IoEnableKeyb(void)
|
void KeybHandler(ISRFrame_t *regs)
|
||||||
{
|
|
||||||
ulong flags = KePauseIRQs();
|
|
||||||
char readedInterruptConfig = IoReadByteFromPort(0x21);
|
|
||||||
IoWriteByteOnPort(0x21, 0xFD & readedInterruptConfig);
|
|
||||||
KeRestoreIRQs(flags);
|
|
||||||
IoEnableNMI();
|
|
||||||
ScanCodesInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeybHandler(void)
|
|
||||||
{
|
{
|
||||||
char status;
|
char status;
|
||||||
char code = 0;
|
char code = 0;
|
||||||
|
@ -116,3 +100,14 @@ void KeybHandler(void)
|
||||||
KeybPrint((int)code);
|
KeybPrint((int)code);
|
||||||
IoSendEOItoPIC(0x21);
|
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 <extras/buf.h>
|
||||||
#include <kernel/time.h>
|
#include <kernel/time.h>
|
||||||
|
|
||||||
extern void RtcIsr(void);
|
|
||||||
|
|
||||||
static ulong IoRtcTicks = 0;
|
static ulong IoRtcTicks = 0;
|
||||||
static uchar RtcRate = 0x05; //2048Hz
|
static uchar RtcRate = 0x05; //2048Hz
|
||||||
static Time_t IoRtcOriginTime;
|
static Time_t IoRtcOriginTime;
|
||||||
static Time_t IoRtcTime;
|
static Time_t IoRtcTime;
|
||||||
static char time24or12Mode;
|
static char time24or12Mode;
|
||||||
void IoSetupRtc(void)
|
|
||||||
{
|
|
||||||
IdtRegisterIrq(RtcIsr, 0x28, 0x8E);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void GetTimeFromRtc(void)
|
static void GetTimeFromRtc(void)
|
||||||
{
|
{
|
||||||
|
@ -143,45 +137,7 @@ static void GetTimeFromRtc(void)
|
||||||
IoRtcTime.century = IoRtcOriginTime.century;
|
IoRtcTime.century = IoRtcOriginTime.century;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IoEnableRtc(void)
|
void RtcHandler(ISRFrame_t *regs)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
//bprintf(BStdOut, " *RTC - ");
|
//bprintf(BStdOut, " *RTC - ");
|
||||||
IoWriteByteOnPort(0x70, 0x0C); // Selects status reg C
|
IoWriteByteOnPort(0x70, 0x0C); // Selects status reg C
|
||||||
|
@ -258,4 +214,44 @@ ulong IoGetRtcTicks(void)
|
||||||
return IoRtcTicks;
|
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