per cpu timer queue

This commit is contained in:
Matheus
2022-08-12 22:11:59 -03:00
parent ab2bd69481
commit ac5339453b
11 changed files with 174 additions and 13 deletions
+10 -5
View File
@@ -190,22 +190,27 @@ void apic_timerinterruptset(uint8_t vector){
lapic_writereg(APIC_TIMER_LVT, vector);
}
void apic_timerstop(){
size_t apic_timerstop(){
size_t ticksremaining = lapic_readreg(APIC_TIMER_COUNT);
lapic_writereg(APIC_TIMER_INITIALCOUNT, 0);
return ticksremaining;
}
size_t apic_timercalibrate(size_t ms){
size_t apic_timercalibrate(size_t us){
lapic_writereg(APIC_TIMER_INITIALCOUNT, 0xFFFFFFFF);
lapic_writereg(APIC_TIMER_DIVIDE, 0b111); // no divider
hpet_wait_ms(ms);
hpet_wait_ms(us);
size_t ticks = 0xFFFFFFFF - lapic_readreg(APIC_TIMER_COUNT);
apic_timerstop();
return ticks;
return ticks / 1000;
}
+22
View File
@@ -0,0 +1,22 @@
#include <arch/cputimer.h>
#include <arch/apic.h>
#include <arch/idt.h>
size_t arch_cputimer_init(){
// XXX invariant TSC?
size_t ticks = apic_timercalibrate(1);
apic_timerinterruptset(VECTOR_TIMER);
return ticks;
}
size_t arch_cputimer_stop(){
return apic_timerstop();
}
void arch_cputimer_fire(size_t ticks){
apic_timerstart(ticks);
}
+4 -4
View File
@@ -2,7 +2,7 @@
#include <arch/gdt.h>
#include <arch/ist.h>
static void setseg(segdesc __seg_gs *seg, uint32_t limit, uint32_t offset, uint8_t flags, uint8_t access){
static void setseg(segdesc *seg, uint32_t limit, uint32_t offset, uint8_t flags, uint8_t access){
seg->limit = limit & 0xFFFF;
seg->offset1 = offset & 0xFFFF;
@@ -14,7 +14,7 @@ static void setseg(segdesc __seg_gs *seg, uint32_t limit, uint32_t offset, uint8
}
static void setsys64(sys64 __seg_gs *e, uint32_t limit, uint64_t offset, uint8_t flags, uint8_t access){
static void setsys64(sys64 *e, uint32_t limit, uint64_t offset, uint8_t flags, uint8_t access){
e->limit = limit & 0xFFFF;
e->offset1 = offset & 0xFFFF;
@@ -32,14 +32,14 @@ gdtr_t gdtr;
static void reloadgdtr(){
gdtr.offset = (uint64_t)&cls->gdt + arch_getcls();
gdtr.offset = &arch_getcls()->gdt;
gdtr.size = sizeof(gdt_t) - 1;
asm("lgdt (%%rax)" : : "a"(&gdtr) : "memory");
}
void gdt_init(){
gdt_t __seg_gs *gdt = &cls->gdt;
gdt_t* gdt = &arch_getcls()->gdt;
setseg(&gdt->null, 0, 0, 0, 0);
+2 -2
View File
@@ -6,10 +6,10 @@
void apic_sendipi(uint8_t cpu, uint8_t vec, uint8_t dest, uint8_t mode, uint8_t level);
void apic_eoi();
void apic_timerstop();
size_t apic_timerstop();
void apic_timerstart(size_t ticks);
void apic_timerinterruptset(uint8_t vector);
size_t apic_timercalibrate(size_t ms);
size_t apic_timercalibrate(size_t us);
void apic_lapicinit();
void apic_init();
+3 -1
View File
@@ -7,6 +7,7 @@
#include <arch/regs.h>
#include <kernel/vmm.h>
#include <kernel/sched.h>
#include <kernel/timer.h>
// cpu level storage
// this will be pointed to by GS and will contain per cpu info
@@ -19,7 +20,8 @@ typedef struct{
arch_regs *laststate;
vmm_context *context;
thread_t* thread;
size_t schedtimerticksperms;
size_t timerticksperus;
timer_req* timerfirstreq;
} cls_t;
void bsp_setcls();
+10
View File
@@ -0,0 +1,10 @@
#ifndef _CPUTIMER_H_INCLUDE
#define _CPUTIMER_H_INCLUDE
#include <stddef.h>
size_t arch_cputimer_init();
size_t arch_cputimer_stop();
void arch_cputimer_fire(size_t ticks);
#endif
+2
View File
@@ -2,6 +2,7 @@
#include <arch/panic.h>
#include <kernel/vmm.h>
#include <arch/apic.h>
#include <kernel/timer.h>
void isr_general(arch_regs *reg){
_panic("Unhandled interrupt", reg);
@@ -30,5 +31,6 @@ void isr_mmuinval(){
}
void isr_timer(arch_regs* reg){
timer_irq(reg);
apic_eoi();
}
+6 -1
View File
@@ -16,6 +16,7 @@
#include <arch/pci.h>
#include <arch/hpet.h>
#include <arch/smp.h>
#include <kernel/timer.h>
static volatile struct limine_terminal_request liminettyr = {
.id = LIMINE_TERMINAL_REQUEST,
@@ -42,7 +43,9 @@ void kmain(){
console_setwritehook(liminewrite);
bsp_setcls();
gdt_init();
idt_bspinit();
pmm_init();
@@ -62,6 +65,8 @@ void kmain(){
hpet_init();
timer_init();
vfs_init();
printf("Mounting tmpfs in /\n");
@@ -76,7 +81,7 @@ void kmain(){
pci_enumerate();
smp_init();
_panic("End of kmain()", 0);
}
+4
View File
@@ -28,6 +28,8 @@ static void apstartup(struct limine_smp_info *info){
arch_mmu_apinit();
apic_lapicinit();
timer_init();
printf("CPU %lu ready!\n", info->lapic_id);
@@ -62,6 +64,8 @@ void smp_init(){
apcls = pmm_hhdmalloc(sizeof(cls_t)*cpucount/PAGE_SIZE+1);
memset(apcls, 0, sizeof(cls_t)*cpucount/PAGE_SIZE+1);
printf("System has %lu CPUs\n", cpucount);
sem = sem_init(-cpucount + 2, 0);
+22
View File
@@ -0,0 +1,22 @@
#ifndef _TIMER_H_INCLUDE
#define _TIMER_H_INCLUDE
#include <stddef.h>
#include <arch/regs.h>
typedef struct _timer_req{
// values callee should care about
void* (*func)(arch_regs*, void*);
void* argptr;
// internal values
struct _timer_req* next;
size_t ticks;
} timer_req;
void timer_init();
void timer_add(timer_req* req, size_t us);
void timer_resume();
void timer_stop();
void timer_irq(arch_regs* ctx);
#endif
+89
View File
@@ -0,0 +1,89 @@
#include <kernel/timer.h>
#include <arch/cputimer.h>
#include <arch/cls.h>
#include <stdio.h>
void timer_init(){
cls_t* cls = arch_getcls();
cls->timerticksperus = arch_cputimer_init();
printf("CPU%d: CPUTIMER tick: %lu per us\n", cls->lapicid, cls->timerticksperus);
}
void timer_irq(arch_regs* ctx){
timer_req* pendingreq = arch_getcls()->timerfirstreq;
timer_req* iter = pendingreq->next;
arch_getcls()->timerfirstreq = iter;
while(iter){
iter->ticks -= pendingreq->ticks;
iter = iter->next;
}
pendingreq->func(ctx, pendingreq->argptr);
if(!arch_getcls()->timerfirstreq) return;
arch_cputimer_fire(arch_getcls()->timerfirstreq->ticks);
}
void timer_resume(){
arch_cputimer_fire(arch_getcls()->timerfirstreq->ticks);
}
void timer_stop(){
size_t remainingticks = arch_cputimer_stop();
timer_req* iter = arch_getcls()->timerfirstreq;
size_t subticks = iter->ticks - remainingticks;
while(iter){
iter->ticks -= subticks;
iter = iter->next;
}
}
void timer_add(timer_req* req, size_t us){
size_t remainingticks = arch_cputimer_stop();
timer_req* iter = arch_getcls()->timerfirstreq;
req->ticks = us*arch_getcls()->timerticksperus;
if(!iter){
arch_getcls()->timerfirstreq = req;
req->next = NULL;
arch_cputimer_fire(req->ticks);
printf("ticks3: %lu", req->ticks);
return;
}
size_t subticks = iter->ticks - remainingticks;
while(iter){
iter->ticks -= subticks;
iter = iter->next;
}
iter = arch_getcls()->timerfirstreq;
if(iter->ticks > req->ticks){
req->next = arch_getcls()->timerfirstreq;
arch_getcls()->timerfirstreq = req;
arch_cputimer_fire(req->ticks);
printf("ticks2: %lu", req->ticks);
return;
}
while(iter->next && iter->next->ticks <= req->ticks)
iter = iter->next;
req->next = iter->next;
iter->next = req;
printf("ticks: %lu", arch_getcls()->timerfirstreq->ticks);
arch_cputimer_fire(arch_getcls()->timerfirstreq->ticks);
}