From 2ef32dbbc2cae6fc9cd9203571c76f234216a5c8 Mon Sep 17 00:00:00 2001 From: Andrzej Stalke Date: Thu, 9 Nov 2023 14:43:21 +0100 Subject: [PATCH] hal/ia32: Add HPET JIRA: RTOS-530 --- hal/ia32/init.c | 81 +++++++++++++ hal/ia32/init.h | 98 +++++++++++---- hal/ia32/interrupts.c | 2 +- hal/ia32/timer.c | 236 +++++++++++++++++++++++++++--------- include/arch/syspage-ia32.h | 6 +- 5 files changed, 339 insertions(+), 84 deletions(-) diff --git a/hal/ia32/init.c b/hal/ia32/init.c index a0f66b107..b1be13752 100644 --- a/hal/ia32/init.c +++ b/hal/ia32/init.c @@ -138,6 +138,9 @@ static int _hal_acpiInit(hal_config_t *config) if (syspage->hs.fadt != 0) { hal_config.fadt = _hal_configMapObjectBeforeStack(pdir, syspage->hs.fadt, syspage->hs.fadtLength, PGHD_WRITE); } + if (syspage->hs.hpet != 0) { + hal_config.hpet = _hal_configMapObjectBeforeStack(pdir, syspage->hs.hpet, syspage->hs.hpetLength, PGHD_WRITE); + } if (hal_config.madt != NULL) { config->localApicAddr = _hal_configMapDevice(pdir, hal_config.madt->localApicAddr, SIZE_PAGE, PGHD_WRITE); @@ -200,6 +203,83 @@ static inline void _hal_configMemoryInit(void) } +void _hal_gasAllocDevice(const hal_gas_t *gas, hal_gasMapped_t *mgas, size_t size) +{ + addr_t *pdir = (addr_t *)(VADDR_KERNEL + syspage->hs.pdir); + mgas->addressSpaceId = gas->addressSpaceId; + mgas->registerWidth = gas->registerWidth; + mgas->registerOffset = gas->registerOffset; + mgas->accessSize = gas->accessSize; + + switch (gas->addressSpaceId) { + case GAS_ADDRESS_SPACE_ID_MEMORY: + mgas->address = _hal_configMapDevice(pdir, (addr_t)gas->address, size, PGHD_WRITE); + break; + default: + mgas->address = (void *)((u32)gas->address); + break; + } +} + + +int _hal_gasWrite32(hal_gasMapped_t *gas, u32 offset, u32 val) +{ + int ret; + switch (gas->addressSpaceId) { + case GAS_ADDRESS_SPACE_ID_MEMORY: + *(volatile u32 *)(gas->address + offset) = val; + ret = 0; + break; + case GAS_ADDRESS_SPACE_ID_IOPORT: + hal_outl(gas->address + offset, val); + ret = 0; + break; + case GAS_ADDRESS_SPACE_ID_PCI: + /* TODO */ + ret = 1; + break; + case GAS_ADDRESS_SPACE_ID_PCIBAR: + /* TODO */ + ret = 1; + break; + default: + /* Unspecified */ + ret = 1; + break; + } + return ret; +} + + +int _hal_gasRead32(hal_gasMapped_t *gas, u32 offset, u32 *val) +{ + int ret; + switch (gas->addressSpaceId) { + case GAS_ADDRESS_SPACE_ID_MEMORY: + *val = *(volatile u32 *)(gas->address + offset); + ret = 0; + break; + case GAS_ADDRESS_SPACE_ID_IOPORT: + *val = hal_inl(gas->address + offset); + ret = 0; + break; + case GAS_ADDRESS_SPACE_ID_PCI: + /* TODO */ + ret = 1; + break; + case GAS_ADDRESS_SPACE_ID_PCIBAR: + /* TODO */ + ret = 1; + break; + default: + /* Unspecified */ + ret = 1; + break; + } + return ret; +} + + void _hal_configInit(syspage_t *s) { unsigned int ra, rb, rc, rd; @@ -215,6 +295,7 @@ void _hal_configInit(syspage_t *s) hal_config.ptable = NULL; hal_config.madt = NULL; hal_config.fadt = NULL; + hal_config.hpet = NULL; hal_config.devices = MMIO_DEVICES_VIRT_ADDR; hal_config.memMap.count = 0; diff --git a/hal/ia32/init.h b/hal/ia32/init.h index 9046950a3..876c0876b 100644 --- a/hal/ia32/init.h +++ b/hal/ia32/init.h @@ -50,6 +50,42 @@ typedef struct { } __attribute__((packed)) sdt_header_t; +#define GAS_ADDRESS_SPACE_ID_MEMORY 0x0 +#define GAS_ADDRESS_SPACE_ID_IOPORT 0x1 +#define GAS_ADDRESS_SPACE_ID_PCI 0x2 +#define GAS_ADDRESS_SPACE_ID_EMBEDD 0x03 /* EMBEDDED_CONTROLLER */ +#define GAS_ADDRESS_SPACE_ID_SMBUS 0x04 +#define GAS_ADDRESS_SPACE_ID_CMOS 0x05 +#define GAS_ADDRESS_SPACE_ID_PCIBAR 0x06 /* PCI_BAR_TARGET */ +#define GAS_ADDRESS_SPACE_ID_IPMI 0x07 +#define GAS_ADDRESS_SPACE_ID_GPIO 0x08 +#define GAS_ADDRESS_SPACE_ID_GSB 0x09 /* Generic Serial Bus*/ +#define GAS_ADDRESS_SPACE_ID_PCC 0x0A /* Platform Communications Channel */ +#define GAS_ADDRESS_SPACE_ID_PRM 0x0B /* Platform Runtime Mechanism */ + +#define GAS_ACCESS_SIZE_UNDEFINED 0 +#define GAS_ACCESS_SIZE_BYTE 1 +#define GAS_ACCESS_SIZE_WORD 2 +#define GAS_ACCESS_SIZE_DWORD 3 +#define GAS_ACCESS_SIZE_QWORD 4 + +typedef struct { + u8 addressSpaceId; + u8 registerWidth; + u8 registerOffset; + u8 accessSize; + u64 address; +} __attribute__ ((packed)) hal_gas_t; + +typedef struct { + u8 addressSpaceId; + u8 registerWidth; + u8 registerOffset; + u8 accessSize; + void *address; +} hal_gasMapped_t; + + typedef struct { sdt_header_t header; addr_t sdt[]; @@ -80,15 +116,18 @@ typedef struct { addr_t localApicAddr; u32 flags; u8 entries[]; /* It is an array of variable length elements */ -} __attribute__ ((packed)) madt_header_t; +} __attribute__ ((packed)) hal_madtHeader_t; + typedef struct { - u8 addressSpaceId; - u8 registerWidth; - u8 registerOffset; - u8 accessSize; - u64 address; -} __attribute__ ((packed)) generic_address_structure_t; + sdt_header_t header; + u32 eventTimerBlockID; + hal_gas_t baseAddress; + u8 hpetNumber; + u16 minPeriodicClockTick; + u8 pageProtection; +} __attribute__ ((packed)) hal_hpetHeader_t; + typedef struct { sdt_header_t header; @@ -130,25 +169,25 @@ typedef struct { u16 iapcBootArch; /* IAPC_BOOT_ARCH */ u8 reserved2; u32 flags; - generic_address_structure_t resetReg; /* RESET_REG */ - u8 resetValue; /* RESET_VALUE */ - u16 armBootArch; /* ARM_BOOT_ARCH */ + hal_gas_t resetReg; /* RESET_REG */ + u8 resetValue; /* RESET_VALUE */ + u16 armBootArch; /* ARM_BOOT_ARCH */ u8 fadtMinorVersion; - u64 xFirmwareCtrl; /* X_FIRMWARE_CTRL */ - u64 xDsdt; /* X_DSDT */ - generic_address_structure_t xPm1aEvtBlk; /* X_PM1a_EVT_BLK */ - generic_address_structure_t xPm1bEvtBlk; /* X_PM1b_EVT_BLK */ - generic_address_structure_t xPm1aCntBlk; /* X_PM1a_CNT_BLK */ - generic_address_structure_t xPm1bCntBlk; /* X_PM1b_CNT_BLK */ - generic_address_structure_t xPm2CntBlk; /* X_PM2_CNT_BLK */ - generic_address_structure_t xPmTmrBlk; /* X_PM_TMR_BLK */ - generic_address_structure_t xGpe0Blk; /* X_GPE0_BLK */ - generic_address_structure_t xGpe1Blk; /* X_GPE1_BLK */ - generic_address_structure_t sleepControlReg; /* SLEEP_CONTROL_REG */ - generic_address_structure_t sleepStatusReg; /* SLEEP_STATUS_REG */ + u64 xFirmwareCtrl; /* X_FIRMWARE_CTRL */ + u64 xDsdt; /* X_DSDT */ + hal_gas_t xPm1aEvtBlk; /* X_PM1a_EVT_BLK */ + hal_gas_t xPm1bEvtBlk; /* X_PM1b_EVT_BLK */ + hal_gas_t xPm1aCntBlk; /* X_PM1a_CNT_BLK */ + hal_gas_t xPm1bCntBlk; /* X_PM1b_CNT_BLK */ + hal_gas_t xPm2CntBlk; /* X_PM2_CNT_BLK */ + hal_gas_t xPmTmrBlk; /* X_PM_TMR_BLK */ + hal_gas_t xGpe0Blk; /* X_GPE0_BLK */ + hal_gas_t xGpe1Blk; /* X_GPE1_BLK */ + hal_gas_t sleepControlReg; /* SLEEP_CONTROL_REG */ + hal_gas_t sleepStatusReg; /* SLEEP_STATUS_REG */ u64 hypervisorVendorIdentity; -} __attribute__ ((packed)) fadt_header_t; +} __attribute__ ((packed)) hal_fadtHeader_t; typedef struct { @@ -167,8 +206,9 @@ typedef struct { addr_t maxAddr; void *heapStart; addr_t *ptable; - madt_header_t *madt; - fadt_header_t *fadt; + hal_madtHeader_t *madt; + hal_fadtHeader_t *fadt; + hal_hpetHeader_t *hpet; void *devices; /* Address space, where memory mapped devices go */ struct { u32 count; @@ -204,4 +244,12 @@ void _hal_configInit(syspage_t *s); void *_hal_configMapDevice(u32 *pdir, addr_t start, size_t size, int attr); +void _hal_gasAllocDevice(const hal_gas_t *gas, hal_gasMapped_t *mgas, size_t size); + + +int _hal_gasWrite32(hal_gasMapped_t *gas, u32 offset, u32 val); + + +int _hal_gasRead32(hal_gasMapped_t *gas, u32 offset, u32 *val); + #endif diff --git a/hal/ia32/interrupts.c b/hal/ia32/interrupts.c index 9a104f925..e53c848ab 100644 --- a/hal/ia32/interrupts.c +++ b/hal/ia32/interrupts.c @@ -371,7 +371,7 @@ static int _hal_ioapicInit(void) u32 flags; } __attribute__((packed)) *localApic; - madt_header_t *madt = hal_config.madt; + hal_madtHeader_t *madt = hal_config.madt; size_t i; u32 high, low, n; void *ptr; diff --git a/hal/ia32/timer.c b/hal/ia32/timer.c index acb8f876b..e38e3bb63 100644 --- a/hal/ia32/timer.c +++ b/hal/ia32/timer.c @@ -31,29 +31,52 @@ #define PIT_OPERATING_ONE_SHOT (0 << 1) #define PIT_OPERATING_RATE_GEN (2 << 1) -#define LAPIC_TIMER_ONE_SHOT 0 +#define LAPIC_TIMER_ONE_SHOT 0 #define LAPIC_TIMER_DEFAULT_DIVIDER 3 /* 3 means 8 (1 << 3) */ +/* 64 bit registers, access must be aligned + Trying to use exclusive-access mechanisms (ex. lock mov, xchg, etc.) is undefined */ +#define HPET_ID 0x00 +#define HPET_CONFIG 0x10 +#define HPET_IRQ_STATUS 0x20 +#define HPET_COUNTER 0xf0 + +#define HPET_ID_LEGACY_CAPABLE (1u << 15) +#define HPET_LEGACY_TMR1_IRQ 8 +#define HPET_CONFIG_TMR_IRQ_EN (1u << 2) +#define HPET_CONFIG_TMR_PERIODIC (1u << 3) +#define HPET_CONFIG_TMR_CAN_BE_PERIODIC (1u << 4) +#define HPET_CONFIG_TMR_PERIODIC_CAN_SET (1u << 6) +#define HPET_CONFIG_TMR_32BIT_MODE (1u << 8) + +typedef enum { timer_unknown, timer_pit, timer_lapic, timer_hpet } timerType_t; + struct { intr_handler_t handler; spinlock_t sp; u32 intervalUs; - enum { timer_unknown, - timer_pit, - timer_lapic } timerType; + timerType_t schedulerTimerType; + timerType_t timestampTimerType; union { struct { volatile time_t jiffies; } pit; + struct { + volatile u64 cycles; /* How many ticks were there on CPU0 */ + } lapic; + struct { + hal_gasMapped_t addr; + u32 period; + intr_handler_t tmr1; + } hpet; + } timestampTimer; + union { struct { u32 frequency; - struct { - u64 cycles; /* How many ticks were there */ - u32 wait; /* Wait time (in cycles) of this CPU */ - } local[MAX_CPU_COUNT]; + u32 wait[MAX_CPU_COUNT]; /* Wait time (in cycles) of this CPU */ } lapic; - }; + } schedulerTimer; } timer; @@ -75,7 +98,7 @@ static int hal_pitTimerIrqHandler(unsigned int n, cpu_context_t *ctx, void *arg) (void)arg; (void)ctx; - timer.pit.jiffies += timer.intervalUs; + (void)hal_cpuAtomAdd((volatile u32 *)&timer.timestampTimer.pit.jiffies, timer.intervalUs); return 0; } @@ -119,9 +142,10 @@ static void _hal_pitInit(u32 intervalUs) _hal_pitSetTimer(_hal_pitCalculateDivider(intervalUs), PIT_OPERATING_RATE_GEN); - timer.timerType = timer_pit; + timer.timestampTimerType = timer_pit; + timer.schedulerTimerType = timer_pit; - timer.pit.jiffies = 0; + timer.timestampTimer.pit.jiffies = 0; (void)hal_timerRegister(hal_pitTimerIrqHandler, NULL, &timer.handler); } @@ -173,13 +197,13 @@ static inline void _hal_lapicTimerConfigure(u32 mode, u32 mask, u32 vector) static inline u32 _hal_lapicTimerCyc2Us(u64 cycles) { - return (u32)(((cycles << LAPIC_TIMER_DEFAULT_DIVIDER) * 1000) / (u64)timer.lapic.frequency); + return (u32)(((cycles << LAPIC_TIMER_DEFAULT_DIVIDER) * 1000) / (u64)timer.schedulerTimer.lapic.frequency); } static inline u64 _hal_lapicTimerUs2Cyc(u32 us) { - return (((u64)us) * (u64)timer.lapic.frequency) / (1000 << LAPIC_TIMER_DEFAULT_DIVIDER); + return (((u64)us) * (u64)timer.schedulerTimer.lapic.frequency) / (1000 << LAPIC_TIMER_DEFAULT_DIVIDER); } @@ -188,59 +212,150 @@ static int hal_lapicTimerIrqHandler(unsigned int n, cpu_context_t *ctx, void *ar spinlock_ctx_t sc; const unsigned int id = hal_cpuGetID(); hal_spinlockSet(&timer.sp, &sc); - timer.lapic.local[id].cycles += timer.lapic.local[id].wait; - timer.lapic.local[id].wait = _hal_lapicTimerUs2Cyc(timer.intervalUs); - _hal_lapicTimerStart(timer.lapic.local[id].wait); + if ((timer.timestampTimerType == timer_lapic) && (id == 0)) { + timer.timestampTimer.lapic.cycles += timer.schedulerTimer.lapic.wait[id]; + } + timer.schedulerTimer.lapic.wait[id] = _hal_lapicTimerUs2Cyc(timer.intervalUs); + _hal_lapicTimerStart(timer.schedulerTimer.lapic.wait[id]); hal_spinlockClear(&timer.sp, &sc); return 0; } +/* High Precision Event Timers */ + + +static inline u32 _hal_hpetRead(u32 offset) +{ + u32 ret; + (void)_hal_gasRead32(&timer.timestampTimer.hpet.addr, offset, &ret); + return ret; +} + + +static inline void _hal_hpetWrite(u32 offset, u32 val) +{ + (void)_hal_gasWrite32(&timer.timestampTimer.hpet.addr, offset, val); +} + + +/* 0 disables, everything else enables */ +static inline void _hal_hpetEnable(int val) +{ + _hal_hpetWrite(HPET_CONFIG, (_hal_hpetRead(HPET_CONFIG) & 0x3) | (val != 0 ? 1 : 0)); +} + + +static inline u64 _hal_hpetGetCounter(void) +{ + u32 high, low; + do { + high = _hal_hpetRead(HPET_COUNTER + sizeof(u32)); + low = _hal_hpetRead(HPET_COUNTER); + } while (high != _hal_hpetRead(HPET_COUNTER + sizeof(u32))); + return ((u64)high) << 32 | low; +} + + +static inline void _hal_hpetSetCounter(u64 val) +{ + u32 high, low; + low = (u32)val; + high = (u32)(val >> 32); + _hal_hpetWrite(HPET_COUNTER, low); + _hal_hpetWrite(HPET_COUNTER + sizeof(u32), high); +} + + +static time_t _hal_hpetGetUs(void) +{ + u64 ret = _hal_hpetGetCounter(); + ret *= (u64)timer.timestampTimer.hpet.period; + ret /= 1000000000LLU; + return ret; +} + + +static int _hal_hpetInit(void) +{ + if (hal_config.hpet == NULL) { + return -1; + } + _hal_gasAllocDevice(&hal_config.hpet->baseAddress, &timer.timestampTimer.hpet.addr, 0x400); + if (_hal_gasRead32(&timer.timestampTimer.hpet.addr, HPET_ID + sizeof(u32), &timer.timestampTimer.hpet.period) != 0) { + return -1; + } + _hal_hpetSetCounter(0LLU); + timer.timestampTimerType = timer_hpet; + _hal_hpetEnable(1); + return 0; +} + + static int _hal_lapicTimerInit(u32 intervalUs) { - u64 freq; + u64 freq, hpetDelta; + time_t hpetStart, hpetEnd; u32 lapicDelta; u16 pitDelta; - if (hal_isLapicPresent() == 1) { - lapicDelta = 0xffffffffu; - pitDelta = 0xffff; - _hal_lapicTimerConfigure(LAPIC_TIMER_ONE_SHOT, 0, SYSTICK_IRQ + INTERRUPTS_VECTOR_OFFSET); - _hal_lapicTimerSetDivider(LAPIC_TIMER_DEFAULT_DIVIDER); - _hal_pitSetTimer(pitDelta, PIT_OPERATING_ONE_SHOT); - _hal_lapicTimerStart(lapicDelta); - while (pitDelta > 0x0fff) { /* Wait is around 51.500 ms*/ - pitDelta = _hal_pitReadTimer(); - } - lapicDelta -= _hal_lapicTimerGetCounter(); - _hal_lapicTimerStop(); - pitDelta = 0xffff - pitDelta; /* timePassed = pitDelta / PIT_FREQUENCY */ - - freq = ((u64)lapicDelta) * ((u64)PIT_FREQUENCY); - freq <<= LAPIC_TIMER_DEFAULT_DIVIDER; - freq /= (u64)pitDelta; /* Frequency in kHz, with current technology it should fit in 32 bit */ - - timer.timerType = timer_lapic; - timer.intervalUs = intervalUs; - - timer.lapic.frequency = freq; - - (void)hal_timerRegister(hal_lapicTimerIrqHandler, NULL, &timer.handler); - return 0; + if (hal_isLapicPresent() == 0) { + return -1; } - else { - return 1; + _hal_lapicTimerConfigure(LAPIC_TIMER_ONE_SHOT, 0, SYSTICK_IRQ + INTERRUPTS_VECTOR_OFFSET); + _hal_lapicTimerSetDivider(LAPIC_TIMER_DEFAULT_DIVIDER); + lapicDelta = 0xffffffffu; + switch (timer.timestampTimerType) { + case timer_pit: + pitDelta = 0xffff; + _hal_pitSetTimer(pitDelta, PIT_OPERATING_ONE_SHOT); + _hal_lapicTimerStart(lapicDelta); + while (pitDelta > 0x0fff) { /* Wait is around 51.500 ms*/ + pitDelta = _hal_pitReadTimer(); + } + lapicDelta -= _hal_lapicTimerGetCounter(); + _hal_lapicTimerStop(); + pitDelta = 0xffff - pitDelta; /* timePassed = pitDelta / PIT_FREQUENCY */ + + freq = ((u64)lapicDelta) * ((u64)PIT_FREQUENCY); + freq <<= LAPIC_TIMER_DEFAULT_DIVIDER; + freq /= (u64)pitDelta; /* Frequency in kHz, with current technology it should fit in 32 bit */ + timer.timestampTimerType = timer_lapic; + timer.timestampTimer.lapic.cycles = 0; + break; + case timer_hpet: + _hal_pitSetTimer(0, PIT_OPERATING_ONE_SHOT); /* Disable PIT */ + hpetStart = _hal_hpetGetUs(); + _hal_lapicTimerStart(lapicDelta); + do { + hpetEnd = _hal_hpetGetUs(); + } while (hpetEnd - hpetStart < 100000); /* 100ms */ + lapicDelta -= _hal_lapicTimerGetCounter(); + _hal_lapicTimerStop(); + hpetDelta = hpetEnd - hpetStart; + + freq = (((u64)lapicDelta) * 1000) << LAPIC_TIMER_DEFAULT_DIVIDER; + freq /= hpetDelta; + break; + default: + return -1; } + timer.schedulerTimerType = timer_lapic; + timer.intervalUs = intervalUs; + + timer.schedulerTimer.lapic.frequency = freq; + + (void)hal_timerRegister(hal_lapicTimerIrqHandler, NULL, &timer.handler); + return 0; } void hal_timerInitCore(const unsigned int id) { - switch (timer.timerType) { + switch (timer.schedulerTimerType) { case timer_lapic: _hal_lapicTimerConfigure(LAPIC_TIMER_ONE_SHOT, 0, SYSTICK_IRQ + INTERRUPTS_VECTOR_OFFSET); _hal_lapicTimerSetDivider(LAPIC_TIMER_DEFAULT_DIVIDER); - timer.lapic.local[id].cycles = 0; - timer.lapic.local[id].wait = 1; + timer.schedulerTimer.lapic.wait[id] = 1; _hal_lapicTimerStart(1); break; default: @@ -254,12 +369,15 @@ time_t hal_timerGetUs(void) spinlock_ctx_t sc; time_t ret; hal_spinlockSet(&timer.sp, &sc); - switch (timer.timerType) { + switch (timer.timestampTimerType) { case timer_lapic: - ret = _hal_lapicTimerCyc2Us(timer.lapic.local[0].cycles); + ret = _hal_lapicTimerCyc2Us(timer.timestampTimer.lapic.cycles); break; case timer_pit: - ret = timer.pit.jiffies; + ret = timer.timestampTimer.pit.jiffies; + break; + case timer_hpet: + ret = _hal_hpetGetUs(); break; default: ret = -1; @@ -280,12 +398,14 @@ void hal_timerSetWakeup(u32 waitUs) } hal_spinlockSet(&timer.sp, &sc); - switch (timer.timerType) { + switch (timer.schedulerTimerType) { case timer_lapic: id = hal_cpuGetID(); - timer.lapic.local[id].cycles += (timer.lapic.local[id].wait - _hal_lapicTimerGetCounter()); - timer.lapic.local[id].wait = _hal_lapicTimerUs2Cyc(waitUs); - _hal_lapicTimerStart(timer.lapic.local[id].wait); + if ((timer.timestampTimerType == timer_lapic) && (id == 0)) { + timer.timestampTimer.lapic.cycles += (timer.schedulerTimer.lapic.wait[id] - _hal_lapicTimerGetCounter()); + } + timer.schedulerTimer.lapic.wait[id] = _hal_lapicTimerUs2Cyc(waitUs); + _hal_lapicTimerStart(timer.schedulerTimer.lapic.wait[id]); break; default: /* Not supported */ @@ -297,9 +417,13 @@ void hal_timerSetWakeup(u32 waitUs) void _hal_timerInit(u32 intervalUs) { - timer.timerType = timer_unknown; + timer.schedulerTimerType = timer_unknown; + timer.timestampTimerType = timer_pit; + hal_spinlockCreate(&timer.sp, "timer"); + (void)_hal_hpetInit(); + if (_hal_lapicTimerInit(intervalUs) != 0) { _hal_pitInit(intervalUs); } diff --git a/include/arch/syspage-ia32.h b/include/arch/syspage-ia32.h index cc92d0adb..81bade04b 100644 --- a/include/arch/syspage-ia32.h +++ b/include/arch/syspage-ia32.h @@ -39,10 +39,12 @@ typedef struct { unsigned int ebda; unsigned int acpi_version; unsigned int localApicAddr; - unsigned int madt; + unsigned long madt; /* addr_t */ unsigned int madtLength; - unsigned int fadt; + unsigned long fadt; /* addr_t */ unsigned int fadtLength; + unsigned long hpet; /* addr_t */ + unsigned int hpetLength; } __attribute__((packed)) hal_syspage_t;