Skip to content

Commit

Permalink
Reset the HPET comparators to a known state during initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
ilmmatias committed Jan 21, 2025
1 parent f4b7b83 commit 0e4401f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 7 deletions.
21 changes: 16 additions & 5 deletions src/kernel/hal/amd64/hpet.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

static void *HpetAddress = NULL;
static uint64_t Period = 1;
static uint64_t MinimumTicks = 0;

/*-------------------------------------------------------------------------------------------------
* PURPOSE:
Expand Down Expand Up @@ -63,17 +62,29 @@ void HalpInitializeHpet(void) {
KeFatalError(KE_PANIC_INSTALL_MORE_MEMORY);
}

uint64_t Caps = ReadHpetRegister(HPET_CAP_REG);
Period = (Caps >> 32) / 1000000;
MinimumTicks = Hpet->MinimumTicks;
/* We can't/shouldn't be messing with the HPET registers if the counter (and interrupts) are
* enabled. */
uint64_t Reg = ReadHpetRegister(HPET_CFG_REG);
WriteHpetRegister(HPET_CFG_REG, Reg & ~HPET_CFG_MASK);

/* We'll just assume that the firmware left the HPET comparators in a state that would be bad to
* us, and reset all comparators. */
for (uint8_t i = 0; i < Hpet->ComparatorCount + 1; i++) {
Reg = ReadHpetRegister(HPET_TIMER_CAP_REG(i));
WriteHpetRegister(HPET_TIMER_CAP_REG(i), Reg & ~HPET_TIMER_MASK);
}

Period = (ReadHpetRegister(HPET_CAP_REG) >> 32) / 1000000;
VidPrint(
VID_MESSAGE_DEBUG,
"Kernel HAL",
"using HPET as timer tick source (period = %llu ns)\n",
Period);

/* At last we can reenable the main counter (after zeroing it). */
Reg = ReadHpetRegister(HPET_CFG_REG);
WriteHpetRegister(HPET_VAL_REG, 0);
WriteHpetRegister(HPET_CFG_REG, 0x01);
WriteHpetRegister(HPET_CFG_REG, (Reg & ~HPET_CFG_MASK) | HPET_CFG_INT_ENABLE);
}

/*-------------------------------------------------------------------------------------------------
Expand Down
18 changes: 16 additions & 2 deletions src/kernel/include/private/amd64/hpet.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,27 @@
#define HPET_TIMER_CMP_REG(n) (0x108 + ((n) << 5))
#define HPET_TIMER_FSB_REG(n) (0x110 + ((n) << 5))

#define HPET_CFG_INT_ENABLE 0x01
#define HPET_CFG_LEGACY_ENABLE 0x02
#define HPET_CFG_MASK (HPET_CFG_INT_ENABLE | HPET_CFG_LEGACY_ENABLE)

#define HPET_TIMER_INT_ENABLE 0x04
#define HPET_TIMER_32B_ENABLE 0x100
#define HPET_TIMER_FSB_ENABLE 0x4000
#define HPET_TIMER_MASK (HPET_TIMER_INT_ENABLE | HPET_TIMER_32B_ENABLE | HPET_TIMER_FSB_ENABLE)

typedef struct __attribute__((packed)) {
char Unused[36];
uint32_t HardwareId;
uint8_t HardwareId;
uint8_t ComparatorCount : 5;
uint8_t CounterSize : 1;
uint8_t Reserved0 : 1;
uint8_t LegacyReplacement : 1;
uint16_t PciVendorId;
uint8_t AddressSpaceId;
uint8_t RegisterBitWidth;
uint8_t RegisterBitOffset;
uint8_t Reserved;
uint8_t Reserved1;
uint64_t Address;
uint8_t SequenceNumber;
uint16_t MinimumTicks;
Expand Down

0 comments on commit 0e4401f

Please sign in to comment.