Handout
This commit is contained in:
65
kernel/arch/pic.cc
Normal file
65
kernel/arch/pic.cc
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "pic.h"
|
||||
|
||||
#include "ioport.h"
|
||||
|
||||
namespace PIC {
|
||||
|
||||
void initialize() {
|
||||
// Access primary & secondary PIC via two ports each
|
||||
IOPort primary_port_a(0x20);
|
||||
IOPort primary_port_b(0x21);
|
||||
IOPort secondary_port_a(0xa0);
|
||||
IOPort secondary_port_b(0xa1);
|
||||
|
||||
// Initialization Command Word 1 (ICW1)
|
||||
// Basic PIC configuration, starting initialization
|
||||
enum InitializationCommandWord1 {
|
||||
ICW4_NEEDED = 1 << 0, // use Initialization Command Word 4
|
||||
SINGLE_MODE = 1 << 1, // Single or multiple (cascade mode) 8259A
|
||||
ADDRESS_INTERVAL_HALF =
|
||||
1
|
||||
<< 2, // 4 or 8 bit interval between the interrupt vector locations
|
||||
LEVEL_TRIGGERED = 1 << 3, // Level or edge triggered
|
||||
ALWAYS_1 = 1 << 4,
|
||||
};
|
||||
const uint8_t icw1 = InitializationCommandWord1::ICW4_NEEDED |
|
||||
InitializationCommandWord1::ALWAYS_1;
|
||||
// ICW1 in port A (each)
|
||||
primary_port_a.outb(icw1);
|
||||
secondary_port_a.outb(icw1);
|
||||
|
||||
// Initialization Command Word 2 (ICW2):
|
||||
// Configure interrupt vector base offset in port B
|
||||
primary_port_b.outb(0x20); // Primary: IRQ Offset 32
|
||||
secondary_port_b.outb(0x28); // Secondary: IRQ Offset 40
|
||||
|
||||
// Initialization Command Word 3 (ICW3):
|
||||
// Configure pin on primary PIC connected to secondary PIC
|
||||
const uint8_t pin = 2; // Secondary connected on primary pin 2
|
||||
primary_port_b.outb(1 << pin); // Pin as bit mask for primary
|
||||
secondary_port_b.outb(pin); // Pin as value (ID) for secondary
|
||||
|
||||
// Initialization Command Word 4 (ICW4)
|
||||
// Basic PIC configuration, starting initialization
|
||||
enum InitializationCommandWord4 {
|
||||
MODE_8086 = 1 << 0, // 8086/8088 or 8085 mode
|
||||
AUTO_EOI = 1 << 1, // Single or multiple (cascade mode) 8259A
|
||||
BUFFER_PRIMARY = 1 << 2, // Primary or secondary buffering
|
||||
BUFFERED_MODE = 1 << 3, // Enable or disable buffering (for primary or
|
||||
// secondary above)
|
||||
SPECIAL_FULLY_NESTED = 1 << 4 // Special or non special fully nested
|
||||
};
|
||||
const uint8_t icw4 = InitializationCommandWord4::MODE_8086 |
|
||||
InitializationCommandWord4::AUTO_EOI;
|
||||
// ICW3 in port B (each)
|
||||
primary_port_b.outb(icw4);
|
||||
secondary_port_b.outb(icw4);
|
||||
|
||||
// Operation Control Word 1 (OCW1):
|
||||
// Disable (mask) all hardware interrupts on both legacy PICs (we'll use
|
||||
// APIC)
|
||||
secondary_port_b.outb(0xff);
|
||||
primary_port_b.outb(0xff);
|
||||
}
|
||||
|
||||
} // namespace PIC
|
||||
Reference in New Issue
Block a user