[INTERRUPTS] IRQs and the Programmable Interrupt Controller

This commit is contained in:
Thomas Lovén 2016-11-09 21:16:29 +01:00
parent 8b2e58b6b1
commit b7c0de7ea5
3 changed files with 105 additions and 0 deletions

View File

@ -29,6 +29,7 @@ int kmain(uint64_t multiboot_magic, void *multiboot_data)
pmm_init();
gdt_init();
scheduler_init();
pic_init();
process_t *p1 = process_spawn(0);
process_t *p2 = process_spawn(p1);
@ -51,6 +52,8 @@ int kmain(uint64_t multiboot_magic, void *multiboot_data)
scheduler_insert(t2);
scheduler_insert(t3);
IRQ_UNMASK(IRQ_TIMER);
asm("sti");
debug_info("BOOT COMPLETE\n");
schedule();
debug_error("PANIC - This line should be unreachable (%s:%d)\n", __FILE__, __LINE__);

View File

@ -33,6 +33,30 @@
#define INT_SX 0x1E // Security exception
// Unused exception 0x1F
// User interrupts 0x20 and forward
#define INT_IRQ0 0x20
#define INT_IRQ1 0x21
#define INT_IRQ2 0x22
#define INT_IRQ3 0x23
#define INT_IRQ4 0x24
#define INT_IRQ5 0x25
#define INT_IRQ6 0x26
#define INT_IRQ7 0x27
#define INT_IRQ8 0x28
#define INT_IRQ9 0x29
#define INT_IRQ10 0x2A
#define INT_IRQ11 0x2B
#define INT_IRQ12 0x2C
#define INT_IRQ13 0x2D
#define INT_IRQ14 0x2E
#define INT_IRQ15 0x2F
#define INT_IRQ16 0x30
#define INT_IRQ17 0x31
#define INT_IRQ18 0x32
#define INT_IRQ19 0x33
#define INT_IRQ20 0x34
#define INT_IRQ21 0x35
#define INT_IRQ22 0x36
#define INT_IRQ23 0x37
#ifndef __ASSEMBLER__
#include <stdint.h>
@ -54,6 +78,19 @@ struct idtr
uint64_t addr;
} __attribute__ ((packed));
void pic_init();
void pic_ack(uint8_t irq);
void pic_mask(uint8_t irq);
void pic_unmask(uint8_t irq);
#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_TIMER 0
#define IRQ_KEYBOARD 1
typedef struct registers_st
{
uint64_t rax;

65
kernel/interrupts/pic.c Normal file
View File

@ -0,0 +1,65 @@
#include <stdint.h>
#include <ports.h>
#include <debug.h>
#include <int.h>
#define MPIC_CMD 0x0020
#define MPIC_DATA 0x0021
#define SPIC_CMD 0x00A0
#define SPIC_DATA 0x00A1
#define PIC_CMD_INIT 0x10
#define PIC_CMD_EXTRA 0x01
#define PIC_CMD_8086 0x01
#define PIC_CMD_EOI 0x20
void pic_init()
{
// Send initialize command
outb(MPIC_CMD, PIC_CMD_INIT | PIC_CMD_EXTRA);
outb(SPIC_CMD, PIC_CMD_INIT | PIC_CMD_EXTRA);
// Remap offsets
outb(MPIC_DATA, INT_IRQ0);
outb(SPIC_DATA, INT_IRQ8);
// Setup slave PIC
outb(MPIC_DATA, 0x04);
outb(SPIC_DATA, 0x02);
// Extra environment data
outb(MPIC_DATA, PIC_CMD_8086);
outb(SPIC_DATA, PIC_CMD_8086);
// Mask all interrupts
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));
}
}