[GOOD] BUILD 0.1.0.450 DATE 8/29/2011 AT 10:30 AM
==================================================== + Changed 'align 0x4' line above multiboot header in loader.asm to 'align 4' + Removed -e option for echo in build.sh + Modified build.sh for linux + Fixed triple fault when enabling paging + Fixed page faults at memory manager initialization + Fixed 'mem' console function + Added more info about page fault at crash screen + Added Panic() macro + Added verbose mode for memory manager [ BAD] BUILD 0.1.0.390 DATE 8/27/2011 AT 10:54 PM ==================================================== + Added stdlib routines, separated in different files + Rewritten physical memory manager + Added virtual mem manager + Added memory allocation/freeing + Added memory library + Added temporary allocation (at end of kernel), until paging is started - Removed functionality from debug console function 'mem' - Removed system.h, the one remaining function now in stdio.h
This commit is contained in:
19
Kernel/hal/clock/clock.c
Normal file
19
Kernel/hal/clock/clock.c
Normal file
@ -0,0 +1,19 @@
|
||||
#include <time.h>
|
||||
#include "clock.h"
|
||||
|
||||
#define MILISECONDS_IN_DAY 86400000
|
||||
|
||||
volatile TimeSystem _internal_time;
|
||||
uint32 _internal_frequency_hz;
|
||||
|
||||
void TimeHandler(_RegsStack32* UNUSED(r))
|
||||
{
|
||||
if (_internal_frequency_hz == 0) return;
|
||||
|
||||
_internal_time.Time += 1000/_internal_frequency_hz;
|
||||
if (_internal_time.Time >= MILISECONDS_IN_DAY)
|
||||
{
|
||||
_internal_time.Date++;
|
||||
_internal_time.Time-=MILISECONDS_IN_DAY;
|
||||
}
|
||||
}
|
9
Kernel/hal/clock/clock.h
Normal file
9
Kernel/hal/clock/clock.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef __CLOCK__H
|
||||
#define __CLOCK__H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
extern void TimeHandler(_RegsStack32 *r);
|
||||
|
||||
|
||||
#endif
|
23
Kernel/hal/cpu/gdt-asm.asm
Normal file
23
Kernel/hal/cpu/gdt-asm.asm
Normal file
@ -0,0 +1,23 @@
|
||||
; GLOBAL DESCRIPTOR TABLE
|
||||
;
|
||||
;
|
||||
|
||||
bits 32
|
||||
; !!! GDT !!!
|
||||
; This will set up our new segment registers. We need to do
|
||||
; something special in order to set CS. We do what is called a
|
||||
; far jump. A jump that includes a segment as well as an offset.
|
||||
|
||||
global GdtFlush ; Allows the C code to link to this
|
||||
extern gp ; Says that 'gp' is in another file
|
||||
GdtFlush:
|
||||
lgdt [gp] ; Load the GDT with our 'gp' which is a special pointer
|
||||
mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
jmp 0x08:flush2 ; 0x08 is the offset to our code segment: Far jump!
|
||||
flush2:
|
||||
ret ; Returns back to the C code!
|
74
Kernel/hal/cpu/gdt.c
Normal file
74
Kernel/hal/cpu/gdt.c
Normal file
@ -0,0 +1,74 @@
|
||||
/******************************************************************
|
||||
* gdt.c - GLOBAL DESCRIPTOR TABLE *
|
||||
* Contains function prototypes for setting up the GDT *
|
||||
******************************************************************/
|
||||
#define MAX_DESCRIPTORS 5
|
||||
#include "gdt.h"
|
||||
|
||||
/* Our GDT, with 3 entries, and finally our special GDT pointer */
|
||||
struct GdtEntry gdt[MAX_DESCRIPTORS];
|
||||
struct GdtPointer gp;
|
||||
|
||||
|
||||
/* Setup a descriptor in the Global Descriptor Table */
|
||||
void GdtSetGate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran)
|
||||
{
|
||||
/* Sanity check */
|
||||
if (num >= MAX_DESCRIPTORS) return;
|
||||
|
||||
/* Setup the descriptor base address */
|
||||
gdt[num].base_low = (base & 0xFFFF);
|
||||
gdt[num].base_middle = (base >> 16) & 0xFF;
|
||||
gdt[num].base_high = (base >> 24) & 0xFF;
|
||||
|
||||
/* Setup the descriptor limits */
|
||||
gdt[num].limit_low = (limit & 0xFFFF);
|
||||
gdt[num].granularity = ((limit >> 16) & 0x0F);
|
||||
|
||||
/* Finally, set up the granularity and access flags */
|
||||
gdt[num].granularity |= (gran & 0xF0);
|
||||
gdt[num].access = access;
|
||||
}
|
||||
|
||||
struct GdtEntry* GdtGetGate(int num)
|
||||
{
|
||||
if (num>MAX_DESCRIPTORS) return 0;
|
||||
return &gdt[num];
|
||||
}
|
||||
|
||||
/* Should be called by main. This will setup the special GDT
|
||||
* pointer, set up the first 3 entries in our GDT, and then
|
||||
* finally call gdt_flush() in our assembler file in order
|
||||
* to tell the processor where the new GDT is and update the
|
||||
* new segment registers */
|
||||
void GdtInstall()
|
||||
{
|
||||
/* Setup the GDT pointer and limit */
|
||||
gp.limit = (sizeof(struct GdtEntry) * 3) - 1;
|
||||
gp.base = (unsigned int)&gdt;
|
||||
|
||||
/* Our NULL descriptor */
|
||||
GdtSetGate(0, 0, 0, 0, 0);
|
||||
|
||||
/* The second entry is our Code Segment. The base address
|
||||
* is 0, the limit is 4GBytes, it uses 4KByte granularity,
|
||||
* uses 32-bit opcodes, and is a Code Segment descriptor.
|
||||
* Please check the table above in the tutorial in order
|
||||
* to see exactly what each value means */
|
||||
GdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
|
||||
|
||||
/* The third entry is our Data Segment. It's EXACTLY the
|
||||
* same as our code segment, but the descriptor type in
|
||||
* this entry's access byte says it's a Data Segment */
|
||||
GdtSetGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
|
||||
|
||||
/* User mode Code segment*/
|
||||
GdtSetGate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
|
||||
|
||||
/* User mode data segment*/
|
||||
GdtSetGate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
|
||||
|
||||
/* Flush out the old GDT and install the new changes! */
|
||||
GdtFlush();
|
||||
}
|
||||
|
38
Kernel/hal/cpu/gdt.h
Normal file
38
Kernel/hal/cpu/gdt.h
Normal file
@ -0,0 +1,38 @@
|
||||
/******************************************************************
|
||||
* gdt.h - GLOBAL DESCRIPTOR TABLE *
|
||||
* Contains structures and function declarations for GDT *
|
||||
******************************************************************/
|
||||
|
||||
#ifndef __GDT_H
|
||||
#define __GDT_H
|
||||
|
||||
/* Defines a GDT entry. We say packed, because it prevents the
|
||||
* compiler from doing things that it thinks is best: Prevent
|
||||
* compiler "optimization" by packing */
|
||||
struct GdtEntry
|
||||
{
|
||||
unsigned short limit_low;
|
||||
unsigned short base_low;
|
||||
unsigned char base_middle;
|
||||
unsigned char access;
|
||||
unsigned char granularity;
|
||||
unsigned char base_high;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Special pointer which includes the limit: The max bytes
|
||||
* taken up by the GDT, minus 1. Again, this NEEDS to be packed */
|
||||
struct GdtPointer
|
||||
{
|
||||
unsigned short limit;
|
||||
unsigned int base;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
/* This will be a function in start.asm. We use this to properly
|
||||
* reload the new segment registers */
|
||||
extern void GdtInstall();
|
||||
extern void GdtFlush();
|
||||
extern void GdtSetGate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);
|
||||
extern struct GdtEntry* GdtGetGate(int num);
|
||||
|
||||
#endif
|
9
Kernel/hal/cpu/idt-asm.asm
Normal file
9
Kernel/hal/cpu/idt-asm.asm
Normal file
@ -0,0 +1,9 @@
|
||||
bits 32
|
||||
|
||||
; !!! IDT !!!
|
||||
; Loads the IDT defined in '_idtp'
|
||||
global IdtLoad
|
||||
extern idtp
|
||||
IdtLoad:
|
||||
lidt [idtp]
|
||||
ret
|
45
Kernel/hal/cpu/idt.c
Normal file
45
Kernel/hal/cpu/idt.c
Normal file
@ -0,0 +1,45 @@
|
||||
/******************************************************************
|
||||
* idt.h - INTERRUPT DESCRIPTOR TABLE *
|
||||
* Contains structures and function declarations for IDT *
|
||||
******************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include "idt.h"
|
||||
|
||||
extern void IdtLoad();
|
||||
/* Declare an IDT of 256 entries. */
|
||||
struct IdtEntry idt[256];
|
||||
struct IdtPointer idtp;
|
||||
|
||||
/* Use this function to set an entry in the IDT. Alot simpler
|
||||
* than twiddling with the GDT ;) */
|
||||
void IdtSetGate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags)
|
||||
{
|
||||
/* The interrupt routine's base address */
|
||||
idt[num].base_lo = (base & 0xFFFF);
|
||||
idt[num].base_hi = (base >> 16) & 0xFFFF;
|
||||
|
||||
/* The segment or 'selector' that this IDT entry will use
|
||||
* is set here, along with any access flags */
|
||||
idt[num].sel = sel;
|
||||
idt[num].always0 = 0;
|
||||
idt[num].flags = flags;
|
||||
}
|
||||
|
||||
struct IdtEntry* IdtGetGate(unsigned char num)
|
||||
{
|
||||
return &idt[num];
|
||||
}
|
||||
|
||||
/* Installs the IDT */
|
||||
void IdtInstall()
|
||||
{
|
||||
/* Sets the special IDT pointer up, just like in 'gdt.c' */
|
||||
idtp.limit = (sizeof (struct IdtEntry) * 256) - 1;
|
||||
idtp.base = (unsigned int)&idt;
|
||||
|
||||
/* Clear out the entire IDT, initializing it to zeros */
|
||||
memset (&idt, 0, sizeof(struct IdtEntry) * 256);
|
||||
|
||||
/* Points the processor's internal register to the new IDT */
|
||||
IdtLoad();
|
||||
}
|
31
Kernel/hal/cpu/idt.h
Normal file
31
Kernel/hal/cpu/idt.h
Normal file
@ -0,0 +1,31 @@
|
||||
/******************************************************************
|
||||
* idt.h - INTERRUPT DESCRIPTOR TABLE *
|
||||
* Contains structures and function declarations for IDT *
|
||||
******************************************************************/
|
||||
|
||||
#ifndef __IDT_H
|
||||
#define __IDT_H
|
||||
|
||||
/* Defines an IDT entry */
|
||||
struct IdtEntry
|
||||
{
|
||||
unsigned short base_lo;
|
||||
unsigned short sel;
|
||||
unsigned char always0;
|
||||
unsigned char flags;
|
||||
unsigned short base_hi;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct IdtPointer
|
||||
{
|
||||
unsigned short limit;
|
||||
unsigned int base;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
/* This exists in 'start.asm', and is used to load our IDT */
|
||||
extern void IdtSetGate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags);
|
||||
extern struct IdtEntry* IdtGetGate(unsigned char num);
|
||||
extern void IdtInstall();
|
||||
|
||||
#endif
|
159
Kernel/hal/cpu/irq-asm.asm
Normal file
159
Kernel/hal/cpu/irq-asm.asm
Normal file
@ -0,0 +1,159 @@
|
||||
bits 32
|
||||
|
||||
; !!! IRQ !!!
|
||||
global Irq_0
|
||||
global Irq_1
|
||||
global Irq_2
|
||||
global Irq_3
|
||||
global Irq_4
|
||||
global Irq_5
|
||||
global Irq_6
|
||||
global Irq_7
|
||||
global Irq_8
|
||||
global Irq_9
|
||||
global Irq_10
|
||||
global Irq_11
|
||||
global Irq_12
|
||||
global Irq_13
|
||||
global Irq_14
|
||||
global Irq_15
|
||||
|
||||
; 32: IRQ0
|
||||
Irq_0:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 32; Note that these don't push an error code on the stack:
|
||||
; We need to push a dummy error code
|
||||
jmp irq_common_stub
|
||||
|
||||
; 33: IRQ1
|
||||
Irq_1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 33
|
||||
jmp irq_common_stub
|
||||
|
||||
; 34: IRQ2
|
||||
Irq_2:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 34
|
||||
jmp irq_common_stub
|
||||
|
||||
; 35: IRQ3
|
||||
Irq_3:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 35
|
||||
jmp irq_common_stub
|
||||
|
||||
; 36: IRQ4
|
||||
Irq_4:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 36
|
||||
jmp irq_common_stub
|
||||
|
||||
; 37: IRQ5
|
||||
Irq_5:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 37
|
||||
jmp irq_common_stub
|
||||
|
||||
; 38: IRQ6
|
||||
Irq_6:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 38
|
||||
jmp irq_common_stub
|
||||
|
||||
; 39: IRQ7
|
||||
Irq_7:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 39
|
||||
jmp irq_common_stub
|
||||
|
||||
; 40: IRQ8
|
||||
Irq_8:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 40
|
||||
jmp irq_common_stub
|
||||
; 41: IRQ9
|
||||
Irq_9:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 41
|
||||
jmp irq_common_stub
|
||||
|
||||
; 42: IRQ10
|
||||
Irq_10:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 42
|
||||
jmp irq_common_stub
|
||||
|
||||
; 43: IRQ11
|
||||
Irq_11:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 43
|
||||
jmp irq_common_stub
|
||||
|
||||
; 44: IRQ12
|
||||
Irq_12:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 44
|
||||
jmp irq_common_stub
|
||||
|
||||
; 45: IRQ13
|
||||
Irq_13:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 45
|
||||
jmp irq_common_stub
|
||||
|
||||
; 46: IRQ14
|
||||
Irq_14:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 46
|
||||
jmp irq_common_stub
|
||||
|
||||
; 47: IRQ15
|
||||
Irq_15:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 47
|
||||
jmp irq_common_stub
|
||||
|
||||
extern IrqHandler
|
||||
|
||||
; This is a stub that we have created for IRQ based ISRs. This calls
|
||||
; 'Irq__handler' in our C code. We need to create this in an 'irq.c'
|
||||
irq_common_stub:
|
||||
pusha
|
||||
push ds
|
||||
push es
|
||||
push fs
|
||||
push gs
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov eax, esp
|
||||
push eax
|
||||
mov eax, IrqHandler
|
||||
call eax
|
||||
pop eax
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
add esp, 8
|
||||
iret
|
91
Kernel/hal/cpu/irq.c
Normal file
91
Kernel/hal/cpu/irq.c
Normal file
@ -0,0 +1,91 @@
|
||||
#include <stdio.h>
|
||||
#include "pic.h"
|
||||
#include "irq.h"
|
||||
#include "idt.h"
|
||||
|
||||
/* These are own ISRs that point to our special IRQ handler
|
||||
* instead of the regular 'fault_handler' function */
|
||||
extern void Irq_0();
|
||||
extern void Irq_1();
|
||||
extern void Irq_2();
|
||||
extern void Irq_3();
|
||||
extern void Irq_4();
|
||||
extern void Irq_5();
|
||||
extern void Irq_6();
|
||||
extern void Irq_7();
|
||||
extern void Irq_8();
|
||||
extern void Irq_9();
|
||||
extern void Irq_10();
|
||||
extern void Irq_11();
|
||||
extern void Irq_12();
|
||||
extern void Irq_13();
|
||||
extern void Irq_14();
|
||||
extern void Irq_15();
|
||||
|
||||
/* This array is actually an array of function pointers. We use
|
||||
* this to handle custom IRQ handlers for a given IRQ */
|
||||
void *IrqRoutines[16] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* This installs a custom IRQ handler for the given IRQ */
|
||||
void IrqInstallHandler (int irq, void (*handler)(_RegsStack32 *r))
|
||||
{
|
||||
IrqRoutines[irq] = handler;
|
||||
}
|
||||
|
||||
void IrqUninstallHandler (int irq)
|
||||
{
|
||||
IrqRoutines[irq] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* We first remap the interrupt controllers, and then we install
|
||||
* the appropriate ISRs to the correct entries in the IDT. This
|
||||
* is just like installing the exception handlers */
|
||||
void IrqInstall()
|
||||
{
|
||||
PicRemap(32,40);
|
||||
|
||||
IdtSetGate(32, (unsigned)Irq_0, 0x08, 0x8E);
|
||||
IdtSetGate(33, (unsigned)Irq_1, 0x08, 0x8E);
|
||||
IdtSetGate(34, (unsigned)Irq_2, 0x08, 0x8E);
|
||||
IdtSetGate(35, (unsigned)Irq_3, 0x08, 0x8E);
|
||||
IdtSetGate(36, (unsigned)Irq_4, 0x08, 0x8E);
|
||||
IdtSetGate(37, (unsigned)Irq_5, 0x08, 0x8E);
|
||||
IdtSetGate(38, (unsigned)Irq_6, 0x08, 0x8E);
|
||||
IdtSetGate(39, (unsigned)Irq_7, 0x08, 0x8E);
|
||||
IdtSetGate(40, (unsigned)Irq_8, 0x08, 0x8E);
|
||||
IdtSetGate(41, (unsigned)Irq_9, 0x08, 0x8E);
|
||||
IdtSetGate(42, (unsigned)Irq_10, 0x08, 0x8E);
|
||||
IdtSetGate(43, (unsigned)Irq_11, 0x08, 0x8E);
|
||||
IdtSetGate(44, (unsigned)Irq_12, 0x08, 0x8E);
|
||||
IdtSetGate(45, (unsigned)Irq_13, 0x08, 0x8E);
|
||||
IdtSetGate(46, (unsigned)Irq_14, 0x08, 0x8E);
|
||||
IdtSetGate(47, (unsigned)Irq_15, 0x08, 0x8E);
|
||||
}
|
||||
|
||||
// Default IRQ handler, launches other handler if installed.
|
||||
// Also sends end-of-interrupt messages to PIC
|
||||
void IrqHandler (_RegsStack32 *r)
|
||||
{
|
||||
/* This is a blank function pointer */
|
||||
void (*handler)(_RegsStack32 *r);
|
||||
|
||||
/* Find out if we have a custom handler to run for this
|
||||
* IRQ, and then finally, run it */
|
||||
handler = IrqRoutines[r->int_no - 32];
|
||||
if (handler) handler(r);
|
||||
|
||||
/* If the IDT entry that was invoked was greater than 40
|
||||
* (meaning IRQ8 - 15), then we need to send an EOI to
|
||||
* the slave controller */
|
||||
if (r->int_no >=40) outportb(0xA0, 0x20);
|
||||
|
||||
/* In either case, we need to send an EOI to the master
|
||||
* interrupt controller too */
|
||||
outportb(0x20, 0x20);
|
||||
}
|
10
Kernel/hal/cpu/irq.h
Normal file
10
Kernel/hal/cpu/irq.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef __IRQ_H
|
||||
#define __IRQ_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
extern void IrqInstallHandler (int irq, void (*handler)(_RegsStack32 *r));
|
||||
extern void IrqUninstallHandler (int irq);
|
||||
extern void IrqInstall();
|
||||
|
||||
#endif
|
217
Kernel/hal/cpu/isrs-asm.asm
Normal file
217
Kernel/hal/cpu/isrs-asm.asm
Normal file
@ -0,0 +1,217 @@
|
||||
bits 32
|
||||
|
||||
; !!! ISRs !!!
|
||||
global isr_exception_0
|
||||
global isr_exception_1
|
||||
global isr_exception_2
|
||||
global isr_exception_3
|
||||
global isr_exception_4
|
||||
global isr_exception_5
|
||||
global isr_exception_6
|
||||
global isr_exception_7
|
||||
global isr_exception_8
|
||||
global isr_exception_9
|
||||
global isr_exception_10
|
||||
global isr_exception_11
|
||||
global isr_exception_12
|
||||
global isr_exception_13
|
||||
global isr_exception_14
|
||||
global isr_exception_15
|
||||
global isr_exception_16
|
||||
global isr_exception_17
|
||||
global isr_exception_18
|
||||
global isr_exception_19
|
||||
global isr_exception_20
|
||||
global isr_exception_21
|
||||
global isr_exception_22
|
||||
global isr_exception_23
|
||||
global isr_exception_24
|
||||
global isr_exception_25
|
||||
global isr_exception_26
|
||||
global isr_exception_27
|
||||
global isr_exception_28
|
||||
global isr_exception_29
|
||||
global isr_exception_30
|
||||
global isr_exception_31
|
||||
|
||||
isr_exception_0:
|
||||
cli
|
||||
push byte 0; A normal ISR stub that pops a dummy error code to keep a
|
||||
; uniform stack frame
|
||||
push byte 0
|
||||
jmp isr_common_stub
|
||||
isr_exception_1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 1
|
||||
jmp isr_common_stub
|
||||
isr_exception_2:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 2
|
||||
jmp isr_common_stub
|
||||
isr_exception_3:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 3
|
||||
jmp isr_common_stub
|
||||
isr_exception_4:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 4
|
||||
jmp isr_common_stub
|
||||
isr_exception_5:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 5
|
||||
jmp isr_common_stub
|
||||
isr_exception_6:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 6
|
||||
jmp isr_common_stub
|
||||
isr_exception_7:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 7
|
||||
jmp isr_common_stub
|
||||
isr_exception_8:
|
||||
cli
|
||||
push byte 8
|
||||
jmp isr_common_stub
|
||||
isr_exception_9:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 9
|
||||
jmp isr_common_stub
|
||||
isr_exception_10:
|
||||
cli
|
||||
push byte 10
|
||||
jmp isr_common_stub
|
||||
isr_exception_11:
|
||||
cli
|
||||
push byte 11
|
||||
jmp isr_common_stub
|
||||
isr_exception_12:
|
||||
cli
|
||||
push byte 12
|
||||
jmp isr_common_stub
|
||||
isr_exception_13:
|
||||
cli
|
||||
push byte 13
|
||||
jmp isr_common_stub
|
||||
isr_exception_14:
|
||||
cli
|
||||
push byte 14
|
||||
jmp isr_common_stub
|
||||
isr_exception_15:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 15
|
||||
jmp isr_common_stub
|
||||
isr_exception_16:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 16
|
||||
jmp isr_common_stub
|
||||
isr_exception_17:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 17
|
||||
jmp isr_common_stub
|
||||
isr_exception_18:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 18
|
||||
jmp isr_common_stub
|
||||
isr_exception_19:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 19
|
||||
jmp isr_common_stub
|
||||
isr_exception_20:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 20
|
||||
jmp isr_common_stub
|
||||
isr_exception_21:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 21
|
||||
jmp isr_common_stub
|
||||
isr_exception_22:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 22
|
||||
jmp isr_common_stub
|
||||
isr_exception_23:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 23
|
||||
jmp isr_common_stub
|
||||
isr_exception_24:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 24
|
||||
jmp isr_common_stub
|
||||
isr_exception_25:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 25
|
||||
jmp isr_common_stub
|
||||
isr_exception_26:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 26
|
||||
jmp isr_common_stub
|
||||
isr_exception_27:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 27
|
||||
jmp isr_common_stub
|
||||
isr_exception_28:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 28
|
||||
jmp isr_common_stub
|
||||
isr_exception_29:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 29
|
||||
jmp isr_common_stub
|
||||
isr_exception_30:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 30
|
||||
jmp isr_common_stub
|
||||
isr_exception_31:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 31
|
||||
jmp isr_common_stub
|
||||
|
||||
extern IsrsFaultHandler
|
||||
|
||||
isr_common_stub:
|
||||
pusha
|
||||
push ds
|
||||
push es
|
||||
push fs
|
||||
push gs
|
||||
mov ax, 0x10 ; Load the Kernel Data Segment descriptor!
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov eax, esp ; Push us the stack
|
||||
push eax
|
||||
mov eax, IsrsFaultHandler
|
||||
call eax ; A special call, preserves the 'eip' register
|
||||
pop eax
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
|
||||
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP!
|
114
Kernel/hal/cpu/isrs.c
Normal file
114
Kernel/hal/cpu/isrs.c
Normal file
@ -0,0 +1,114 @@
|
||||
#include <debugio.h>
|
||||
|
||||
#include "isrs.h"
|
||||
#include "idt.h"
|
||||
|
||||
// Assembly coded
|
||||
extern void isr_exception_0();
|
||||
extern void isr_exception_1();
|
||||
extern void isr_exception_2();
|
||||
extern void isr_exception_3();
|
||||
extern void isr_exception_4();
|
||||
extern void isr_exception_5();
|
||||
extern void isr_exception_6();
|
||||
extern void isr_exception_7();
|
||||
extern void isr_exception_8();
|
||||
extern void isr_exception_9();
|
||||
extern void isr_exception_10();
|
||||
extern void isr_exception_11();
|
||||
extern void isr_exception_12();
|
||||
extern void isr_exception_13();
|
||||
extern void isr_exception_14();
|
||||
extern void isr_exception_15();
|
||||
extern void isr_exception_16();
|
||||
extern void isr_exception_17();
|
||||
extern void isr_exception_18();
|
||||
extern void isr_exception_19();
|
||||
extern void isr_exception_20();
|
||||
extern void isr_exception_21();
|
||||
extern void isr_exception_22();
|
||||
extern void isr_exception_23();
|
||||
extern void isr_exception_24();
|
||||
extern void isr_exception_25();
|
||||
extern void isr_exception_26();
|
||||
extern void isr_exception_27();
|
||||
extern void isr_exception_28();
|
||||
extern void isr_exception_29();
|
||||
extern void isr_exception_30();
|
||||
extern void isr_exception_31();
|
||||
|
||||
|
||||
void* IdtFaultHandlers[32] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
void IsrsInstall()
|
||||
{
|
||||
IdtSetGate(0, (unsigned)isr_exception_0, 0x08, 0x8E);
|
||||
IdtSetGate(1, (unsigned)isr_exception_1, 0x08, 0x8E);
|
||||
IdtSetGate(2, (unsigned)isr_exception_2, 0x08, 0x8E);
|
||||
IdtSetGate(3, (unsigned)isr_exception_3, 0x08, 0x8E);
|
||||
IdtSetGate(4, (unsigned)isr_exception_4, 0x08, 0x8E);
|
||||
IdtSetGate(5, (unsigned)isr_exception_5, 0x08, 0x8E);
|
||||
IdtSetGate(6, (unsigned)isr_exception_6, 0x08, 0x8E);
|
||||
IdtSetGate(7, (unsigned)isr_exception_7, 0x08, 0x8E);
|
||||
IdtSetGate(8, (unsigned)isr_exception_8, 0x08, 0x8E);
|
||||
IdtSetGate(9, (unsigned)isr_exception_9, 0x08, 0x8E);
|
||||
IdtSetGate(10, (unsigned)isr_exception_10, 0x08, 0x8E);
|
||||
IdtSetGate(11, (unsigned)isr_exception_11, 0x08, 0x8E);
|
||||
IdtSetGate(12, (unsigned)isr_exception_12, 0x08, 0x8E);
|
||||
IdtSetGate(13, (unsigned)isr_exception_13, 0x08, 0x8E);
|
||||
IdtSetGate(14, (unsigned)isr_exception_14, 0x08, 0x8E);
|
||||
IdtSetGate(15, (unsigned)isr_exception_15, 0x08, 0x8E);
|
||||
IdtSetGate(16, (unsigned)isr_exception_16, 0x08, 0x8E);
|
||||
IdtSetGate(17, (unsigned)isr_exception_17, 0x08, 0x8E);
|
||||
IdtSetGate(18, (unsigned)isr_exception_18, 0x08, 0x8E);
|
||||
IdtSetGate(19, (unsigned)isr_exception_19, 0x08, 0x8E);
|
||||
IdtSetGate(20, (unsigned)isr_exception_20, 0x08, 0x8E);
|
||||
IdtSetGate(21, (unsigned)isr_exception_21, 0x08, 0x8E);
|
||||
IdtSetGate(22, (unsigned)isr_exception_22, 0x08, 0x8E);
|
||||
IdtSetGate(23, (unsigned)isr_exception_23, 0x08, 0x8E);
|
||||
IdtSetGate(24, (unsigned)isr_exception_24, 0x08, 0x8E);
|
||||
IdtSetGate(25, (unsigned)isr_exception_25, 0x08, 0x8E);
|
||||
IdtSetGate(26, (unsigned)isr_exception_26, 0x08, 0x8E);
|
||||
IdtSetGate(27, (unsigned)isr_exception_27, 0x08, 0x8E);
|
||||
IdtSetGate(28, (unsigned)isr_exception_28, 0x08, 0x8E);
|
||||
IdtSetGate(29, (unsigned)isr_exception_29, 0x08, 0x8E);
|
||||
IdtSetGate(30, (unsigned)isr_exception_30, 0x08, 0x8E);
|
||||
IdtSetGate(31, (unsigned)isr_exception_31, 0x08, 0x8E);
|
||||
}
|
||||
|
||||
|
||||
void IsrsInstallHandler(int interr, void (*function)(_RegsStack32 *r))
|
||||
{
|
||||
if (interr < 32) IdtFaultHandlers[interr] = function;
|
||||
}
|
||||
|
||||
|
||||
void IsrsUninstallHandler(int interr)
|
||||
{
|
||||
if (interr < 32) IdtFaultHandlers[interr] = 0;
|
||||
}
|
||||
|
||||
|
||||
extern void CrashMessage(_RegsStack32 *r);
|
||||
// Default fault handler; calls other handlers, or displays error message.
|
||||
void IsrsFaultHandler(_RegsStack32 *r)
|
||||
{
|
||||
/* Is this a fault whose number is from 0 to 31? */
|
||||
if (r->int_no < 32)
|
||||
{
|
||||
void (*func)(_RegsStack32 *r);
|
||||
func = IdtFaultHandlers[r->int_no];
|
||||
|
||||
// Halt system if unhandled
|
||||
if (!func) {
|
||||
CrashMessage(r);
|
||||
asm ("cli");
|
||||
asm ("hlt");
|
||||
}
|
||||
|
||||
else (*func)(r);
|
||||
}
|
||||
}
|
10
Kernel/hal/cpu/isrs.h
Normal file
10
Kernel/hal/cpu/isrs.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef __ISRS_H_
|
||||
#define __ISRS_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
extern void IsrsInstall();
|
||||
extern void IsrsInstallHandler(int interr, void (*function)(_RegsStack32 *r));
|
||||
extern void IsrsUninstallHandler(int interr);
|
||||
|
||||
#endif
|
23
Kernel/hal/cpu/pic.c
Normal file
23
Kernel/hal/cpu/pic.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include <stdio.h>
|
||||
#include "pic.h"
|
||||
|
||||
void PicRemap(int pic1, int pic2)
|
||||
{
|
||||
// Send ICW1
|
||||
outportb(0x20, 0x11);
|
||||
outportb(0xA0, 0x11);
|
||||
|
||||
// send ICW2
|
||||
outportb(0x21, pic1); // remap pics
|
||||
outportb(0xA1, pic2);
|
||||
|
||||
// send ICW3
|
||||
outportb(0x21, 4);
|
||||
outportb(0xA1, 2);
|
||||
|
||||
// Send ICW4
|
||||
outportb(0x21, 0x01);
|
||||
outportb(0xA1, 0x01);
|
||||
|
||||
outportb(0x21, 0x00);
|
||||
}
|
6
Kernel/hal/cpu/pic.h
Normal file
6
Kernel/hal/cpu/pic.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef _PIC_H
|
||||
#define _PIC_H
|
||||
|
||||
extern void PicRemap(int pic1, int pic2);
|
||||
|
||||
#endif
|
96
Kernel/hal/crash.c
Normal file
96
Kernel/hal/crash.c
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* crash.c
|
||||
*
|
||||
* Created on: Aug 19, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <debugio.h>
|
||||
|
||||
string errorCodes[] =
|
||||
{
|
||||
"Division by zero", //0
|
||||
"Debugger", //1
|
||||
"Non maskable interrupt", //2
|
||||
"Breakpoint", //3
|
||||
"Overflow", //4
|
||||
"Bounds", //5
|
||||
"Invalid opcode", //6
|
||||
"Coprocessor not available", //7
|
||||
"Double fault", //8
|
||||
"Coprocessor segment overrun",//9
|
||||
"Invalid task state segment", //A
|
||||
"Segment not present", //B
|
||||
"Stack fault", //C
|
||||
"General protection fault", //D
|
||||
"Page fault", //E
|
||||
"", //F
|
||||
"Math fault", //10
|
||||
"Alignment check", //11
|
||||
"Machine check", //12
|
||||
"SIMD floating-point exception" //13
|
||||
};
|
||||
|
||||
void CrashMessage(_RegsStack32 *r)
|
||||
{
|
||||
ConsoleSetDefaultColor(ColorLightRed);
|
||||
ConsoleWrite("\n"); uint32 i;
|
||||
for (i = 0; i < 80; i++) ConsoleWrite("%c", 205);
|
||||
|
||||
ConsoleWrite("%#\t\t\t\tSomething went terribly wrong :(\n\n", ColorWhite);
|
||||
ConsoleWrite("There was an unhandled exception: ");
|
||||
|
||||
if (r->int_no < 20)
|
||||
ConsoleWrite("%#%s (INT%u)", ColorWhite, errorCodes[r->int_no], r->int_no);
|
||||
else ConsoleWrite("%#INT%u", ColorWhite, r->int_no);
|
||||
|
||||
ConsoleWrite("\nTo protect your computer, it had to be halted.\n\n");
|
||||
ConsoleWrite("Here, this might help find the problem:\n");
|
||||
|
||||
Point a = {4, -1}, b = {22, -1}, c = {40, -1}, d = {58, -1};
|
||||
|
||||
ConsoleSetDefaultColor(ColorWhite);
|
||||
ConsoleCursorGoto(a); ConsoleWrite("eax=0x%x", r->eax);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("ebx=0x%x", r->ebx);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("ecx=0x%x", r->ecx);
|
||||
ConsoleCursorGoto(d); ConsoleWrite("edx=0x%x\n", r->edx);
|
||||
|
||||
ConsoleCursorGoto(a); ConsoleWrite("edi=0x%x", r->edi);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("esi=0x%x", r->esi);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("ebp=0x%x", r->ebp);
|
||||
ConsoleCursorGoto(d); ConsoleWrite("esp=0x%x\n", r->esp);
|
||||
|
||||
ConsoleCursorGoto(a); ConsoleWrite("gs=0x%x", r->gs);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("fs=0x%x", r->fs);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("es=0x%x", r->es);
|
||||
ConsoleCursorGoto(d); ConsoleWrite("ds=0x%x\n", r->ds);
|
||||
|
||||
ConsoleCursorGoto(a); ConsoleWrite("eip=0x%x", r->eip);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("cs=0x%x", r->cs);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("eflags=0x%x", r->eflags);
|
||||
ConsoleCursorGoto(d); ConsoleWrite("useresp=0x%x\n", r->useresp);
|
||||
|
||||
ConsoleCursorGoto(a); ConsoleWrite("gs=0x%x", r->ss);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("fs=0x%x", r->int_no);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("err_code=0x%x", r->err_code);
|
||||
|
||||
// Useful info about page fault
|
||||
if (r->int_no == 0xE)
|
||||
{
|
||||
uint32 faulting_address;
|
||||
asm volatile("mov %%cr2, %0" : "=r" (faulting_address));
|
||||
|
||||
ConsoleCursorGoto(d); ConsoleWrite("address=0x%x\n", faulting_address);
|
||||
ConsoleCursorGoto(a); ConsoleWrite("reason: ");
|
||||
|
||||
if (!(r->err_code & 1)) ConsoleWrite("%#PAGE_NOT_PRESENT; ", ColorLightGray);
|
||||
if (r->err_code & 2) ConsoleWrite("%#WRITE_OPERATION; ", ColorLightGray);
|
||||
if (r->err_code & 4) ConsoleWrite("%#CPU_IN_USER_MODE; ", ColorLightGray);
|
||||
if (r->err_code & 8) ConsoleWrite("%#CPU_RESERVED_PAGE_ENTRY_OVERWRITTEN; ", ColorLightGray);
|
||||
if (r->err_code & 0x10) ConsoleWrite("%#INSTRUCTION_FETCH; ", ColorLightGray);
|
||||
}
|
||||
|
||||
ConsoleSetDefaultColor(ColorLightRed);
|
||||
ConsoleWrite("\n");
|
||||
for (i = 0; i < 80; i++) ConsoleWrite("%c", 205);
|
||||
}
|
97
Kernel/hal/crash.c~
Normal file
97
Kernel/hal/crash.c~
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* crash.c
|
||||
*
|
||||
* Created on: Aug 19, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <debugio.h>
|
||||
|
||||
string errorCodes[] =
|
||||
{
|
||||
"Division by zero", //0
|
||||
"Debugger", //1
|
||||
"Non maskable interrupt", //2
|
||||
"Breakpoint", //3
|
||||
"Overflow", //4
|
||||
"Bounds", //5
|
||||
"Invalid opcode", //6
|
||||
"Coprocessor not available", //7
|
||||
"Double fault", //8
|
||||
"Coprocessor segment overrun",//9
|
||||
"Invalid task state segment", //A
|
||||
"Segment not present", //B
|
||||
"Stack fault", //C
|
||||
"General protection fault", //D
|
||||
"Page fault", //E
|
||||
"", //F
|
||||
"Math fault", //10
|
||||
"Alignment check", //11
|
||||
"Machine check", //12
|
||||
"SIMD floating-point exception" //13
|
||||
};
|
||||
|
||||
void CrashMessage(_RegsStack32 *r)
|
||||
{
|
||||
ConsoleSetDefaultColor(ColorLightRed);
|
||||
|
||||
ConsoleWrite("\n"); uint32 i;
|
||||
for (i = 0; i < 80; i++) ConsoleWrite("%c", 205);
|
||||
|
||||
ConsoleWrite("%#\t\t\t\tSomething went terribly wrong :(\n\n", ColorWhite);
|
||||
ConsoleWrite("There was an unhandled exception: ");
|
||||
|
||||
if (r->int_no < 20)
|
||||
ConsoleWrite("%#%s (INT%u)", ColorWhite, errorCodes[r->int_no], r->int_no);
|
||||
else ConsoleWrite("%#INT%u", ColorWhite, r->int_no);
|
||||
|
||||
ConsoleWrite("\nTo protect your computer, it had to be halted.\n\n");
|
||||
ConsoleWrite("Here, this might help find the problem:\n");
|
||||
|
||||
Point a = {4, -1}, b = {22, -1}, c = {40, -1}, d = {58, -1};
|
||||
|
||||
ConsoleSetDefaultColor(ColorWhite);
|
||||
ConsoleCursorGoto(a); ConsoleWrite("eax=0x%x", r->eax);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("ebx=0x%x", r->ebx);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("ecx=0x%x", r->ecx);
|
||||
ConsoleCursorGoto(d); ConsoleWrite("edx=0x%x\n", r->edx);
|
||||
|
||||
ConsoleCursorGoto(a); ConsoleWrite("edi=0x%x", r->edi);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("esi=0x%x", r->esi);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("ebp=0x%x", r->ebp);
|
||||
ConsoleCursorGoto(d); ConsoleWrite("esp=0x%x\n", r->esp);
|
||||
|
||||
ConsoleCursorGoto(a); ConsoleWrite("gs=0x%x", r->gs);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("fs=0x%x", r->fs);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("es=0x%x", r->es);
|
||||
ConsoleCursorGoto(d); ConsoleWrite("ds=0x%x\n", r->ds);
|
||||
|
||||
ConsoleCursorGoto(a); ConsoleWrite("eip=0x%x", r->eip);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("cs=0x%x", r->cs);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("eflags=0x%x", r->eflags);
|
||||
ConsoleCursorGoto(d); ConsoleWrite("useresp=0x%x\n", r->useresp);
|
||||
|
||||
ConsoleCursorGoto(a); ConsoleWrite("gs=0x%x", r->ss);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("fs=0x%x", r->int_no);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("err_code=0x%x", r->err_code);
|
||||
|
||||
// Useful info about page fault
|
||||
if (r->int_no == 0xE)
|
||||
{
|
||||
uint32 faulting_address;
|
||||
asm volatile("mov %%cr2, %0" : "=r" (faulting_address));
|
||||
|
||||
ConsoleCursorGoto(d); ConsoleWrite("address=0x%x\n", faulting_address);
|
||||
ConsoleCursorGoto(a); ConsoleWrite("reason: ");
|
||||
|
||||
if (!(r->err_code & 1)) ConsoleWrite("%#PAGE_NOT_PRESENT; ", ColorLightGray);
|
||||
if (r->err_code & 2) ConsoleWrite("%#WRITE_OPERATION; ", ColorLightGray);
|
||||
if (r->err_code & 4) ConsoleWrite("%#CPU_IN_USER_MODE; ", ColorLightGray);
|
||||
if (r->err_code & 8) ConsoleWrite("%#CPU_RESERVED_PAGE_ENTRY_OVERWRITTEN; ", ColorLightGray);
|
||||
if (r->err_code & 0x10) ConsoleWrite("%#INSTRUCTION_FETCH; ", ColorLightGray);
|
||||
}
|
||||
|
||||
ConsoleSetDefaultColor(ColorLightRed);
|
||||
ConsoleWrite("\n");
|
||||
for (i = 0; i < 80; i++) ConsoleWrite("%c", 205);
|
||||
}
|
35
Kernel/hal/hal.c
Normal file
35
Kernel/hal/hal.c
Normal file
@ -0,0 +1,35 @@
|
||||
// HARDWARE ABSTRACTION LAYER
|
||||
#include "cpu/gdt.h"
|
||||
#include "cpu/idt.h"
|
||||
#include "cpu/isrs.h"
|
||||
#include "cpu/irq.h"
|
||||
|
||||
#include "clock/clock.h"
|
||||
#include "keyboard/keyboard.h"
|
||||
#include "mouse/mouse.h"
|
||||
|
||||
#include <debugio.h>
|
||||
|
||||
void HalInitialize()
|
||||
{
|
||||
// Initialize cpu
|
||||
GdtInstall(); Log("%#[HAL] %#Installed GDT\n", ColorYellow, ColorLightGreen);
|
||||
IdtInstall(); Log("%#[HAL] %#Installed IDT\n", ColorYellow, ColorLightGreen);
|
||||
IsrsInstall(); Log("%#[HAL] %#Installed ISRs\n", ColorYellow, ColorLightGreen);
|
||||
IrqInstall(); Log("%#[HAL] %#Installed IRQs\n", ColorYellow, ColorLightGreen);
|
||||
|
||||
// Start interrupts
|
||||
asm volatile ("sti");
|
||||
Log("%#[HAL] %#Interrupts are started...\n", ColorYellow, ColorLightMagenta);
|
||||
|
||||
// Install keyboard
|
||||
IrqInstallHandler(0, TimeHandler);
|
||||
IrqInstallHandler(1, KeyboardHandler);
|
||||
IrqInstallHandler(12, MouseHandler);
|
||||
|
||||
KeyboardInstallA(); Log("%#[HAL] %#Installing keyboard... %#[1/2] ", ColorYellow, ColorLightGray, ColorLightGreen);
|
||||
KeyboardInstallB(); Log("%#[2/2]\n", ColorLightGreen);
|
||||
|
||||
// Install mouse driver
|
||||
MouseInstall(); Log("%#[HAL] %#Installed mouse driver\n", ColorYellow, ColorLightGreen);
|
||||
}
|
6
Kernel/hal/hal.h
Normal file
6
Kernel/hal/hal.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __HAL__H
|
||||
#define __HAL__H
|
||||
|
||||
extern void HalInitialize();
|
||||
|
||||
#endif
|
327
Kernel/hal/keyboard/keyboard.c
Normal file
327
Kernel/hal/keyboard/keyboard.c
Normal file
@ -0,0 +1,327 @@
|
||||
#include <stdio.h>
|
||||
#include "keyboard.h"
|
||||
|
||||
#define KeybCmdWriteLED 0xed
|
||||
#define KeybCmdEcho 0xee
|
||||
#define KeybCmdSetScancodeSet 0xf0
|
||||
#define KeybCmdGetID 0xf2
|
||||
#define KeybCmdSetRepeatDelay 0xf3
|
||||
#define KeybCmdEnable 0xf4
|
||||
#define KeybCmdSetDefaultDisable 0xf5
|
||||
#define KeybCmdSetDefault 0xf6
|
||||
#define KeybCmdResend 0xfe
|
||||
#define KeybCmdReset 0xff
|
||||
|
||||
volatile uint8 KeyState[16];
|
||||
volatile uint8 KeyboardLastStatus;
|
||||
volatile uint8 KeyboardLastScancode;
|
||||
|
||||
uint8 KeyboardScancodeSet = 2;
|
||||
|
||||
// Byte map:
|
||||
// 0 If set, next code is break
|
||||
// 1 'Gray' key
|
||||
// 2 'Weird' key (Pause/Break)
|
||||
// 3 Scroll
|
||||
// 4 Num
|
||||
// 5 Caps
|
||||
// 6 If set, LEDs changed
|
||||
uint8 KeyboardModifiers;
|
||||
|
||||
const char KeyboardMap[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '`', 0,
|
||||
0, 0, 0, 0, 0, 'q', '1', 0, 0, 0, 'z', 's', 'a', 'w', '2', 0,
|
||||
0, 'c', 'x', 'd', 'e', '4', '3', 0, 0, ' ', 'v', 'f', 't', 'r', '5', 0,
|
||||
0, 'n', 'b', 'h', 'g', 'y', '6', 0, 0, 0, 'm', 'j', 'u', '7', '8', 0,
|
||||
0, ',', 'k', 'i', 'o', '0', '9', 0, 0, '.', '/', 'l', ';', 'p', '-', 0,
|
||||
0, 0, '\'', 0, '[', '=', 0, 0, 0, 0, '\n', ']', 0, '\\', 0, 0,
|
||||
0, 0, 0, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', '\n', 0, 0,
|
||||
'0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
|
||||
};
|
||||
|
||||
const char KeyboardMapShift[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '~', 0,
|
||||
0, 0, 0, 0, 0, 'Q', '!', 0, 0, 0, 'Z', 'S', 'A', 'W', '@', 0,
|
||||
0, 'C', 'X', 'D', 'E', '$', '#', 0, 0, ' ', 'V', 'F', 'T', 'R', '%', 0,
|
||||
0, 'N', 'B', 'H', 'G', 'Y', '^', 0, 0, 0, 'M', 'J', 'U', '&', '*', 0,
|
||||
0, '<', 'K', 'I', 'O', ')', '(', 0, 0, '>', '?', 'L', ':', 'P', '_', 0,
|
||||
0, 0, '\"', 0, '{', '+', 0, 0, 0, 0, '\n', '}', 0, '|', 0, 0,
|
||||
0, 0, 0, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', '\n', 0, 0,
|
||||
'0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
|
||||
};
|
||||
|
||||
|
||||
void KeyboardSetKeyStatus (uint8 scancode, uint8 status)
|
||||
{
|
||||
int32 index = scancode>>3, pos = scancode & 0x7;
|
||||
|
||||
if (status) KeyState[index] |= 1<<pos;
|
||||
else KeyState[index] &= ~(1<<pos);
|
||||
}
|
||||
|
||||
|
||||
uint8 KeyboardGetKeyStatus (uint8 scancode)
|
||||
{
|
||||
int32 index = scancode>>3, pos = scancode & 0x7;
|
||||
|
||||
return KeyState[index] & (1<<pos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _process_scancode(uint8 scancode)
|
||||
{
|
||||
switch (scancode)
|
||||
{
|
||||
// Messages from keyboard controller
|
||||
case 0x00: // Error 0x00
|
||||
case 0xFC: // Diagnostics failed (MF kb)
|
||||
case 0xFD: // Diagnostics failed (AT kb)
|
||||
case 0xFF: KeyboardWaitOutport();
|
||||
outportb(0x60, KeybCmdEnable);
|
||||
return; // Error 0xFF, reenable keyboard
|
||||
case 0xAA: // BAT test successful.
|
||||
case 0xFA: // ACKnowledge
|
||||
case 0xFE: // Last command invalid or parity error
|
||||
case 0xEE: return; // Echo response
|
||||
|
||||
// Break
|
||||
case 0xF0: KeyboardModifiers |= 1; return;
|
||||
|
||||
// Special character (gray, etc)
|
||||
case 0xE0: KeyboardModifiers |= 2; return;
|
||||
case 0xE1: KeyboardModifiers |= 4; return;
|
||||
|
||||
// Remap some characters:
|
||||
case 0x83: scancode = KeyboardKeyF7; break;
|
||||
|
||||
// LEDs
|
||||
case KeyboardKeyScrollLock:
|
||||
if ((KeyboardModifiers & 1) == 0) {
|
||||
KeyboardModifiers ^= 1<<3;
|
||||
KeyboardModifiers |= 1<<6;
|
||||
} break;
|
||||
|
||||
case KeyboardKeyNumLock:
|
||||
if ((KeyboardModifiers & 1) == 0) {
|
||||
KeyboardModifiers ^= 1<<4;
|
||||
KeyboardModifiers |= 1<<6;
|
||||
} break;
|
||||
case KeyboardKeyCapsLock:
|
||||
if ((KeyboardModifiers & 1) == 0) {
|
||||
KeyboardModifiers ^= 1<<5;
|
||||
KeyboardModifiers |= 1<<6;
|
||||
} break;
|
||||
}
|
||||
|
||||
// Remap most gray characters
|
||||
if (KeyboardModifiers & 2) switch (scancode)
|
||||
{
|
||||
case 0x10: scancode = KeyboardKeyMediaWebSearch; break;
|
||||
case 0x11: scancode = KeyboardKeyRightAlt; break;
|
||||
case 0x12: return; // Fake shift, ignore
|
||||
case 0x14: scancode = KeyboardKeyRightCtrl; break;
|
||||
case 0x15: scancode = KeyboardKeyMediaPrevious; break;
|
||||
case 0x18: scancode = KeyboardKeyMediaWebFavorites; break;
|
||||
case 0x1F: scancode = KeyboardKeyLeftWin; break;
|
||||
case 0x20: scancode = KeyboardKeyMediaWebRefresh; break;
|
||||
case 0x21: scancode = KeyboardKeyMediaVolDown; break;
|
||||
case 0x23: scancode = KeyboardKeyMediaMute; break;
|
||||
case 0x27: scancode = KeyboardKeyRightWin; break;
|
||||
case 0x28: scancode = KeyboardKeyMediaWebStop; break;
|
||||
case 0x2B: scancode = KeyboardKeyMediaCalculator; break;
|
||||
case 0x2F: scancode = KeyboardKeyMenu; break;
|
||||
case 0x30: scancode = KeyboardKeyMediaWebForward; break;
|
||||
case 0x32: scancode = KeyboardKeyMediaVolUp; break;
|
||||
case 0x34: scancode = KeyboardKeyMediaPause; break;
|
||||
case 0x37: scancode = KeyboardKeyPower; break;
|
||||
case 0x38: scancode = KeyboardKeyMediaWebBack; break;
|
||||
case 0x3A: scancode = KeyboardKeyMediaWebHome; break;
|
||||
case 0x3B: scancode = KeyboardKeyMediaStop; break;
|
||||
case 0x3F: scancode = KeyboardKeySleep; break;
|
||||
case 0x40: scancode = KeyboardKeyMediaComputer; break;
|
||||
case 0x48: scancode = KeyboardKeyMediaEmail; break;
|
||||
case 0x4A: scancode = KeyboardKeyNumpadSlash; break;
|
||||
case 0x4D: scancode = KeyboardKeyMediaNext; break;
|
||||
case 0x50: scancode = KeyboardKeyMediaSelect; break;
|
||||
case 0x5A: scancode = KeyboardKeyNumpadEnter; break;
|
||||
case 0x5E: scancode = KeyboardKeyWake; break;
|
||||
case 0x69: scancode = KeyboardKeyEnd; break;
|
||||
case 0x6B: scancode = KeyboardKeyLeft; break;
|
||||
case 0x6C: scancode = KeyboardKeyHome; break;
|
||||
case 0x70: scancode = KeyboardKeyInsert; break;
|
||||
case 0x71: scancode = KeyboardKeyDelete; break;
|
||||
case 0x72: scancode = KeyboardKeyDown; break;
|
||||
case 0x74: scancode = KeyboardKeyRight; break;
|
||||
case 0x75: scancode = KeyboardKeyUp; break;
|
||||
case 0x7A: scancode = KeyboardKeyPageDown; break;
|
||||
case 0x7C: scancode = KeyboardKeyPrintScreen; break;
|
||||
case 0x7D: scancode = KeyboardKeyPageUp; break;
|
||||
}
|
||||
|
||||
// Pause/break
|
||||
if (KeyboardModifiers & 4)
|
||||
{
|
||||
KeyboardSetKeyStatus(KeyboardKeyPause, 1 - (KeyboardModifiers & 1));
|
||||
|
||||
if (scancode == 0x77) KeyboardModifiers = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
KeyboardSetKeyStatus(scancode, 1 - (KeyboardModifiers & 1));
|
||||
|
||||
// Give functions something to wait for :P
|
||||
KeyboardLastScancode = scancode;
|
||||
KeyboardLastStatus = KeyboardModifiers;
|
||||
KeyboardModifiers &= ~7;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void KeyboardHandler (_RegsStack32* UNUSED(r))
|
||||
{
|
||||
// Get scancode from keyboard
|
||||
uint8 scancode = inportb(0x60);
|
||||
|
||||
// Process scancode
|
||||
_process_scancode(scancode);
|
||||
|
||||
// LED update
|
||||
if (KeyboardModifiers & (1<<6))
|
||||
{
|
||||
KeyboardSetLEDs(KeyboardModifiers & (1<<3), KeyboardModifiers & (1<<4), KeyboardModifiers & (1<<5));
|
||||
KeyboardModifiers &= ~(1<<6);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void KeyboardSetLEDs (uint8 scroll, uint8 num, uint8 caps)
|
||||
{
|
||||
uint8 status = 0;
|
||||
status |= (scroll > 0);
|
||||
status |= (num > 0) << 1;
|
||||
status |= (caps > 0) << 2;
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb (0x60, KeybCmdWriteLED);
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb (0x60, status);
|
||||
}
|
||||
|
||||
|
||||
/***************************************
|
||||
* Set repeat rate/delay *
|
||||
***************************************
|
||||
Values for inter-character delay (bits 4-0)
|
||||
(characters per second; default is 10.9)
|
||||
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
|
||||
----+----+----+----+----+----+----+----+----
|
||||
0 |30.0|26.7|24.0|21.8|20.0|18.5|17.1|16.0
|
||||
8 |15.0|13.3|12.0|10.9|10.0|9.2 |8.6 |8.0
|
||||
16 |7.5 |6.7 |6.0 |5.5 |5.0 |4.6 |4.3 |4.0
|
||||
24 |3.7 |3.3 |3.0 |2.7 |2.5 |2.3 |2.1 |2.0
|
||||
|
||||
Values for delay:
|
||||
(miliseconds; default is 500)
|
||||
0 | 1 | 2 | 3
|
||||
-----+-----+-----+-----
|
||||
250 | 500 | 750 | 1000
|
||||
|
||||
***************************************/
|
||||
void KeyboardSetRepeatRate(uint8 rate, uint8 delay)
|
||||
{
|
||||
if (rate>3 || delay>31) return;
|
||||
|
||||
uint8 out = rate<<5 | delay;
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x60, KeybCmdSetRepeatDelay);
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x60, out);
|
||||
}
|
||||
|
||||
/***************************************
|
||||
* Set scancode set *
|
||||
***************************************
|
||||
1 Set to scancode set 1
|
||||
2 Set to scancode set 2
|
||||
3 Set to scancode set 3
|
||||
***************************************/
|
||||
void KeyboardSetScancodeSet(uint8 set)
|
||||
{
|
||||
if (set>3 || set <= 0) return;
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb (0x60, KeybCmdSetScancodeSet);
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb (0x60, set);
|
||||
|
||||
KeyboardScancodeSet = set;
|
||||
}
|
||||
|
||||
|
||||
void KeyboardWaitOutport()
|
||||
{
|
||||
int fail_safe=200000;
|
||||
while ((inportb(0x64)&2)!=0 && fail_safe>0) fail_safe--;
|
||||
}
|
||||
|
||||
void KeyboardWaitInport()
|
||||
{
|
||||
int fail_safe=200000;
|
||||
while ((inportb(0x64)&1)==0 && fail_safe>0) fail_safe--;
|
||||
}
|
||||
|
||||
|
||||
void KeyboardInstallA()
|
||||
{
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x60, KeybCmdReset); // Reset kb
|
||||
|
||||
// Initialize variables
|
||||
KeyboardLastStatus = 0;
|
||||
KeyboardModifiers = 0;
|
||||
|
||||
int32 i;
|
||||
for (i = 0; i < 16; i++)
|
||||
KeyState[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
void KeyboardInstallB()
|
||||
{
|
||||
// Wait for BAT test results
|
||||
KeyboardWaitInport();
|
||||
|
||||
unsigned char temp;
|
||||
do temp = inportb(0x60);
|
||||
while (temp!=0xAA && temp!=0xFC);
|
||||
|
||||
// Error
|
||||
if (temp == 0xFC) return;
|
||||
|
||||
// Set new repeat rate
|
||||
KeyboardSetRepeatRate(1, 11);
|
||||
|
||||
// Set scancode set 2
|
||||
KeyboardSetScancodeSet(2); // Set new scancode set
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x64, 0x20); // Get "Command unsigned char"
|
||||
|
||||
do { temp = inportb(0x60);
|
||||
} while (temp==0xFA || temp==0xAA);
|
||||
|
||||
temp &= ~(1<<6); // Unset bit6: disable conversion
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x64, 0x60); // Function to write cmd unsigned char
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x60, temp); // Send it
|
||||
}
|
52
Kernel/hal/keyboard/keyboard.h
Normal file
52
Kernel/hal/keyboard/keyboard.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef __KEYBOARD__H
|
||||
#define __KEYBOARD__H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
extern const char KeyboardMap[0x80];
|
||||
extern const char KeyboardMapShift[0x80];
|
||||
extern volatile uint8 KeyboardLastStatus;
|
||||
extern volatile uint8 KeyboardLastScancode;
|
||||
|
||||
extern void KeyboardSetKeyStatus (uint8 scancode, uint8 status);
|
||||
extern uint8 KeyboardGetKeyStatus (uint8 scancode);
|
||||
extern void KeyboardHandler (_RegsStack32 *r);
|
||||
extern void KeyboardSetLEDs (uint8 scroll, uint8 num, uint8 caps);
|
||||
/***************************************
|
||||
* Set repeat rate/delay *
|
||||
***************************************
|
||||
Values for inter-character delay (bits 4-0)
|
||||
(characters per second; default is 10.9)
|
||||
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
|
||||
----+----+----+----+----+----+----+----+----
|
||||
0 |30.0|26.7|24.0|21.8|20.0|18.5|17.1|16.0
|
||||
8 |15.0|13.3|12.0|10.9|10.0|9.2 |8.6 |8.0
|
||||
16 |7.5 |6.7 |6.0 |5.5 |5.0 |4.6 |4.3 |4.0
|
||||
24 |3.7 |3.3 |3.0 |2.7 |2.5 |2.3 |2.1 |2.0
|
||||
|
||||
Values for delay:
|
||||
(miliseconds; default is 500)
|
||||
0 | 1 | 2 | 3
|
||||
-----+-----+-----+-----
|
||||
250 | 500 | 750 | 1000
|
||||
|
||||
***************************************/
|
||||
extern void KeyboardSetRepeatRate(uint8 rate, uint8 delay);
|
||||
|
||||
/***************************************
|
||||
* Set scancode set *
|
||||
***************************************
|
||||
1 Set to scancode set 1
|
||||
2 Set to scancode set 2
|
||||
3 Set to scancode set 3
|
||||
***************************************/
|
||||
extern void KeyboardSetScancodeSet(uint8 set);
|
||||
|
||||
extern void KeyboardWaitOutport();
|
||||
extern void KeyboardWaitInport();
|
||||
|
||||
extern void KeyboardInstallA();
|
||||
extern void KeyboardInstallB();
|
||||
|
||||
#endif
|
||||
|
116
Kernel/hal/mouse/mouse.c
Normal file
116
Kernel/hal/mouse/mouse.c
Normal file
@ -0,0 +1,116 @@
|
||||
#include <stdio.h>
|
||||
#include <debugio.h>
|
||||
#include "mouse.h"
|
||||
#include "../keyboard/keyboard.h"
|
||||
|
||||
uint8 MouseCycle = 0;
|
||||
uint8 MouseCycleExpected = 3;
|
||||
uint8 Packets[4];
|
||||
|
||||
Point MousePosition = {0,0};
|
||||
Point MouseMinimumPosition = {0,0}, MouseMaximumPosition = {80, 25};
|
||||
Point Prev = {0,0};
|
||||
|
||||
#define SpeedLimit 0x8
|
||||
|
||||
// IRQ12
|
||||
void MouseHandler (_RegsStack32* UNUSED(r))
|
||||
{
|
||||
uint8 data = inportb(0x60);
|
||||
Point delta;
|
||||
|
||||
if (MouseCycle == 0 && (data == 0 || data == 0xFA || data == 0xFF || data == 0xAA)) return;
|
||||
Packets[MouseCycle++] = data;
|
||||
|
||||
// Cycle ended
|
||||
if (MouseCycle >= MouseCycleExpected)
|
||||
{
|
||||
MouseCycle = 0;
|
||||
if (Packets[0] & 0xC0) return; // Discard packet
|
||||
|
||||
// Update X position
|
||||
if (Packets[0] & 0x10) delta.X = (int32) (Packets[1] | 0xFFFFFF00);
|
||||
else delta.X = (int32) Packets[1];
|
||||
|
||||
// Update Y position
|
||||
if (Packets[0] & 0x20) delta.Y = -1 * (int32) (Packets[2] | 0xFFFFFF00);
|
||||
else delta.Y = -1 * (int32)Packets[2];
|
||||
|
||||
if (delta.X >= SpeedLimit) delta.X = SpeedLimit;
|
||||
if (delta.X <= -SpeedLimit) delta.X = -SpeedLimit;
|
||||
if (delta.Y >= SpeedLimit) delta.Y = SpeedLimit;
|
||||
if (delta.Y <= -SpeedLimit) delta.Y = -SpeedLimit;
|
||||
|
||||
MousePosition.X += delta.X;
|
||||
MousePosition.Y += delta.Y;
|
||||
|
||||
// Check limits
|
||||
if (MousePosition.X < MouseMinimumPosition.X) MousePosition.X = MouseMinimumPosition.X;
|
||||
if (MousePosition.Y < MouseMinimumPosition.Y) MousePosition.Y = MouseMinimumPosition.Y;
|
||||
if (MousePosition.X >= MouseMaximumPosition.X) MousePosition.X = MouseMaximumPosition.X - 1;
|
||||
if (MousePosition.Y >= MouseMaximumPosition.Y) MousePosition.Y = MouseMaximumPosition.Y - 1;
|
||||
|
||||
/* TESTING ONLY */
|
||||
ConsoleSetColor(Prev, 0xFF - ConsoleGetColor(Prev));
|
||||
ConsoleSetColor(MousePosition, 0xFF - ConsoleGetColor(MousePosition));
|
||||
Prev = MousePosition;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void MouseSendCommand(uint8 command)
|
||||
{
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x64, 0xD4);
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x60, command);
|
||||
}
|
||||
|
||||
uint8 MouseReadData ()
|
||||
{
|
||||
KeyboardWaitInport();
|
||||
return inportb(0x60);
|
||||
}
|
||||
|
||||
void MouseInstall()
|
||||
{
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x64, 0xA8);
|
||||
|
||||
// Enable interrupts
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x64, 0x20);
|
||||
|
||||
KeyboardWaitInport();
|
||||
uint8 temp = inportb(0x60) | 2;
|
||||
temp &= ~0x20;
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x64, 0x60);
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x60, temp);
|
||||
|
||||
// Reset mouse, and enable it
|
||||
MouseSendCommand(MouseCommandReset);
|
||||
MouseReadData(); MouseReadData();
|
||||
|
||||
MouseSendCommand(MouseCommandSetDefaults);
|
||||
MouseReadData(); // Read ack
|
||||
|
||||
MouseSendCommand(MouseCommandEnableDataReporting);
|
||||
MouseReadData(); // Read ack
|
||||
|
||||
}
|
||||
|
||||
void MouseSetLimits (Point min_pos, Point max_pos)
|
||||
{
|
||||
MouseMinimumPosition = min_pos;
|
||||
MouseMaximumPosition = max_pos;
|
||||
}
|
||||
|
||||
MouseState MouseGetState()
|
||||
{
|
||||
MouseState ret = { Packets[0] & 0x7, MousePosition};
|
||||
return ret;
|
||||
}
|
36
Kernel/hal/mouse/mouse.h
Normal file
36
Kernel/hal/mouse/mouse.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef __MOUSE__H
|
||||
#define __MOUSE__H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 Buttons;
|
||||
Point Position;
|
||||
} MouseState;
|
||||
|
||||
enum MouseCommands
|
||||
{
|
||||
MouseCommandReset = 0xFF,
|
||||
MouseCommandResend = 0xFE,
|
||||
MouseCommandSetDefaults = 0xF6,
|
||||
MouseCommandDisableDataReporting = 0xF5,
|
||||
MouseCommandEnableDataReporting = 0xF4,
|
||||
MouseCommandSetSampleRate = 0xF3,
|
||||
MouseCommandGetDeviceID = 0xF2,
|
||||
MouseCommandSetRemoteMode = 0xF0,
|
||||
MouseCommandSetWrapMode = 0xEE,
|
||||
MouseCommandReadData = 0xEB,
|
||||
MouseCommandSetStreamMode = 0xEA,
|
||||
MouseCommandStatusRequest = 0xE9,
|
||||
MouseCommandSetResolution = 0xE8,
|
||||
MouseCommandSetScaling_2_1 = 0xE7,
|
||||
MouseCommandSetScaling_1_1 = 0xE6
|
||||
};
|
||||
|
||||
extern void MouseInstall();
|
||||
extern void MouseHandler (_RegsStack32 *r);
|
||||
extern void MouseSetLimits (Point min_pos, Point max_pos);
|
||||
extern MouseState MouseGetState();
|
||||
|
||||
#endif
|
27
Kernel/hal/sysinfo.c
Normal file
27
Kernel/hal/sysinfo.c
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* sysinfo.c
|
||||
*
|
||||
* Provides information about system, and useful utilities
|
||||
*
|
||||
* Created on: Aug 17, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <multiboot.h>
|
||||
#include <debugio.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include <../drivers/cmos/cmos.h>
|
||||
|
||||
#include "keyboard/keyboard.h"
|
||||
void SystemReboot()
|
||||
{
|
||||
Log("Rebooting system...\n");
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb (0x64, 0xFE);
|
||||
|
||||
asm("cli");
|
||||
asm("hlt");
|
||||
}
|
40
Kernel/hal/vfs.c
Normal file
40
Kernel/hal/vfs.c
Normal file
@ -0,0 +1,40 @@
|
||||
#include<fileio.h>
|
||||
#include<storage.h>
|
||||
|
||||
#define MAX_FS_COUNT 64
|
||||
|
||||
uint32 FsRead(FsNode *node, uint32 offset, uint32 size, uint8 *buffer)
|
||||
{
|
||||
if (node->Read != NULL) return node->Read(node, offset, size, buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32 FsWrite(FsNode *node, uint32 offset, uint32 size, uint8 *buffer)
|
||||
{
|
||||
if (node->Write != NULL) return node->Write(node, offset, size, buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void FsOpen(FsNode *node, uint8 read, uint8 write)
|
||||
{
|
||||
if (node->Open != NULL) return node->Open(node, read, write);
|
||||
}
|
||||
|
||||
void FsClose(FsNode *node)
|
||||
{
|
||||
if (node->Close != NULL) return node->Close();
|
||||
}
|
||||
|
||||
DirectoryEntry *FsReadDir(FsNode *node, uint32 index)
|
||||
{
|
||||
if (node->ReadDir != NULL && (node->Flags&7) == FsDirectory)
|
||||
return node->ReadDir(node, index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FsNode *FsFindDir(FsNode *node, char *name)
|
||||
{
|
||||
if (node->FindDir != NULL && (node->Flags&7) == FsDirectory)
|
||||
return node->FindDir(node, name);
|
||||
return NULL;
|
||||
}
|
Reference in New Issue
Block a user