Enable PIT ISR to count milliseconds

This commit is contained in:
Josh Holtrop 2023-10-25 12:02:44 -04:00
parent e357f2ba44
commit e480bd0ed0
4 changed files with 18 additions and 5 deletions

View File

@ -7,11 +7,14 @@ import hulk.hurl;
import hulk.acpi; import hulk.acpi;
import hulk.idt; import hulk.idt;
import hulk.rtc; import hulk.rtc;
import hulk.pit;
import hulk.klog;
struct Apic struct Apic
{ {
private enum uint PERIODIC_MODE = 0x2_0000u; private enum uint PERIODIC_MODE = 0x2_0000u;
private enum ulong IRQ_PIT = 2u;
private enum ulong IRQ_RTC = 8u; private enum ulong IRQ_RTC = 8u;
static struct ApicRegister static struct ApicRegister
@ -77,6 +80,8 @@ struct Apic
apic_registers.lvt_timer.value = Idt.INT_APIC_TIMER; apic_registers.lvt_timer.value = Idt.INT_APIC_TIMER;
apic_registers.lvt_lint[0].value = Idt.INT_APIC_LINT0; apic_registers.lvt_lint[0].value = Idt.INT_APIC_LINT0;
apic_registers.lvt_lint[1].value = Idt.INT_APIC_LINT1; apic_registers.lvt_lint[1].value = Idt.INT_APIC_LINT1;
/* Enable PIT interrupt. */
configure_io_apic_irq(IRQ_PIT, Idt.INT_APIC_BASE + IRQ_PIT);
/* Enable RTC interrupt. */ /* Enable RTC interrupt. */
configure_io_apic_irq(IRQ_RTC, Idt.INT_APIC_BASE + IRQ_RTC); configure_io_apic_irq(IRQ_RTC, Idt.INT_APIC_BASE + IRQ_RTC);
} }
@ -99,11 +104,16 @@ struct Apic
{ {
switch (vector) switch (vector)
{ {
case Idt.INT_APIC_BASE + IRQ_PIT:
Pit.isr();
break;
case Idt.INT_APIC_BASE + IRQ_RTC: case Idt.INT_APIC_BASE + IRQ_RTC:
Rtc.isr(); Rtc.isr();
break; break;
default: default:
Klog.writefln("Unhandled APIC ISR %u", vector);
break; break;
} }
eoi(); eoi();

View File

@ -23,6 +23,7 @@ import hulk.apic;
import hulk.rtc; import hulk.rtc;
import hulk.serial; import hulk.serial;
import hulk.usb; import hulk.usb;
import hulk.pit;
extern extern(C) __gshared ubyte _hulk_bss_size; extern extern(C) __gshared ubyte _hulk_bss_size;
@ -81,7 +82,7 @@ void hulk_start()
Rtc.time t = Rtc.read_rtc_time(); Rtc.time t = Rtc.read_rtc_time();
Klog.writefln("System time is 20%02u-%02u-%02u %02u:%02u:%02u", Klog.writefln("System time is 20%02u-%02u-%02u %02u:%02u:%02u",
t.year, t.month, t.day, t.hour, t.minute, t.second); t.year, t.month, t.day, t.hour, t.minute, t.second);
Pit.initialize();
Pci.initialize(); Pci.initialize();
Usb.initialize(); Usb.initialize();
sti(); sti();

View File

@ -5,12 +5,13 @@ module hulk.pit;
import hulk.cpu; import hulk.cpu;
import hulk.klog; import hulk.klog;
import hulk.console;
struct Pit struct Pit
{ {
/** PIT input frequency in 1/1000 Hz. */ /** PIT input frequency in 1/1000 Hz. */
private enum ulong PIT_FREQUENCY_1000HZ = 1_193_181_667u; private enum ulong PIT_FREQUENCY_1000HZ = 1_193_181_667u;
private enum ulong TARGET_INTERRUPT_HZ = 100u; private enum ulong TARGET_INTERRUPT_HZ = 1000u;
private enum ulong TARGET_INTERRUPT_1000HZ = TARGET_INTERRUPT_HZ * 1000u; private enum ulong TARGET_INTERRUPT_1000HZ = TARGET_INTERRUPT_HZ * 1000u;
private enum ulong PIT_DIVIDER = (PIT_FREQUENCY_1000HZ + TARGET_INTERRUPT_1000HZ / 2u) / TARGET_INTERRUPT_1000HZ; private enum ulong PIT_DIVIDER = (PIT_FREQUENCY_1000HZ + TARGET_INTERRUPT_1000HZ / 2u) / TARGET_INTERRUPT_1000HZ;
@ -28,8 +29,11 @@ struct Pit
private enum ubyte MC_RATE_GENERATOR = 0x04u; private enum ubyte MC_RATE_GENERATOR = 0x04u;
private enum ubyte MC_BINARY = 0x00u; private enum ubyte MC_BINARY = 0x00u;
private static __gshared ulong milliseconds;
public static void initialize() public static void initialize()
{ {
Klog.writefln("\a3Initializing PIT");
out8(PORT_MC, MC_CH_0 | MC_LO_HI | MC_RATE_GENERATOR | MC_BINARY); out8(PORT_MC, MC_CH_0 | MC_LO_HI | MC_RATE_GENERATOR | MC_BINARY);
out8(PORT_CH_0, PIT_DIVIDER & 0xFFu); out8(PORT_CH_0, PIT_DIVIDER & 0xFFu);
out8(PORT_CH_0, PIT_DIVIDER >> 8u); out8(PORT_CH_0, PIT_DIVIDER >> 8u);
@ -37,6 +41,6 @@ struct Pit
public static void isr() public static void isr()
{ {
Klog.writefln("PIT ISR"); milliseconds++;
} }
} }

View File

@ -79,11 +79,9 @@ struct Rtc
public static void isr() public static void isr()
{ {
static __gshared ulong count; static __gshared ulong count;
static __gshared ulong seconds;
count++; count++;
if ((count % 1024) == 0u) if ((count % 1024) == 0u)
{ {
seconds++;
Console.update_header(); Console.update_header();
} }
eoi(); eoi();