paulbergmann_mpstubs/machine/pic.cc

62 lines
2.4 KiB
C++
Raw Permalink Normal View History

#include "machine/pic.h"
#include "machine/ioport.h"
#include "types.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