WIP - IOAPIC
This commit is contained in:
parent
8bd9b0ef16
commit
253cd84a1f
@ -4,6 +4,7 @@
|
||||
#include <mem.h>
|
||||
#include <string.h>
|
||||
#include <multiboot.h>
|
||||
#include <int.h>
|
||||
|
||||
RSDP_st *find_rsdp()
|
||||
{
|
||||
@ -87,6 +88,7 @@ void parse_MADT(SDT_header *header)
|
||||
break;
|
||||
case 2: // Interrupt Source Override
|
||||
debug_info("ACPI - Interrupt source override %x->%x\n", f->ISO.irq, f->ISO.interrupt);
|
||||
irq_map[f->ISO.irq] = f->ISO.interrupt;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -35,6 +35,7 @@ int kmain(uint64_t multiboot_magic, void *multiboot_data)
|
||||
pic_init();
|
||||
acpi_init();
|
||||
apic_init();
|
||||
ioapic_init();
|
||||
|
||||
|
||||
process_t *p1 = process_spawn(0);
|
||||
|
@ -9,3 +9,8 @@ void apic_ack();
|
||||
#define APIC_INT_TYPE_FIXED 0x0
|
||||
#define APIC_INT_TYPE_INIT 0x5
|
||||
#define APIC_INT_TYPE_STARTUP 0x6
|
||||
|
||||
|
||||
void ioapic_init();
|
||||
void ioapic_mask(uint8_t irq);
|
||||
void ioapic_unmask(uint8_t irq);
|
||||
|
@ -87,14 +87,12 @@ struct idtr
|
||||
} __attribute__ ((packed));
|
||||
|
||||
void pic_init();
|
||||
void pic_ack(uint8_t irq);
|
||||
void pic_mask(uint8_t irq);
|
||||
void pic_unmask(uint8_t irq);
|
||||
extern unsigned int irq_map[24];
|
||||
#define IRQ_INT(irq) (INT_IRQ0 + irq)
|
||||
#define IRQ(irq) (irq)
|
||||
#define IRQ_MASK(irq) pic_mask(irq)
|
||||
#define IRQ_UNMASK(irq) pic_unmask(irq)
|
||||
#define IRQ_ACK(irq) pic_ack(irq)
|
||||
#define IRQ(irq) (irq_map[irq])
|
||||
#define IRQ_MASK(irq) ioapic_mask(IRQ(irq))
|
||||
#define IRQ_UNMASK(irq) ioapic_unmask(IRQ(irq))
|
||||
#define IRQ_ACK(irq) apic_ack(IRQ(irq))
|
||||
|
||||
#define IRQ_TIMER 0
|
||||
#define IRQ_KEYBOARD 1
|
||||
|
@ -49,9 +49,6 @@ void apic_init()
|
||||
// Make sure the APIC base addres is mapped in kernel memory
|
||||
vmm_set_page(0, (uintptr_t)P2V(APIC_BASE), APIC_BASE, PAGE_PRESENT | PAGE_WRITE);
|
||||
|
||||
debug_info("APIC - ID: %x\n", APIC(R_ID));
|
||||
debug_info("APIC - Version: %x\n", APIC(R_VERSION));
|
||||
|
||||
uint8_t id = APIC(R_ID) >> 24;
|
||||
if(id <= 0)
|
||||
APIC(R_LDR) = 1 << (24 + id);
|
||||
|
91
kernel/interrupts/ioapic.c
Normal file
91
kernel/interrupts/ioapic.c
Normal file
@ -0,0 +1,91 @@
|
||||
#include <apic.h>
|
||||
#include <mem.h>
|
||||
#include <debug.h>
|
||||
|
||||
#define IOAPIC_BASE 0xFEC00000
|
||||
|
||||
#define IOAPIC_DEST_PHYSICAL 0x0
|
||||
#define IOAPIC_DEST_LOGICAL 0x8
|
||||
#define IOAPIC_DELIVERY_FIXED 0x0
|
||||
#define IOAPIC_DELIVERY_LOWEST 0x1
|
||||
|
||||
|
||||
volatile uint32_t *ioregsel = (void *)P2V(IOAPIC_BASE);
|
||||
volatile uint32_t *iowin = (void *)P2V(IOAPIC_BASE + 0x10);
|
||||
|
||||
uint32_t ioapic_read(uint32_t reg)
|
||||
{
|
||||
// Read value from APIC register
|
||||
*ioregsel = reg;
|
||||
return *iowin;
|
||||
}
|
||||
void ioapic_write(uint32_t reg, uint32_t value)
|
||||
{
|
||||
// Read value from APIC register
|
||||
*ioregsel = reg;
|
||||
*iowin = value;
|
||||
}
|
||||
|
||||
struct ioapic_redirection
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t data[2];
|
||||
}__attribute__((packed));
|
||||
struct
|
||||
{
|
||||
uint8_t vector;
|
||||
uint8_t mode;
|
||||
uint8_t mask;
|
||||
uint32_t reserved;
|
||||
uint8_t target;
|
||||
}__attribute__((packed));
|
||||
};
|
||||
};
|
||||
|
||||
void ioapic_readv(uint8_t irq, struct ioapic_redirection *v)
|
||||
{
|
||||
v->data[0] = ioapic_read(0x10 + 2*irq);
|
||||
v->data[1] = ioapic_read(0x11 + 2*irq);
|
||||
}
|
||||
void ioapic_writev(uint8_t irq, struct ioapic_redirection *v)
|
||||
{
|
||||
ioapic_write(0x10 + 2*irq, v->data[0]);
|
||||
ioapic_write(0x11 + 2*irq, v->data[1]);
|
||||
}
|
||||
|
||||
void ioapic_route(uint8_t irq, uint8_t mode, uint8_t target, uint8_t vector)
|
||||
{
|
||||
struct ioapic_redirection v;
|
||||
ioapic_readv(irq, &v);
|
||||
v.target = target;
|
||||
v.vector = vector;
|
||||
v.mode = mode;
|
||||
ioapic_writev(irq, &v);
|
||||
}
|
||||
|
||||
void ioapic_mask(uint8_t irq)
|
||||
{
|
||||
struct ioapic_redirection v;
|
||||
ioapic_readv(irq, &v);
|
||||
v.mask |= 1;
|
||||
ioapic_writev(irq, &v);
|
||||
}
|
||||
void ioapic_unmask(uint8_t irq)
|
||||
{
|
||||
struct ioapic_redirection v;
|
||||
ioapic_readv(irq, &v);
|
||||
v.mask &= 0xFE;
|
||||
ioapic_writev(irq, &v);
|
||||
}
|
||||
|
||||
void ioapic_init()
|
||||
{
|
||||
vmm_set_page(0, (uintptr_t)P2V(IOAPIC_BASE), IOAPIC_BASE, PAGE_PRESENT | PAGE_WRITE);
|
||||
for(int i = 0; i < 24; i++)
|
||||
ioapic_route(i, IOAPIC_DEST_LOGICAL | IOAPIC_DELIVERY_LOWEST, 0xFF, INT_IRQ0+i);
|
||||
|
||||
IRQ_UNMASK(IRQ_KEYBOARD);
|
||||
}
|
@ -13,6 +13,7 @@
|
||||
#define PIC_CMD_8086 0x01
|
||||
#define PIC_CMD_EOI 0x20
|
||||
|
||||
unsigned int irq_map[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};
|
||||
|
||||
void pic_init()
|
||||
{
|
||||
@ -37,29 +38,3 @@ void pic_init()
|
||||
outb(MPIC_DATA, 0xFF);
|
||||
outb(SPIC_DATA, 0xFF);
|
||||
}
|
||||
|
||||
void pic_ack(uint8_t irq)
|
||||
{
|
||||
if(irq >= 8)
|
||||
outb(SPIC_CMD, PIC_CMD_EOI);
|
||||
outb(MPIC_CMD, PIC_CMD_EOI);
|
||||
}
|
||||
|
||||
void pic_mask(uint8_t irq)
|
||||
{
|
||||
if(irq >= 8)
|
||||
{
|
||||
outb(SPIC_DATA, inb(SPIC_DATA) | 1 << (irq-8));
|
||||
} else {
|
||||
outb(MPIC_DATA, inb(MPIC_DATA) | 1 << irq);
|
||||
}
|
||||
}
|
||||
void pic_unmask(uint8_t irq)
|
||||
{
|
||||
if(irq >= 8)
|
||||
{
|
||||
outb(SPIC_DATA, inb(SPIC_DATA) & ~(1 << (irq-8)));
|
||||
} else {
|
||||
outb(MPIC_DATA, inb(MPIC_DATA) & ~(1 << irq));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user