This commit is contained in:
Freya Murphy 2024-01-29 18:20:21 -05:00
parent 36d7dad070
commit 0d2f0d2491
Signed by: freya
GPG key ID: 744AB800E383AE52
3 changed files with 112 additions and 0 deletions

78
src/arch/amd64/pic.c Normal file
View file

@ -0,0 +1,78 @@
#include "bindings.h"
#include "pic.h"
#define PIC1_COMMAND_PORT 0x20
#define PIC1_DATA_PORT 0x21
#define PIC2_COMMAND_PORT 0xA0
#define PIC2_DATA_PORT 0xA1
void pic_remap(void) {
char a1 = inb(PIC1_DATA_PORT);
char a2 = inb(PIC2_DATA_PORT);
// control word 1
// 0x11: initialize, enable ICW4
outb(PIC1_COMMAND_PORT, 0x11);
io_wait();
outb(PIC2_COMMAND_PORT, 0x11);
io_wait();
// control word 2
// interrupt offset
outb(PIC1_DATA_PORT, PIC_REMAP_OFFSET);
io_wait();
outb(PIC2_DATA_PORT, PIC_REMAP_OFFSET + 8);
io_wait();
// control word 3
// primary pic: set which pin secondary is connected to
// (pin 2)
outb(PIC1_DATA_PORT, 0x04);
io_wait();
outb(PIC2_DATA_PORT, 2);
io_wait();
// control word 3
// 0x01: enable 8086 mode
outb(PIC1_DATA_PORT, 0x01);
io_wait();
outb(PIC2_DATA_PORT, 0x01);
io_wait();
// clear data registers
outb(PIC1_DATA_PORT, a1);
outb(PIC2_DATA_PORT, a2);
}
void pic_mask(int irq) {
uint8_t port;
if(irq < 8) {
port = PIC1_DATA_PORT;
} else {
irq -= 8;
port = PIC2_DATA_PORT;
}
uint8_t mask = inb(port);
outb(port, mask | (1 << irq));
}
void pic_unmask(int irq) {
uint8_t port;
if(irq < 8) {
port = PIC1_DATA_PORT;
} else {
irq -= 8;
port = PIC2_DATA_PORT;
}
uint8_t mask = inb(port);
outb(port, mask & ~(1 << irq));
}
void pic_disable(void) {
outb(PIC1_DATA_PORT, 0xff);
io_wait();
outb(PIC2_DATA_PORT, 0xff);
io_wait();
}
void pic_eoi(int irq) {
if(irq >= 8) {
outb(PIC2_COMMAND_PORT, 0x20);
}
outb(PIC1_COMMAND_PORT, 0x20);
}

31
src/arch/amd64/pic.h Normal file
View file

@ -0,0 +1,31 @@
#pragma once
#define PIC_REMAP_OFFSET 0x20
/**
* Remaps the pie, i.e. initializes it
*/
void pic_remap(void);
/**
* Masks an external irq to stop firing until un masked
* @param irq - the irq to mask
*/
void pic_mask(int irq);
/**
* Unmasks an external irq to allow interrupts to continue for that irq
* @param irq - the irq to unmask
*/
void pic_unmask(int irq);
/**
* Disabled the pick
*/
void pic_disable(void);
/**
* Tells the pick that the interrupt has ended
* @param irq - the irq that has ended
*/
void pic_eoi(int irq);

View file

@ -7,12 +7,15 @@
#include "paging.h" #include "paging.h"
#include "mboot.h" #include "mboot.h"
#include "idt.h" #include "idt.h"
#include "pic.h"
static struct boot_info boot_info; static struct boot_info boot_info;
void* amd64_shim(void *mboot_data_ptr) { void* amd64_shim(void *mboot_data_ptr) {
serial_init(); serial_init();
paging_init(); paging_init();
idt_init(); idt_init();
pic_remap();
kmap_page(mboot_data_ptr, mboot_data_ptr, F_WRITEABLE); kmap_page(mboot_data_ptr, mboot_data_ptr, F_WRITEABLE);