Big code refactor, get rid of HAL entirely
This commit is contained in:
245
kernel/intr/intr.c
Normal file
245
kernel/intr/intr.c
Normal file
@ -0,0 +1,245 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "intr/intr.h"
|
||||
#include "intr/pic.h"
|
||||
#include "intr/pit.h"
|
||||
#include "io/io.h"
|
||||
#include "cpu/gdt.h"
|
||||
#include "compiler/attr.h"
|
||||
#include "proc/proc.h"
|
||||
#include "syscall/syscall.h"
|
||||
#include "ipc/pipe/pipe.h"
|
||||
#include "rbuf/rbuf.h"
|
||||
#include "dlmalloc/malloc.h"
|
||||
#include "util/util.h"
|
||||
#include "cpu/hang.h"
|
||||
#include "kprintf.h"
|
||||
#include "errors.h"
|
||||
|
||||
typedef struct IntrHandler {
|
||||
struct IntrHandler *next;
|
||||
void (*fn)(void);
|
||||
int irq;
|
||||
} IntrHandler;
|
||||
|
||||
IntrHandler *INTR_HANDLERS = NULL;
|
||||
|
||||
void intr_attchhandler(void (*fn)(void), int irq) {
|
||||
IntrHandler *ih = dlmalloc(sizeof(*ih));
|
||||
ih->fn = fn;
|
||||
ih->irq = irq;
|
||||
LL_APPEND(INTR_HANDLERS, ih);
|
||||
}
|
||||
|
||||
typedef struct BackTraceFrame {
|
||||
struct BackTraceFrame *rbp;
|
||||
uint64_t rip;
|
||||
} BackTraceFrame;
|
||||
|
||||
void backtrace(BackTraceFrame *bt) {
|
||||
kprintf("Backtrace:\n");
|
||||
for (size_t frame = 0; bt; frame++) {
|
||||
kprintf(" %zu: 0x%lx\n", frame, bt->rip);
|
||||
bt = bt->rbp;
|
||||
}
|
||||
}
|
||||
|
||||
void intr_disable(void) {
|
||||
asm volatile("cli");
|
||||
}
|
||||
|
||||
void intr_enable(void) {
|
||||
asm volatile("sti");
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint16_t intrlow;
|
||||
uint16_t kernelcs;
|
||||
uint8_t ist;
|
||||
uint8_t attrs;
|
||||
uint16_t intrmid;
|
||||
uint32_t intrhigh;
|
||||
uint32_t resv;
|
||||
} PACKED IdtGate;
|
||||
|
||||
typedef struct {
|
||||
uint16_t limit;
|
||||
uint64_t base;
|
||||
} PACKED Idt;
|
||||
|
||||
#define ENTRIES 256
|
||||
ALIGNED(0x10) static IdtGate idtgates[ENTRIES] = {0};
|
||||
static Idt idt = {0};
|
||||
|
||||
void idt_setentry(int i, uint64_t handler, uint8_t flags) {
|
||||
idtgates[i].intrlow = handler & 0xffff;
|
||||
idtgates[i].kernelcs = KCODE;
|
||||
idtgates[i].ist = 0;
|
||||
idtgates[i].attrs = flags;
|
||||
idtgates[i].intrmid = (handler >> 16) & 0xFFFF;
|
||||
idtgates[i].intrhigh = (handler >> 32) & 0xFFFFFFFF;
|
||||
idtgates[i].resv = 0;
|
||||
}
|
||||
|
||||
void idt_init(void) {
|
||||
idt.base = (uint64_t)&idtgates;
|
||||
idt.limit = ENTRIES * sizeof(IdtGate) - 1;
|
||||
asm volatile("lidt %0" :: "m"(idt) : "memory");
|
||||
|
||||
LOG("hal", "idt init\n");
|
||||
}
|
||||
|
||||
extern void *ISR_REDIRTABLE[];
|
||||
|
||||
static const char *exceptions[] = {
|
||||
"#DE", "#DB", "NMI",
|
||||
"#BP", "#OF", "#BR",
|
||||
"#UD", "#NM", "#DF",
|
||||
"CSO", "#TS", "#NP",
|
||||
"#SS", "#GP", "#PF",
|
||||
"RES", "#MF", "#AC",
|
||||
"#MC", "#XM", "#VE",
|
||||
"#CP",
|
||||
};
|
||||
|
||||
void intr_init(void) {
|
||||
#define MKINTR(N) \
|
||||
extern void intr_vec##N(void); \
|
||||
idt_setentry(N, (uint64_t)&intr_vec##N, 0x8E);
|
||||
|
||||
MKINTR(0);
|
||||
MKINTR(1);
|
||||
MKINTR(2);
|
||||
MKINTR(4);
|
||||
MKINTR(5);
|
||||
MKINTR(6);
|
||||
MKINTR(7);
|
||||
MKINTR(8);
|
||||
MKINTR(9);
|
||||
MKINTR(10);
|
||||
MKINTR(11);
|
||||
MKINTR(12);
|
||||
MKINTR(13);
|
||||
MKINTR(14);
|
||||
MKINTR(15);
|
||||
MKINTR(16);
|
||||
MKINTR(17);
|
||||
MKINTR(18);
|
||||
MKINTR(19);
|
||||
MKINTR(20);
|
||||
MKINTR(21);
|
||||
MKINTR(22);
|
||||
MKINTR(23);
|
||||
MKINTR(24);
|
||||
MKINTR(25);
|
||||
MKINTR(26);
|
||||
MKINTR(27);
|
||||
MKINTR(28);
|
||||
MKINTR(29);
|
||||
MKINTR(30);
|
||||
MKINTR(31);
|
||||
MKINTR(32);
|
||||
MKINTR(33);
|
||||
MKINTR(34);
|
||||
MKINTR(35);
|
||||
MKINTR(36);
|
||||
MKINTR(37);
|
||||
MKINTR(38);
|
||||
MKINTR(39);
|
||||
MKINTR(40);
|
||||
MKINTR(41);
|
||||
MKINTR(42);
|
||||
MKINTR(43);
|
||||
MKINTR(44);
|
||||
MKINTR(45);
|
||||
MKINTR(46);
|
||||
MKINTR(47);
|
||||
|
||||
extern void intr_vec128(void);
|
||||
idt_setentry(0x80, (uint64_t)&intr_vec128, 0xEE);
|
||||
|
||||
idt_init();
|
||||
intr_pic_init();
|
||||
intr_pit_init();
|
||||
intr_disable();
|
||||
}
|
||||
|
||||
void intr_dumpframe(IntrStackFrame *frame) {
|
||||
uint64_t cr2;
|
||||
asm volatile("mov %%cr2, %0" : "=r"(cr2));
|
||||
uint64_t cr3;
|
||||
asm volatile("mov %%cr3, %0" : "=r"(cr3));
|
||||
uint64_t cr4;
|
||||
asm volatile("mov %%cr4, %0" : "=r"(cr4));
|
||||
kprintf("rax=%016lx rcx=%016lx rdx=%016lx\n"
|
||||
"rsi=%016lx rdi=%016lx r8 =%016lx\n"
|
||||
"r9 =%016lx r10=%016lx r11=%016lx\n"
|
||||
"rip=%016lx rfl=%016lx rsp=%016lx\n"
|
||||
"cs =%016lx ss =%016lx trp=%016lx\n"
|
||||
"cr2=%016lx cr3=%016lx cr4=%016lx\n"
|
||||
"\n\n",
|
||||
frame->regs.rax, frame->regs.rcx, frame->regs.rdx,
|
||||
frame->regs.rsi, frame->regs.rdi, frame->regs.r8,
|
||||
frame->regs.r9, frame->regs.r10, frame->regs.r11,
|
||||
frame->rip, frame->rflags, frame->rsp,
|
||||
frame->cs, frame->ss, frame->trapnum,
|
||||
cr2, cr3, cr4
|
||||
);
|
||||
}
|
||||
|
||||
void intr_syscalldispatch(IntrStackFrame *frame) {
|
||||
uint64_t sysnum = frame->regs.rax;
|
||||
if (sysnum < SYSCALLS_MAX) {
|
||||
SyscallFn fn = SYSCALL_TABLE[sysnum];
|
||||
if (fn == NULL) {
|
||||
frame->regs.rax = E_BADSYSCALL;
|
||||
return;
|
||||
}
|
||||
uint64_t calling_proc_pid = PROCS.current->pid;
|
||||
intr_enable();
|
||||
int32_t ret = fn(frame, calling_proc_pid, frame->regs.rdi, frame->regs.rsi, frame->regs.rdx,
|
||||
frame->regs.r10, frame->regs.r8, frame->regs.r9);
|
||||
|
||||
if (ret == E_DOSCHEDULING) {
|
||||
proc_sched((void *)frame);
|
||||
}
|
||||
frame->regs.rax = *(uint64_t *)&ret;
|
||||
}
|
||||
}
|
||||
|
||||
void intr_handleintr(IntrStackFrame *frame) {
|
||||
if (frame->trapnum <= 31) {
|
||||
kprintf("ERROR %s, 0x%lX\n", exceptions[frame->trapnum], frame->errnum);
|
||||
intr_dumpframe(frame);
|
||||
backtrace((BackTraceFrame *)frame->regs.rbp);
|
||||
if (frame->cs == (UCODE | 0x3)) {
|
||||
kprintf("killed pid %ld %s\n", PROCS.current->pid, PROCS.current->name);
|
||||
proc_killself();
|
||||
proc_sched((void *)frame);
|
||||
} else {
|
||||
kprintf("Kernel error :(\n");
|
||||
cpu_hang();
|
||||
}
|
||||
} else if (frame->trapnum >= 32 && frame->trapnum <= 47) {
|
||||
switch (frame->trapnum) {
|
||||
case INTR_IRQBASE+0:
|
||||
PIT_TICKS++;
|
||||
intr_pic_eoi();
|
||||
proc_sched((void *)frame);
|
||||
break;
|
||||
default:
|
||||
IntrHandler *ih, *ihtmp;
|
||||
LL_FOREACH_SAFE(INTR_HANDLERS, ih, ihtmp) {
|
||||
if ((uint64_t)ih->irq == frame->trapnum) {
|
||||
ih->fn();
|
||||
}
|
||||
}
|
||||
intr_pic_eoi();
|
||||
break;
|
||||
}
|
||||
} else if (frame->trapnum == 0x80) {
|
||||
intr_syscalldispatch(frame);
|
||||
}
|
||||
}
|
||||
|
||||
42
kernel/intr/intr.h
Normal file
42
kernel/intr/intr.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef INTR_INTR_H_
|
||||
#define INTR_INTR_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "compiler/attr.h"
|
||||
|
||||
#define INTR_IRQBASE 0x20
|
||||
|
||||
typedef struct {
|
||||
uint64_t r15;
|
||||
uint64_t r14;
|
||||
uint64_t r13;
|
||||
uint64_t r12;
|
||||
uint64_t r11;
|
||||
uint64_t r10;
|
||||
uint64_t r9;
|
||||
uint64_t r8;
|
||||
uint64_t rbp;
|
||||
uint64_t rdi;
|
||||
uint64_t rsi;
|
||||
uint64_t rdx;
|
||||
uint64_t rcx;
|
||||
uint64_t rax;
|
||||
} PACKED SavedRegs;
|
||||
|
||||
typedef struct {
|
||||
SavedRegs regs;
|
||||
uint64_t trapnum;
|
||||
uint64_t errnum;
|
||||
uint64_t rip;
|
||||
uint64_t cs;
|
||||
uint64_t rflags;
|
||||
uint64_t rsp;
|
||||
uint64_t ss;
|
||||
} PACKED IntrStackFrame;
|
||||
|
||||
void intr_attchhandler(void (*fn)(void), int irq);
|
||||
void intr_disable(void);
|
||||
void intr_enable(void);
|
||||
void intr_init(void);
|
||||
|
||||
#endif // INTR_INTR_H_
|
||||
221
kernel/intr/intr0.S
Normal file
221
kernel/intr/intr0.S
Normal file
@ -0,0 +1,221 @@
|
||||
#include "cpu/regs.S"
|
||||
|
||||
.extern intr_handleintr
|
||||
|
||||
.global intr_vec0
|
||||
.global intr_vec1
|
||||
.global intr_vec2
|
||||
.global intr_vec3
|
||||
.global intr_vec4
|
||||
.global intr_vec5
|
||||
.global intr_vec6
|
||||
.global intr_vec7
|
||||
.global intr_vec8
|
||||
.global intr_vec9
|
||||
.global intr_vec10
|
||||
.global intr_vec11
|
||||
.global intr_vec12
|
||||
.global intr_vec13
|
||||
.global intr_vec14
|
||||
.global intr_vec15
|
||||
.global intr_vec16
|
||||
.global intr_vec17
|
||||
.global intr_vec18
|
||||
.global intr_vec19
|
||||
.global intr_vec20
|
||||
.global intr_vec21
|
||||
.global intr_vec22
|
||||
.global intr_vec23
|
||||
.global intr_vec24
|
||||
.global intr_vec25
|
||||
.global intr_vec26
|
||||
.global intr_vec27
|
||||
.global intr_vec28
|
||||
.global intr_vec29
|
||||
.global intr_vec30
|
||||
.global intr_vec31
|
||||
.global intr_vec32
|
||||
.global intr_vec33
|
||||
.global intr_vec34
|
||||
.global intr_vec35
|
||||
.global intr_vec36
|
||||
.global intr_vec37
|
||||
.global intr_vec38
|
||||
.global intr_vec39
|
||||
.global intr_vec40
|
||||
.global intr_vec41
|
||||
.global intr_vec42
|
||||
.global intr_vec43
|
||||
.global intr_vec44
|
||||
.global intr_vec45
|
||||
.global intr_vec46
|
||||
.global intr_vec47
|
||||
.global intr_vec128
|
||||
|
||||
.macro _vecintr_errorcode_present_save num
|
||||
pushq $\num
|
||||
.endm
|
||||
|
||||
.macro _vecintr_plain_save num
|
||||
pushq $0x0
|
||||
pushq $\num
|
||||
.endm
|
||||
|
||||
.macro _vecintr_bodygen
|
||||
cli
|
||||
_push_regs
|
||||
cld
|
||||
movq %rsp, %rdi
|
||||
call intr_handleintr
|
||||
_pop_regs
|
||||
add $0x10, %rsp
|
||||
iretq
|
||||
.endm
|
||||
|
||||
intr_vec0:
|
||||
_vecintr_plain_save 0
|
||||
_vecintr_bodygen
|
||||
intr_vec1:
|
||||
_vecintr_plain_save 1
|
||||
_vecintr_bodygen
|
||||
intr_vec2:
|
||||
_vecintr_plain_save 2
|
||||
_vecintr_bodygen
|
||||
intr_vec3:
|
||||
_vecintr_plain_save 3
|
||||
_vecintr_bodygen
|
||||
intr_vec4:
|
||||
_vecintr_plain_save 4
|
||||
_vecintr_bodygen
|
||||
intr_vec5:
|
||||
_vecintr_plain_save 5
|
||||
_vecintr_bodygen
|
||||
intr_vec6:
|
||||
_vecintr_plain_save 6
|
||||
_vecintr_bodygen
|
||||
intr_vec7:
|
||||
_vecintr_plain_save 7
|
||||
_vecintr_bodygen
|
||||
intr_vec8:
|
||||
_vecintr_errorcode_present_save 8
|
||||
_vecintr_bodygen
|
||||
intr_vec9:
|
||||
_vecintr_plain_save 9
|
||||
_vecintr_bodygen
|
||||
intr_vec10:
|
||||
_vecintr_errorcode_present_save 10
|
||||
_vecintr_bodygen
|
||||
intr_vec11:
|
||||
_vecintr_errorcode_present_save 11
|
||||
_vecintr_bodygen
|
||||
intr_vec12:
|
||||
_vecintr_errorcode_present_save 12
|
||||
_vecintr_bodygen
|
||||
intr_vec13:
|
||||
_vecintr_errorcode_present_save 13
|
||||
_vecintr_bodygen
|
||||
intr_vec14:
|
||||
_vecintr_errorcode_present_save 14
|
||||
_vecintr_bodygen
|
||||
intr_vec15:
|
||||
_vecintr_plain_save 15
|
||||
_vecintr_bodygen
|
||||
intr_vec16:
|
||||
_vecintr_plain_save 16
|
||||
_vecintr_bodygen
|
||||
intr_vec17:
|
||||
_vecintr_errorcode_present_save 17
|
||||
_vecintr_bodygen
|
||||
intr_vec18:
|
||||
_vecintr_plain_save 18
|
||||
_vecintr_bodygen
|
||||
intr_vec19:
|
||||
_vecintr_plain_save 19
|
||||
_vecintr_bodygen
|
||||
intr_vec20:
|
||||
_vecintr_plain_save 20
|
||||
_vecintr_bodygen
|
||||
intr_vec21:
|
||||
_vecintr_errorcode_present_save 21
|
||||
_vecintr_bodygen
|
||||
intr_vec22:
|
||||
_vecintr_plain_save 22
|
||||
_vecintr_bodygen
|
||||
intr_vec23:
|
||||
_vecintr_plain_save 23
|
||||
_vecintr_bodygen
|
||||
intr_vec24:
|
||||
_vecintr_plain_save 24
|
||||
_vecintr_bodygen
|
||||
intr_vec25:
|
||||
_vecintr_plain_save 25
|
||||
_vecintr_bodygen
|
||||
intr_vec26:
|
||||
_vecintr_plain_save 26
|
||||
_vecintr_bodygen
|
||||
intr_vec27:
|
||||
_vecintr_plain_save 27
|
||||
_vecintr_bodygen
|
||||
intr_vec28:
|
||||
_vecintr_plain_save 28
|
||||
_vecintr_bodygen
|
||||
intr_vec29:
|
||||
_vecintr_errorcode_present_save 29
|
||||
_vecintr_bodygen
|
||||
intr_vec30:
|
||||
_vecintr_errorcode_present_save 30
|
||||
_vecintr_bodygen
|
||||
intr_vec31:
|
||||
_vecintr_plain_save 31
|
||||
_vecintr_bodygen
|
||||
intr_vec32:
|
||||
_vecintr_plain_save 32
|
||||
_vecintr_bodygen
|
||||
intr_vec33:
|
||||
_vecintr_plain_save 33
|
||||
_vecintr_bodygen
|
||||
intr_vec34:
|
||||
_vecintr_plain_save 34
|
||||
_vecintr_bodygen
|
||||
intr_vec35:
|
||||
_vecintr_plain_save 35
|
||||
_vecintr_bodygen
|
||||
intr_vec36:
|
||||
_vecintr_plain_save 36
|
||||
_vecintr_bodygen
|
||||
intr_vec37:
|
||||
_vecintr_plain_save 37
|
||||
_vecintr_bodygen
|
||||
intr_vec38:
|
||||
_vecintr_plain_save 38
|
||||
_vecintr_bodygen
|
||||
intr_vec39:
|
||||
_vecintr_plain_save 39
|
||||
_vecintr_bodygen
|
||||
intr_vec40:
|
||||
_vecintr_plain_save 40
|
||||
_vecintr_bodygen
|
||||
intr_vec41:
|
||||
_vecintr_plain_save 41
|
||||
_vecintr_bodygen
|
||||
intr_vec42:
|
||||
_vecintr_plain_save 42
|
||||
_vecintr_bodygen
|
||||
intr_vec43:
|
||||
_vecintr_plain_save 43
|
||||
_vecintr_bodygen
|
||||
intr_vec44:
|
||||
_vecintr_plain_save 44
|
||||
_vecintr_bodygen
|
||||
intr_vec45:
|
||||
_vecintr_plain_save 45
|
||||
_vecintr_bodygen
|
||||
intr_vec46:
|
||||
_vecintr_plain_save 46
|
||||
_vecintr_bodygen
|
||||
intr_vec47:
|
||||
_vecintr_plain_save 47
|
||||
_vecintr_bodygen
|
||||
intr_vec128:
|
||||
_vecintr_plain_save 128
|
||||
_vecintr_bodygen
|
||||
46
kernel/intr/pic.c
Normal file
46
kernel/intr/pic.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "io/io.h"
|
||||
#include "intr/pic.h"
|
||||
#include "intr/intr.h"
|
||||
|
||||
#define PIC1_CMD 0x0020
|
||||
#define PIC1_DATA 0x0021
|
||||
#define PIC2_CMD 0x00A0
|
||||
#define PIC2_DATA 0x00A1
|
||||
|
||||
#define PIC_EOI 0x20
|
||||
|
||||
#define ICW1_ICW4 0x01
|
||||
#define ICW1_SINGLE 0x02
|
||||
#define ICW1_ADI 0x04
|
||||
#define ICW1_LTIM 0x08
|
||||
#define ICW1_INIT 0x10
|
||||
|
||||
#define ICW4_8086 0x01
|
||||
#define ICW4_AUTO 0x02
|
||||
#define ICW4_BUFSLAVE 0x04
|
||||
#define ICW4_BUFMASTER 0x0C
|
||||
#define ICW4_SFNM 0x10
|
||||
|
||||
void intr_pic_init(void) {
|
||||
io_out8(PIC1_CMD, ICW1_INIT | ICW1_ICW4);
|
||||
io_out8(PIC2_CMD, ICW1_INIT | ICW1_ICW4);
|
||||
|
||||
io_out8(PIC1_DATA, INTR_IRQBASE);
|
||||
io_out8(PIC2_DATA, INTR_IRQBASE+8);
|
||||
|
||||
io_out8(PIC1_DATA, 2);
|
||||
io_out8(PIC2_DATA, 2);
|
||||
|
||||
io_out8(PIC1_DATA, ICW4_8086);
|
||||
io_out8(PIC2_DATA, ICW4_8086);
|
||||
|
||||
io_out8(PIC1_DATA, 0);
|
||||
io_out8(PIC2_DATA, 0);
|
||||
}
|
||||
|
||||
void intr_pic_eoi(void) {
|
||||
io_out8(PIC2_CMD, PIC_EOI);
|
||||
io_out8(PIC1_CMD, PIC_EOI);
|
||||
}
|
||||
7
kernel/intr/pic.h
Normal file
7
kernel/intr/pic.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef INTR_PIC_H_
|
||||
#define INTR_PIC_H_
|
||||
|
||||
void intr_pic_init(void);
|
||||
void intr_pic_eoi(void);
|
||||
|
||||
#endif // INTR_PIC_H_
|
||||
39
kernel/intr/pit.c
Normal file
39
kernel/intr/pit.c
Normal file
@ -0,0 +1,39 @@
|
||||
#include <stdint.h>
|
||||
#include "intr/pit.h"
|
||||
#include "io/io.h"
|
||||
|
||||
#define PIT_COUNTER0 0x40
|
||||
#define PIT_CMD 0x43
|
||||
#define PIT_CMD_BINARY 0x00
|
||||
#define PIT_CMD_BCD 0x01
|
||||
#define PIT_CMD_MODE0 0x00
|
||||
#define PIT_CMD_MODE1 0x02
|
||||
#define PIT_CMD_MODE2 0x04
|
||||
#define PIT_CMD_MODE3 0x06
|
||||
#define PIT_CMD_MODE4 0x08
|
||||
#define PIT_CMD_MODE5 0x0A
|
||||
#define PIT_CMD_LATCH 0x00
|
||||
#define PIT_CMD_RW_LOW 0x10
|
||||
#define PIT_CMD_RW_HI 0x20
|
||||
#define PIT_CMD_RW_BOTH 0x30
|
||||
#define PIT_CMD_COUNTER0 0x00
|
||||
#define PIT_CMD_COUNTER1 0x40
|
||||
#define PIT_CMD_COUNTER2 0x80
|
||||
#define PIT_CMD_READBACK 0xC0
|
||||
|
||||
#define PIT_FREQ 1193182
|
||||
|
||||
volatile uint32_t PIT_TICKS;
|
||||
|
||||
void intr_pit_init(void) {
|
||||
uint32_t hz = 1000;
|
||||
uint32_t div = PIT_FREQ / hz;
|
||||
io_out8(PIT_CMD, PIT_CMD_BINARY | PIT_CMD_MODE3 | PIT_CMD_RW_BOTH | PIT_CMD_COUNTER0);
|
||||
io_out8(PIT_COUNTER0, div & 0xFF);
|
||||
io_out8(PIT_COUNTER0, div >> 8);
|
||||
}
|
||||
|
||||
void intr_pit_wait(uint32_t ms) {
|
||||
uint32_t now = PIT_TICKS;
|
||||
while (PIT_TICKS - now < ms);
|
||||
}
|
||||
11
kernel/intr/pit.h
Normal file
11
kernel/intr/pit.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef INTR_PIT_H_
|
||||
#define INTR_PIT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern volatile uint32_t PIT_TICKS;
|
||||
|
||||
void intr_pit_init(void);
|
||||
void intr_pit_wait(uint32_t ms);
|
||||
|
||||
#endif // INTR_PIT_H_
|
||||
Reference in New Issue
Block a user