diff --git a/sdk/xtdk/amd64/hlfuncs.h b/sdk/xtdk/amd64/hlfuncs.h index d5d6bff..e615724 100644 --- a/sdk/xtdk/amd64/hlfuncs.h +++ b/sdk/xtdk/amd64/hlfuncs.h @@ -43,4 +43,8 @@ VOID HlIoPortOutShort(IN USHORT Port, IN USHORT Value); +XTCDECL +VOID +HlIoPortWait(VOID); + #endif /* __XTDK_AMD64_HLFUNCS_H */ diff --git a/sdk/xtdk/hltypes.h b/sdk/xtdk/hltypes.h index 8eec8f2..b5bca03 100644 --- a/sdk/xtdk/hltypes.h +++ b/sdk/xtdk/hltypes.h @@ -90,6 +90,25 @@ #define COMPORT_REG_MSR 0x06 /* Modem Status Register */ #define COMPORT_REG_SR 0x07 /* Scratch Register */ +/* 8259 PIC ports */ +#define PIC_MASTER_COMMAND 0xA0 +#define PIC_MASTER_DATA 0xA1 +#define PIC_SLAVE_COMMAND 0x20 +#define PIC_SLAVE_DATA 0x21 + +/* 8259 PIC commands */ +#define PIC_ICW1_ICW4 0x01 /* Indicates that ICW4 will be present */ +#define PIC_ICW1_SINGLE 0x02 /* Single (cascade) mode */ +#define PIC_ICW1_INTERVAL4 0x04 /* Call address interva l 4 (8) */ +#define PIC_ICW1_LEVEL 0x08 /* Level triggered (edge) mode */ +#define PIC_ICW1_INIT 0x10 /* Initialization - required! */ + +#define PIC_ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ +#define PIC_ICW4_AUTO 0x02 /* Auto (normal) EOI */ +#define PIC_ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ +#define PIC_ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */ +#define PIC_ICW4_SFNM 0x10 /* Special fully nested (not) */ + /* APIC Register Address Map */ typedef enum _APIC_REGISTER { diff --git a/sdk/xtdk/i686/hlfuncs.h b/sdk/xtdk/i686/hlfuncs.h index dfc35ac..24c6746 100644 --- a/sdk/xtdk/i686/hlfuncs.h +++ b/sdk/xtdk/i686/hlfuncs.h @@ -43,4 +43,8 @@ VOID HlIoPortOutShort(IN USHORT Port, IN USHORT Value); +XTCDECL +VOID +HlIoPortWait(VOID); + #endif /* __XTDK_I686_HLFUNCS_H */ diff --git a/xtoskrnl/hl/amd64/ioport.c b/xtoskrnl/hl/amd64/ioport.c index 6ba8609..4e5fa81 100644 --- a/xtoskrnl/hl/amd64/ioport.c +++ b/xtoskrnl/hl/amd64/ioport.c @@ -143,3 +143,19 @@ HlIoPortOutShort(IN USHORT Port, : "a" (Value), "Nd" (Port)); } + +/** + * Sends a 0x00 byte to an unused IO port. + * This operation takes 1 - 4 microseconds and functions as an + * imprecise wait function. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +HlIoPortWait(VOID) +{ + HlIoPortOutByte(0x80, 0x00); +} \ No newline at end of file diff --git a/xtoskrnl/hl/i686/ioport.c b/xtoskrnl/hl/i686/ioport.c index 7f6b5d7..c15712c 100644 --- a/xtoskrnl/hl/i686/ioport.c +++ b/xtoskrnl/hl/i686/ioport.c @@ -143,3 +143,19 @@ HlIoPortOutShort(IN USHORT Port, : "a" (Value), "Nd" (Port)); } + +/** + * Sends a 0x00 byte to an unused IO port. + * This operation takes 1 - 4 microseconds and functions as an + * imprecise wait function. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +HlIoPortWait(VOID) +{ + HlIoPortOutByte(0x80, 0x00); +} \ No newline at end of file diff --git a/xtoskrnl/hl/pic.c b/xtoskrnl/hl/pic.c index c0d33ff..571a4b9 100644 --- a/xtoskrnl/hl/pic.c +++ b/xtoskrnl/hl/pic.c @@ -4,10 +4,124 @@ * FILE: xtoskrnl/hl/pic.c * DESCRIPTION: Programmable Interrupt Controller (PIC) support * DEVELOPERS: Rafal Kupiec + * Jozef Nagy */ #include +/** + * Initializes the 8259 PIC. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +HlInitializePic(VOID) +{ + /* Start in cascade mode */ + HlWritePic(PIC_MASTER_COMMAND, PIC_ICW1_INIT | PIC_ICW1_ICW4); + HlWritePic(PIC_SLAVE_COMMAND, PIC_ICW1_INIT | PIC_ICW1_ICW4); + + /* Master PIC Vector offset */ + HlWritePic(PIC_MASTER_DATA, 0x20); + /* Slave PIC Vector offset */ + HlWritePic(PIC_SLAVE_DATA, 0x28); + + /* Tell Master PIC that there is a Slave PIC */ + HlWritePic(PIC_MASTER_DATA, 4); + /* Tell Slave PIC its cascade identity */ + HlWritePic(PIC_SLAVE_DATA, 2); + + /* Tell Master PIC to use 8086 mode */ + HlWritePic(PIC_MASTER_DATA, PIC_ICW4_8086); + /* Tell Slave PIC to use 8086 mode */ + HlWritePic(PIC_SLAVE_DATA, PIC_ICW4_8086); + + /* Mask all IRQs by default */ + for (UCHAR Irq = 0; Irq < 16; Irq++) + { + HlSetMaskIrqPic(Irq); + } +} + +/** + * Masks an IRQ in the 8259 PIC. + * + * @param Irq + * Supplies the IRQ number to be masked. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +HlSetMaskIrqPic(UINT Irq) +{ + UINT Port; + + if(Irq < 8) { + Port = PIC_MASTER_DATA; + } else { + Port = PIC_SLAVE_DATA; + Irq -= 8; + } + + HlWritePic(Port, HlIoPortInByte(Port) | (1 << Irq)); +} + +/** + * Clears an IRQ mask in the 8259 PIC. + * + * @param Irq + * Supplies the IRQ number to be unmasked. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +HlClearMaskIrqPic(UINT Irq) +{ + UINT Port; + + if(Irq < 8) { + Port = PIC_MASTER_DATA; + } else { + Port = PIC_SLAVE_DATA; + Irq -= 8; + } + + HlWritePic(Port, HlIoPortInByte(Port) & ~(1 << Irq)); +} + +/** + * Disables the 8259 PIC. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +HlDisablePic(VOID) +{ + HlIoPortOutByte(PIC_MASTER_DATA, 0xFF); + HlIoPortOutByte(PIC_SLAVE_DATA, 0xFF); +} + +XTFASTCALL +VOID +HlWritePic(IN UCHAR Register, IN UCHAR Value) +{ + /* Send data */ + HlIoPortOutByte(Register, Value); + /* Wait for some time to make sure PIC has processed the data */ + HlIoPortWait(); +} /** * Reads from the local APIC register. diff --git a/xtoskrnl/includes/hl.h b/xtoskrnl/includes/hl.h index 6ff39d1..42d0c5b 100644 --- a/xtoskrnl/includes/hl.h +++ b/xtoskrnl/includes/hl.h @@ -13,6 +13,26 @@ /* HAL library routines forward references */ +XTCDECL +VOID +HlInitializePic(VOID); + +XTCDECL +VOID +HlSetMaskIrqPic(UINT Irq); + +XTCDECL +VOID +HlClearMaskIrqPic(UINT Irq); + +XTCDECL +VOID +HlDisablePic(VOID); + +XTFASTCALL +VOID +HlWritePic(IN UCHAR Register, IN UCHAR Value); + XTAPI VOID HlClearScreen(VOID); diff --git a/xtoskrnl/ke/amd64/krnlinit.c b/xtoskrnl/ke/amd64/krnlinit.c index e09923b..b3022be 100644 --- a/xtoskrnl/ke/amd64/krnlinit.c +++ b/xtoskrnl/ke/amd64/krnlinit.c @@ -69,6 +69,10 @@ KepInitializeMachine(VOID) /* Re-enable IDE interrupts */ HlIoPortOutByte(0x376, 0); HlIoPortOutByte(0x3F6, 0); + + /* Disable the legacy PIC */ + HlInitializePic(); + HlDisablePic(); } /**