Added 8259 PIC support #5
@ -43,4 +43,8 @@ VOID
|
||||
HlIoPortOutShort(IN USHORT Port,
|
||||
IN USHORT Value);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
HlIoPortWait(VOID);
|
||||
|
||||
#endif /* __XTDK_AMD64_HLFUNCS_H */
|
||||
|
@ -90,6 +90,25 @@
|
||||
#define COMPORT_REG_MSR 0x06 /* Modem Status Register */
|
||||
#define COMPORT_REG_SR 0x07 /* Scratch Register */
|
||||
|
||||
/* 8259 PIC ports */
|
||||
belliash marked this conversation as resolved
Outdated
|
||||
#define PIC_MASTER_COMMAND 0xA0
|
||||
#define PIC_MASTER_DATA 0xA1
|
||||
#define PIC_SLAVE_COMMAND 0x20
|
||||
#define PIC_SLAVE_DATA 0x21
|
||||
belliash marked this conversation as resolved
Outdated
belliash
commented
I think Master and Slave (PIC1 and PIC2) I/O port addresses are swapped. I think Master and Slave (PIC1 and PIC2) I/O port addresses are swapped.
|
||||
|
||||
/* 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
|
||||
{
|
||||
|
@ -43,4 +43,8 @@ VOID
|
||||
HlIoPortOutShort(IN USHORT Port,
|
||||
IN USHORT Value);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
HlIoPortWait(VOID);
|
||||
|
||||
#endif /* __XTDK_I686_HLFUNCS_H */
|
||||
|
@ -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)
|
||||
belliash marked this conversation as resolved
Outdated
belliash
commented
Do you think this function might be useful anywhere else, or could we just call Do you think this function might be useful anywhere else, or could we just call ```HlIoPortOutByte(0x80, 0x00);``` directly as currently it is used only in ```HlWritePic()```?
|
||||
{
|
||||
HlIoPortOutByte(0x80, 0x00);
|
||||
}
|
@ -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);
|
||||
}
|
@ -4,10 +4,124 @@
|
||||
* FILE: xtoskrnl/hl/pic.c
|
||||
* DESCRIPTION: Programmable Interrupt Controller (PIC) support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Jozef Nagy <schkwve@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
belliash marked this conversation as resolved
Outdated
belliash
commented
What do you think about putting an empty line before each comment? In my opinion it is easy to read, if comment says what does below block of code do and each block ends up with an empty line. What do you think about putting an empty line before each comment? In my opinion it is easy to read, if comment says what does below block of code do and each block ends up with an empty line.
|
||||
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++)
|
||||
belliash marked this conversation as resolved
Outdated
belliash
commented
Do we need to mask all IRQs if we finally disable PIC and use APIC? Do we want to support PIC as a failover? Do we need to mask all IRQs if we finally disable PIC and use APIC? Do we want to support PIC as a failover?
![]()
Ghost
commented
I have not found any mention of IRQs being explicitly masked or unmasked in any documents, so I masked them so the kernel doesn't get interrupted when the IRQ isn't ready to be served yet (in the case that PIC is indeed used as a failsafe). I have not found any mention of IRQs being explicitly masked or unmasked in any documents, so I masked them so the kernel doesn't get interrupted when the IRQ isn't ready to be served yet (in the case that PIC is indeed used as a failsafe).
|
||||
{
|
||||
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.
|
||||
|
@ -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);
|
||||
|
@ -69,6 +69,10 @@ KepInitializeMachine(VOID)
|
||||
/* Re-enable IDE interrupts */
|
||||
HlIoPortOutByte(0x376, 0);
|
||||
HlIoPortOutByte(0x3F6, 0);
|
||||
|
||||
/* Disable the legacy PIC */
|
||||
HlInitializePic();
|
||||
HlDisablePic();
|
||||
}
|
||||
|
||||
/**
|
||||
|
Does any other platform than x86 and x86_64 support 8259 PIC? If not, this should be architecture specific.