[INTERRUPTS] IRQs and the Programmable Interrupt Controller
This commit is contained in:
parent
8b2e58b6b1
commit
b7c0de7ea5
@ -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__);
|
||||
|
@ -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
65
kernel/interrupts/pic.c
Normal 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));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user