Kernel: HPET doesn't use the legacy mapping anymore

This commit is contained in:
Bananymous 2023-08-10 21:04:01 +03:00
parent f7449c4ab9
commit 778778fede
1 changed files with 18 additions and 6 deletions

View File

@ -21,6 +21,7 @@
#define HPET_Tn_TYPE_CNF (1 << 3) #define HPET_Tn_TYPE_CNF (1 << 3)
#define HPET_Tn_PER_INT_CAP (1 << 4) #define HPET_Tn_PER_INT_CAP (1 << 4)
#define HPET_Tn_VAL_SET_CNF (1 << 6) #define HPET_Tn_VAL_SET_CNF (1 << 6)
#define HPET_Tn_INT_ROUTE_CNF_SHIFT 9
#define FS_PER_S 1'000'000'000'000'000 #define FS_PER_S 1'000'000'000'000'000
#define FS_PER_MS 1'000'000'000'000 #define FS_PER_MS 1'000'000'000'000
@ -30,8 +31,6 @@
namespace Kernel namespace Kernel
{ {
static uint64_t s_system_time = 0;
BAN::ErrorOr<BAN::UniqPtr<HPET>> HPET::create() BAN::ErrorOr<BAN::UniqPtr<HPET>> HPET::create()
{ {
HPET* hpet = new HPET(); HPET* hpet = new HPET();
@ -93,13 +92,26 @@ namespace Kernel
return BAN::Error::from_errno(ENOTSUP); return BAN::Error::from_errno(ENOTSUP);
} }
uint32_t irq_cap = timer0_config >> 32;
if (irq_cap == 0)
{
dwarnln("HPET doesn't have any interrupts available");
return BAN::Error::from_errno(EINVAL);
}
int irq = 0;
for (; irq < 32; irq++)
if (irq_cap & (1 << irq))
break;
unmapper.disable(); unmapper.disable();
// Enable main counter // Enable main counter
write_register(HPET_REG_CONFIG, read_register(HPET_REG_CONFIG) | HPET_CONFIG_LEG_RT | HPET_CONFIG_ENABLE); write_register(HPET_REG_CONFIG, read_register(HPET_REG_CONFIG) | HPET_CONFIG_ENABLE);
// Enable timer 0 as 1 ms periodic // Enable timer 0 as 1 ms periodic
write_register(HPET_REG_TIMER_CONFIG(0), HPET_Tn_INT_ENB_CNF | HPET_Tn_TYPE_CNF | HPET_Tn_VAL_SET_CNF); write_register(HPET_REG_TIMER_CONFIG(0), HPET_Tn_INT_ENB_CNF | HPET_Tn_TYPE_CNF | HPET_Tn_VAL_SET_CNF | (irq << HPET_Tn_INT_ROUTE_CNF_SHIFT));
write_register(HPET_REG_TIMER_COMPARATOR(0), read_register(HPET_REG_COUNTER) + ticks_per_ms); write_register(HPET_REG_TIMER_COMPARATOR(0), read_register(HPET_REG_COUNTER) + ticks_per_ms);
write_register(HPET_REG_TIMER_COMPARATOR(0), ticks_per_ms); write_register(HPET_REG_TIMER_COMPARATOR(0), ticks_per_ms);
@ -107,8 +119,8 @@ namespace Kernel
for (int i = 1; i <= header->comparator_count; i++) for (int i = 1; i <= header->comparator_count; i++)
write_register(HPET_REG_TIMER_CONFIG(i), 0); write_register(HPET_REG_TIMER_CONFIG(i), 0);
IDT::register_irq_handler(0, [] { s_system_time++; Scheduler::get().timer_reschedule(); }); IDT::register_irq_handler(irq, [] { Scheduler::get().timer_reschedule(); });
InterruptController::get().enable_irq(0); InterruptController::get().enable_irq(irq);
return {}; return {};
} }