[amd64] timer irq
This commit is contained in:
+3
-1
@@ -10,7 +10,9 @@ OBJS+=$(O)/arch/amd64/kernel.o \
|
||||
$(O)/arch/amd64/hw/idt.o \
|
||||
$(O)/arch/amd64/hw/ints.o \
|
||||
$(O)/arch/amd64/hw/exc.o \
|
||||
$(O)/arch/amd64/hw/regs.o
|
||||
$(O)/arch/amd64/hw/regs.o \
|
||||
$(O)/arch/amd64/hw/irq0.o \
|
||||
$(O)/arch/amd64/hw/pic8259.o
|
||||
kernel_OBJS=$(O)/arch/amd64/entry.o \
|
||||
$(OBJS)
|
||||
kernel_LINKER=$(S)/arch/amd64/link.ld
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "ints.h"
|
||||
#include "pic8259.h"
|
||||
#include "sys/mem.h"
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
@@ -52,6 +53,9 @@ extern void amd64_isr_29();
|
||||
extern void amd64_isr_30();
|
||||
extern void amd64_isr_31();
|
||||
|
||||
// 8259 PIC IRQs
|
||||
extern void amd64_irq_0();
|
||||
|
||||
typedef struct {
|
||||
uint16_t base_lo;
|
||||
uint16_t selector;
|
||||
@@ -119,5 +123,7 @@ void amd64_idt_init(void) {
|
||||
amd64_idt_set(30, (uintptr_t) amd64_isr_30, 0x08, IDT_FLG_P | IDT_FLG_R0 | IDT_FLG_INT32);
|
||||
amd64_idt_set(31, (uintptr_t) amd64_isr_31, 0x08, IDT_FLG_P | IDT_FLG_R0 | IDT_FLG_INT32);
|
||||
|
||||
amd64_idt_set(IRQ_BASE + 0, (uintptr_t) amd64_irq_0, 0x08, IDT_FLG_P | IDT_FLG_R0 | IDT_FLG_INT32);
|
||||
|
||||
asm volatile ("lea idtr(%%rip), %%rax; lidt (%%rax)":::"memory");
|
||||
}
|
||||
|
||||
@@ -35,3 +35,39 @@
|
||||
mov %ds, %rax
|
||||
pushq %rax
|
||||
.endm
|
||||
|
||||
.macro __int_pop_ctx
|
||||
// segments
|
||||
pop %rax
|
||||
mov %rax, %ds
|
||||
pop %rax
|
||||
mov %rax, %es
|
||||
pop %rax
|
||||
mov %rax, %fs
|
||||
pop %rax
|
||||
mov %rax, %gs
|
||||
|
||||
// cr3
|
||||
pop %rax
|
||||
mov %rax, %cr3
|
||||
|
||||
// r15-r8
|
||||
pop %r15
|
||||
pop %r14
|
||||
pop %r13
|
||||
pop %r12
|
||||
pop %r11
|
||||
pop %r10
|
||||
pop %r9
|
||||
pop %r8
|
||||
|
||||
// popal
|
||||
pop %rdi
|
||||
pop %rsi
|
||||
pop %rbp
|
||||
pop %rax // Ignore rsp
|
||||
pop %rbx
|
||||
pop %rdx
|
||||
pop %rcx
|
||||
pop %rax
|
||||
.endm
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "int_macros.inc"
|
||||
|
||||
.section .text
|
||||
.global amd64_irq_0
|
||||
amd64_irq_0:
|
||||
cli
|
||||
|
||||
__int_push_ctx
|
||||
|
||||
// EOI
|
||||
mov $0x20, %dx
|
||||
mov $0x20, %al
|
||||
outb %al, %dx
|
||||
|
||||
__int_pop_ctx
|
||||
|
||||
iretq
|
||||
@@ -0,0 +1,62 @@
|
||||
#include "pic8259.h"
|
||||
#include "io.h"
|
||||
|
||||
#define PIC_MCMD 0x20
|
||||
#define PIC_MDAT 0x21
|
||||
#define PIC_SCMD 0xA0
|
||||
#define PIC_SDAT 0xA1
|
||||
#define PIC_EOI 0x20
|
||||
|
||||
#define PIC_ICW1_ICW4 0x01
|
||||
#define PIC_ICW1_SINGLE 0x02
|
||||
#define PIC_ICW1_INTERVAL4 0x04
|
||||
#define PIC_ICW1_LEVEL 0x08
|
||||
#define PIC_ICW1_INIT 0x10
|
||||
|
||||
#define PIC_ICW4_8086 0x01
|
||||
#define PIC_ICW4_AUTO 0x02
|
||||
#define PIC_ICW4_BUF_SLAVE 0x08
|
||||
#define PIC_ICW4_BUF_MASTER 0x0C
|
||||
#define PIC_ICW4_SFNM 0x10
|
||||
|
||||
void pic8259_clear_mask(uint8_t line) {
|
||||
uint16_t port;
|
||||
uint8_t value;
|
||||
|
||||
if (line < 8) {
|
||||
port = PIC_MDAT;
|
||||
} else {
|
||||
port = PIC_SDAT;
|
||||
line -= 8;
|
||||
}
|
||||
value = inb(port) & ~(1 << line);
|
||||
outb(port, value);
|
||||
}
|
||||
|
||||
void pic8259_init(void) {
|
||||
uint8_t a1, a2;
|
||||
a1 = inb(PIC_MDAT);
|
||||
a2 = inb(PIC_SDAT);
|
||||
|
||||
outb(PIC_MCMD, PIC_ICW1_INIT | PIC_ICW1_ICW4);
|
||||
io_wait();
|
||||
outb(PIC_SCMD, PIC_ICW1_INIT | PIC_ICW1_ICW4);
|
||||
io_wait();
|
||||
outb(PIC_MDAT, IRQ_BASE);
|
||||
io_wait();
|
||||
outb(PIC_SDAT, IRQ_BASE + 8);
|
||||
io_wait();
|
||||
outb(PIC_MDAT, 4);
|
||||
io_wait();
|
||||
outb(PIC_SDAT, 2);
|
||||
io_wait();
|
||||
|
||||
outb(PIC_MDAT, PIC_ICW4_8086);
|
||||
io_wait();
|
||||
outb(PIC_SDAT, PIC_ICW4_8086);
|
||||
io_wait();
|
||||
|
||||
outb(PIC_MDAT, a1);
|
||||
outb(PIC_SDAT, a2);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#define IRQ_BASE 32
|
||||
|
||||
void pic8259_init(void);
|
||||
@@ -1,13 +1,22 @@
|
||||
#include "sys/mm.h"
|
||||
#include "sys/debug.h"
|
||||
#include "arch/amd64/hw/gdt.h"
|
||||
#include "arch/amd64/hw/pic8259.h"
|
||||
#include "arch/amd64/hw/ints.h"
|
||||
|
||||
// TODO: move to some util header
|
||||
#define __wfe() asm volatile ("sti; hlt")
|
||||
|
||||
void kernel_main(void) {
|
||||
kdebug("Booting\n");
|
||||
|
||||
// Memory management
|
||||
amd64_mm_init();
|
||||
amd64_gdt_init();
|
||||
pic8259_init();
|
||||
amd64_idt_init();
|
||||
|
||||
while (1) {
|
||||
__wfe();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user