mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 15:34:33 +00:00
Fixed timer calibration
This commit is contained in:
parent
782b3fa78a
commit
7918999799
@ -208,6 +208,14 @@ namespace APIC
|
|||||||
else if (madt->nmi[i]->lint == 1)
|
else if (madt->nmi[i]->lint == 1)
|
||||||
this->Write(APIC_LINT1, nmi);
|
this->Write(APIC_LINT1, nmi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disable PIT
|
||||||
|
outb(0x43, 0x28);
|
||||||
|
outb(0x40, 0x0);
|
||||||
|
|
||||||
|
// Disable PIC
|
||||||
|
outb(0x21, 0xFF);
|
||||||
|
outb(0xA1, 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
APIC::~APIC()
|
APIC::~APIC()
|
||||||
@ -224,62 +232,84 @@ namespace APIC
|
|||||||
|
|
||||||
void Timer::OneShot(uint32_t Vector, uint64_t Miliseconds)
|
void Timer::OneShot(uint32_t Vector, uint64_t Miliseconds)
|
||||||
{
|
{
|
||||||
this->lapic->Write(APIC_TDCR, 0x03);
|
LVTTimer timer = {.raw = 0};
|
||||||
LVTTimer timer = {0, 0, 0, 0, 0, 0, 0};
|
|
||||||
timer.Vector = Vector;
|
timer.Vector = Vector;
|
||||||
timer.TimerMode = 0;
|
timer.TimerMode = 0;
|
||||||
|
this->lapic->Write(APIC_TDCR, 0x0);
|
||||||
|
this->lapic->Write(APIC_TICR, Ticks * Miliseconds);
|
||||||
this->lapic->Write(APIC_TIMER, timer.raw);
|
this->lapic->Write(APIC_TIMER, timer.raw);
|
||||||
this->lapic->Write(APIC_TICR, (TicksIn10ms / 10) * Miliseconds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer::Timer(APIC *apic) : Interrupts::Handler(IRQ0)
|
Timer::Timer(APIC *apic) : Interrupts::Handler(IRQ0)
|
||||||
{
|
{
|
||||||
trace("Initializing APIC timer on CPU %d", GetCurrentCPU()->ID);
|
|
||||||
this->lapic = apic;
|
this->lapic = apic;
|
||||||
this->lapic->Write(APIC_TDCR, 0x3);
|
trace("Initializing APIC timer on CPU %d", GetCurrentCPU()->ID);
|
||||||
|
|
||||||
int Count = 10000; /* µs */
|
// Setup the spurrious interrupt vector
|
||||||
int Ticks = 1193180 / (Count / 100);
|
APICSpurious Spurious = {.raw = this->lapic->Read(APIC_SVR)};
|
||||||
|
Spurious.Vector = IRQ223; // TODO: Should I map the IRQ to something?
|
||||||
int IOIn = inb(0x61);
|
Spurious.Software = 1;
|
||||||
IOIn = (IOIn & 0xFD) | 1;
|
this->lapic->Write(APIC_SVR, Spurious.raw);
|
||||||
outb(0x61, IOIn);
|
|
||||||
outb(0x43, 178);
|
|
||||||
outb(0x40, Ticks & 0xff);
|
|
||||||
inb(0x60);
|
|
||||||
outb(0x40, Ticks >> 8);
|
|
||||||
|
|
||||||
|
this->lapic->Write(APIC_TDCR, 0x0);
|
||||||
this->lapic->Write(APIC_TICR, 0xFFFFFFFF);
|
this->lapic->Write(APIC_TICR, 0xFFFFFFFF);
|
||||||
|
|
||||||
IOIn = inb(0x61);
|
// After PIT sleep is completed. Mask the timer.
|
||||||
IOIn = (IOIn & 0xFC);
|
LVTTimer masktimer = {.raw = 0x10000};
|
||||||
outb(0x61, IOIn);
|
|
||||||
IOIn |= 1;
|
|
||||||
outb(0x61, IOIn);
|
|
||||||
uint32_t Loop = 0;
|
|
||||||
while ((inb(0x61) & 0x20) != 0)
|
|
||||||
++Loop;
|
|
||||||
|
|
||||||
this->lapic->Write(APIC_TIMER, 0x10000);
|
// // PIT Config
|
||||||
|
// int Count = 10000; /* µs */
|
||||||
|
// int Ticks = 1193180 / (Count / 100);
|
||||||
|
|
||||||
outb(0x43, 0x28);
|
// // https://wiki.osdev.org/Programmable_Interval_Timer#I.2FO_Ports
|
||||||
outb(0x40, 0x0);
|
|
||||||
|
|
||||||
outb(0x21, 0xFF);
|
// // PIT Prepare
|
||||||
outb(0xA1, 0xFF);
|
// int IOIn = inb(0x61);
|
||||||
|
// IOIn = (IOIn & 0xFD) | 1;
|
||||||
|
// outb(0x61, IOIn);
|
||||||
|
// outb(0x43, 178);
|
||||||
|
// outb(0x40, Ticks & 0xff);
|
||||||
|
// inb(0x60);
|
||||||
|
// outb(0x40, Ticks >> 8);
|
||||||
|
|
||||||
TicksIn10ms = 0xFFFFFFFF - this->lapic->Read(APIC_TCCR);
|
// // PIT Start
|
||||||
|
// IOIn = inb(0x61);
|
||||||
|
// IOIn = (IOIn & 0xFC);
|
||||||
|
// outb(0x61, IOIn);
|
||||||
|
// IOIn |= 1;
|
||||||
|
// outb(0x61, IOIn);
|
||||||
|
// uint32_t Loop = 0;
|
||||||
|
// while ((inb(0x61) & 0x20) != 0)
|
||||||
|
// ++Loop;
|
||||||
|
|
||||||
LVTTimer timer = {0, 0, 0, 0, 0, 0, 0};
|
// 10000ms
|
||||||
|
for (int i = 0; i < 10000; i++)
|
||||||
|
inb(0x80); // 1µs
|
||||||
|
|
||||||
|
// Mask the timer
|
||||||
|
this->lapic->Write(APIC_TIMER, masktimer.raw);
|
||||||
|
|
||||||
|
// // Disable the PIT
|
||||||
|
// outb(0x43, 0x28);
|
||||||
|
// outb(0x40, 0x0);
|
||||||
|
|
||||||
|
// outb(0x21, 0xFF);
|
||||||
|
// outb(0xA1, 0xFF);
|
||||||
|
|
||||||
|
Ticks = 0xFFFFFFFF - this->lapic->Read(APIC_TCCR);
|
||||||
|
|
||||||
|
// Config for IRQ0 timer
|
||||||
|
LVTTimer timer = {.raw = 0};
|
||||||
timer.Vector = IRQ0;
|
timer.Vector = IRQ0;
|
||||||
timer.Mask = 0;
|
timer.Mask = 0;
|
||||||
timer.TimerMode = 1;
|
timer.TimerMode = 1;
|
||||||
|
|
||||||
|
// Initialize APIC timer
|
||||||
|
this->lapic->Write(APIC_TDCR, 0x0);
|
||||||
|
this->lapic->Write(APIC_TICR, Ticks);
|
||||||
this->lapic->Write(APIC_TIMER, timer.raw);
|
this->lapic->Write(APIC_TIMER, timer.raw);
|
||||||
this->lapic->Write(APIC_TDCR, 0x3);
|
trace("%d APIC Timer %d ticks in.", GetCurrentCPU()->ID, Ticks);
|
||||||
this->lapic->Write(APIC_TICR, TicksIn10ms / 10);
|
KPrint("APIC Timer: \e8888FF%ld\eCCCCCC ticks.", Ticks);
|
||||||
trace("APIC Timer (CPU %d): %d ticks in 10ms", GetCurrentCPU()->ID, TicksIn10ms / 10);
|
|
||||||
KPrint("APIC Timer: \e8888FF%ld\eCCCCCC ticks in 10ms", TicksIn10ms / 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer::~Timer()
|
Timer::~Timer()
|
||||||
|
@ -86,6 +86,26 @@ namespace APIC
|
|||||||
uint64_t raw;
|
uint64_t raw;
|
||||||
} __attribute__((packed)) LVTTimer;
|
} __attribute__((packed)) LVTTimer;
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
/** @brief Spurious Vector */
|
||||||
|
uint64_t Vector : 8;
|
||||||
|
/** @brief Enable or disable APIC software */
|
||||||
|
uint64_t Software : 1;
|
||||||
|
/** @brief Focus Processor Checking */
|
||||||
|
uint64_t FocusProcessorChecking : 1;
|
||||||
|
/** @brief Reserved */
|
||||||
|
uint64_t Reserved : 2;
|
||||||
|
/** @brief Disable EOI Broadcast */
|
||||||
|
uint64_t DisableEOIBroadcast : 1;
|
||||||
|
/** @brief Reserved */
|
||||||
|
uint64_t Reserved1 : 19;
|
||||||
|
};
|
||||||
|
uint64_t raw;
|
||||||
|
} __attribute__((packed)) APICSpurious;
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
@ -123,11 +143,11 @@ namespace APIC
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
APIC *lapic;
|
APIC *lapic;
|
||||||
uint64_t TicksIn10ms = 0;
|
uint64_t Ticks = 0;
|
||||||
void OnInterruptReceived(CPU::x64::TrapFrame *Frame);
|
void OnInterruptReceived(CPU::x64::TrapFrame *Frame);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
uint64_t GetTicksIn10ms() { return TicksIn10ms; }
|
uint64_t GetTicks() { return Ticks; }
|
||||||
void OneShot(uint32_t Vector, uint64_t Miliseconds);
|
void OneShot(uint32_t Vector, uint64_t Miliseconds);
|
||||||
Timer(APIC *apic);
|
Timer(APIC *apic);
|
||||||
~Timer();
|
~Timer();
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// #define DEBUG_SCHEDULER 1
|
#define DEBUG_SCHEDULER 1
|
||||||
|
|
||||||
#ifdef DEBUG_SCHEDULER
|
#ifdef DEBUG_SCHEDULER
|
||||||
#define schedbg(m, ...) debug(m, ##__VA_ARGS__)
|
#define schedbg(m, ...) debug(m, ##__VA_ARGS__)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user