[amd64] timer irq

This commit is contained in:
Mark
2019-03-25 17:04:33 +02:00
parent 29ebc06bee
commit cbab36dd2b
7 changed files with 137 additions and 1 deletions
+3 -1
View File
@@ -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
+6
View File
@@ -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");
}
+36
View File
@@ -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
+17
View File
@@ -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
+62
View File
@@ -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);
}
+4
View File
@@ -0,0 +1,4 @@
#pragma once
#define IRQ_BASE 32
void pic8259_init(void);
+9
View File
@@ -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();
}
}