mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
scheduler timer
abstraction of a timer that is local to each cpu and is used for scheduling
This commit is contained in:
+36
-3
@@ -9,7 +9,10 @@
|
|||||||
#define APIC_REGISTER_ID 0x20
|
#define APIC_REGISTER_ID 0x20
|
||||||
#define APIC_REGISTER_EOI 0xB0
|
#define APIC_REGISTER_EOI 0xB0
|
||||||
#define APIC_REGISTER_SPURIOUS 0xF0
|
#define APIC_REGISTER_SPURIOUS 0xF0
|
||||||
|
#define APIC_TIMER_LVT 0x320
|
||||||
|
#define APIC_TIMER_INITIALCOUNT 0x380
|
||||||
|
#define APIC_TIMER_COUNT 0x390
|
||||||
|
#define APIC_TIMER_DIVIDE 0x3E0
|
||||||
|
|
||||||
#define TYPE_LAPIC 0
|
#define TYPE_LAPIC 0
|
||||||
#define TYPE_IOAPIC 1
|
#define TYPE_IOAPIC 1
|
||||||
@@ -148,11 +151,38 @@ static void ioapic_writeiored(ioapic_descriptor* ioapic, uint8_t irq, uint8_t ve
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t lapic_readreg(size_t reg){
|
static inline uint32_t lapic_readreg(size_t reg){
|
||||||
return *(uint32_t* volatile)(lapicaddr + reg);
|
return *(uint32_t volatile*)(lapicaddr + reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void lapic_writereg(size_t reg, uint32_t data){
|
static inline void lapic_writereg(size_t reg, uint32_t data){
|
||||||
*(uint32_t* volatile)(lapicaddr + reg) = data;
|
*(uint32_t volatile*)(lapicaddr + reg) = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void apic_timerstart(size_t ticks){
|
||||||
|
lapic_writereg(APIC_TIMER_INITIALCOUNT, ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
void apic_timerinterruptset(uint8_t vector){
|
||||||
|
lapic_writereg(APIC_TIMER_LVT, vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
void apic_timerstop(){
|
||||||
|
lapic_writereg(APIC_TIMER_INITIALCOUNT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t apic_timercalibrate(size_t ms){
|
||||||
|
|
||||||
|
lapic_writereg(APIC_TIMER_INITIALCOUNT, 0xFFFFFFFF);
|
||||||
|
lapic_writereg(APIC_TIMER_DIVIDE, 0b111); // no divider
|
||||||
|
|
||||||
|
hpet_wait_ms(ms);
|
||||||
|
|
||||||
|
size_t ticks = 0xFFFFFFFF - lapic_readreg(APIC_TIMER_COUNT);
|
||||||
|
|
||||||
|
apic_timerstop();
|
||||||
|
|
||||||
|
return ticks;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void apic_lapicinit(){
|
void apic_lapicinit(){
|
||||||
@@ -161,6 +191,9 @@ void apic_lapicinit(){
|
|||||||
arch_getcls()->lapicid >>= 24;
|
arch_getcls()->lapicid >>= 24;
|
||||||
|
|
||||||
lapic_writereg(APIC_REGISTER_SPURIOUS, 0x1FF);
|
lapic_writereg(APIC_REGISTER_SPURIOUS, 0x1FF);
|
||||||
|
lapic_writereg(APIC_TIMER_LVT, 1 << 16); // mask timer interrupt off
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include <arch/isr.h>
|
#include <arch/isr.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <arch/schedtimer.h>
|
||||||
|
|
||||||
idtentry_t idt[256];
|
idtentry_t idt[256];
|
||||||
|
|
||||||
@@ -36,6 +37,8 @@ void idt_bspinit(){
|
|||||||
|
|
||||||
idt_setentry(&idt[VECTOR_PF], asmisr_pagefault, 0x28, FLAGS_PRESENT | FLAGS_TYPE_TRAP, 0);
|
idt_setentry(&idt[VECTOR_PF], asmisr_pagefault, 0x28, FLAGS_PRESENT | FLAGS_TYPE_TRAP, 0);
|
||||||
|
|
||||||
|
idt_setentry(&idt[SCHEDTIMER_VECTOR], asmisr_schedtimer, 0x28, FLAGS_PRESENT | FLAGS_TYPE_INTERRUPT, 0);
|
||||||
|
|
||||||
idt_reload();
|
idt_reload();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
#ifndef _APIC_H_INCLUDE
|
#ifndef _APIC_H_INCLUDE
|
||||||
#define _APIC_H_INCLUDE
|
#define _APIC_H_INCLUDE
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void apic_timerstop();
|
||||||
|
void apic_timerstart(size_t ticks);
|
||||||
|
void apic_timerinterruptset(uint8_t vector);
|
||||||
|
size_t apic_timercalibrate(size_t ms);
|
||||||
void apic_lapicinit();
|
void apic_lapicinit();
|
||||||
void apic_init();
|
void apic_init();
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ typedef struct{
|
|||||||
int lapicid;
|
int lapicid;
|
||||||
arch_regs *laststate;
|
arch_regs *laststate;
|
||||||
vmm_context *context;
|
vmm_context *context;
|
||||||
|
size_t schedtimerticksperms;
|
||||||
} cls_t;
|
} cls_t;
|
||||||
|
|
||||||
void bsp_setcls();
|
void bsp_setcls();
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef _CPUID_H_INCLUDE
|
||||||
|
#define _CPUID_H_INCLUDE
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <cpuid.h>
|
||||||
|
|
||||||
|
static inline uint64_t cpuid(){
|
||||||
|
uint32_t eax, unused, edx;
|
||||||
|
__get_cpuid(1, &eax, &unused, &unused, &edx);
|
||||||
|
return ((uint64_t)edx << 32) + eax;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <arch/regs.h>
|
#include <arch/regs.h>
|
||||||
|
|
||||||
|
extern void asmisr_schedtimer(arch_regs*);
|
||||||
extern void asmisr_general(arch_regs*);
|
extern void asmisr_general(arch_regs*);
|
||||||
extern void asmisr_except(arch_regs*);
|
extern void asmisr_except(arch_regs*);
|
||||||
extern void asmisr_pagefault(arch_regs*);
|
extern void asmisr_pagefault(arch_regs*);
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef _SCHEDTIMER_H_INCLUDE
|
||||||
|
#define _SCHEDTIMER_H_INCLUDE
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#define SCHEDTIMER_VECTOR 0x50
|
||||||
|
|
||||||
|
void arch_schedtimer_run(size_t ms);
|
||||||
|
void arch_schedtimer_stop();
|
||||||
|
void arch_schedtimer_calibrate();
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -126,6 +126,7 @@ section .text
|
|||||||
iretq
|
iretq
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
except asmisr_pagefault, isr_pagefault
|
except asmisr_pagefault, isr_pagefault
|
||||||
isr asmisr_general, isr_general
|
isr asmisr_general, isr_general
|
||||||
except asmisr_except, isr_except
|
except asmisr_except, isr_except
|
||||||
|
isr asmisr_schedtimer, isr_schedtimer
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
#include <arch/panic.h>
|
#include <arch/panic.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/vmm.h>
|
||||||
|
|
||||||
|
void isr_schedtimer(arch_regs *reg){
|
||||||
|
printf("schedtimer irq\n");
|
||||||
|
}
|
||||||
|
|
||||||
void isr_general(arch_regs *reg){
|
void isr_general(arch_regs *reg){
|
||||||
_panic("Unhandled interrupt", reg);
|
_panic("Unhandled interrupt", reg);
|
||||||
asm("hlt");
|
asm("hlt");
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ void kmain(){
|
|||||||
|
|
||||||
hpet_init();
|
hpet_init();
|
||||||
|
|
||||||
|
arch_schedtimer_calibrate();
|
||||||
|
|
||||||
smp_init();
|
smp_init();
|
||||||
|
|
||||||
_panic("End of kmain()", 0);
|
_panic("End of kmain()", 0);
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#include <arch/schedtimer.h>
|
||||||
|
#include <arch/cls.h>
|
||||||
|
#include <arch/apic.h>
|
||||||
|
|
||||||
|
void arch_schedtimer_waitms(size_t ms){
|
||||||
|
|
||||||
|
apic_timerstart(cls->schedtimerticksperms * ms);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void arch_schedtimer_stop(){
|
||||||
|
|
||||||
|
apic_timerstop();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void arch_schedtimer_calibrate(){
|
||||||
|
|
||||||
|
cls->schedtimerticksperms = apic_timercalibrate(1);
|
||||||
|
|
||||||
|
apic_timerinterruptset(SCHEDTIMER_VECTOR);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -18,8 +18,6 @@ static size_t cpucount = 1;
|
|||||||
|
|
||||||
static void apstartup(struct limine_smp_info *info){
|
static void apstartup(struct limine_smp_info *info){
|
||||||
|
|
||||||
spinlock_acquire(&lock);
|
|
||||||
|
|
||||||
arch_setcls(&apcls[info->processor_id]);
|
arch_setcls(&apcls[info->processor_id]);
|
||||||
|
|
||||||
gdt_init();
|
gdt_init();
|
||||||
@@ -30,11 +28,10 @@ static void apstartup(struct limine_smp_info *info){
|
|||||||
|
|
||||||
apic_lapicinit();
|
apic_lapicinit();
|
||||||
|
|
||||||
|
arch_schedtimer_calibrate();
|
||||||
|
|
||||||
printf("CPU %lu ready!\n", info->lapic_id);
|
printf("CPU %lu ready!\n", info->lapic_id);
|
||||||
|
|
||||||
spinlock_release(&lock);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
asm("cli;hlt");
|
asm("cli;hlt");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user