forked from BSB-WS23/mpstubs
62 lines
2.4 KiB
C++
62 lines
2.4 KiB
C++
|
#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
|