load hpet info for HPET ACPI table from qemu
PATCH 1/1 load hpet info for HPET ACPI table from qemu
Load hpet info for HPET ACPI table from qemu instead of using hardcoded values. Use hardcoded values anyway if old qemu is detected.
Signed-off-by Gleb Natapov <[email protected]>
src/acpi.c +26 -7
@@ -469,7 +469,7 @@ build_ssdt(void)#define HPET_SIGNATURE 0x54455048 //HPETstatic void * -build_hpet (void ) +build_hpet (struct hpet_fw_entry *e,u8 id) {struct acpi_20_hpet *hpet =malloc_high (sizeof (*hpet));if (!hpet) {
@@ -478,11 +478,11 @@ build_hpet(void) }memset (hpet,0 ,sizeof (*hpet)); -/* Note timer_block_id value must be kept in sync with value advertised by -* emulated hpet -*/ - hpet->timer_block_id =cpu_to_le32 (0x8086a201 ); - hpet->addr.address =cpu_to_le32 (ACPI_HPET_ADDRESS ); + hpet->timer_block_id =cpu_to_le32 (e->event_timer_block_id); + hpet->addr.address =cpu_to_le32 (e->address); + hpet->min_tick =cpu_to_le32 (e->min_tick); + hpet->hpet_number = id; + hpet->page_protect = e->page_prot;build_header ((void *)hpet,HPET_SIGNATURE ,sizeof (*hpet),1 );return hpet;
@@ -637,9 +637,28 @@ acpi_bios_init(void)ACPI_INIT_TABLE (build_fadt (bdf));ACPI_INIT_TABLE (build_ssdt ());ACPI_INIT_TABLE (build_madt ()); -ACPI_INIT_TABLE (build_hpet ());ACPI_INIT_TABLE (build_srat ()); +u8 hpet_id =0 ; +u32 c =qemu_cfg_hpet_entries (); +struct hpet_fw_entry e; + +if (c == ~0 ) { +/* qemu do not provide hpet description */ + e.event_timer_block_id =0x8086a201 ; + e.address =ACPI_HPET_ADDRESS ; + e.min_tick =0 ; + c =1 ; + }else if (c !=0 ) +qemu_cfg_hpet_load_next (&e); + +while (c--) { +ACPI_INIT_TABLE (build_hpet (&e, hpet_id++)); +if (c) +qemu_cfg_hpet_load_next (&e); + } + +u16 i, external_tables =qemu_cfg_acpi_additional_tables ();for (i =0 ; i < external_tables; i++) {
src/paravirt.c +20 -0
@@ -149,6 +149,26 @@ void* qemu_cfg_e820_load_next(void *addr)return addr; } +u32 qemu_cfg_hpet_entries (void ) +{ +u8 cnt; + +if (!qemu_cfg_present) +return 0 ; + +/* read valid flags */ +qemu_cfg_read_entry (&cnt,QEMU_CFG_HPET ,sizeof (cnt)); +if (!cnt) +return ~0 ; +qemu_cfg_read (&cnt,sizeof (cnt)); +return cnt; +} + +void qemu_cfg_hpet_load_next (struct hpet_fw_entry *e) +{ +qemu_cfg_read ((u8 *)e,sizeof (*e)); +} +struct smbios_header {u16 length;u8 type;
src/paravirt.h +11 -0
@@ -37,6 +37,7 @@ static inline int kvm_para_available(void)#define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1)#define QEMU_CFG_IRQ0_OVERRIDE (QEMU_CFG_ARCH_LOCAL + 2)#define QEMU_CFG_E820_TABLE (QEMU_CFG_ARCH_LOCAL + 3) +#define QEMU_CFG_HPET (QEMU_CFG_ARCH_LOCAL + 4)extern int qemu_cfg_present;
@@ -68,10 +69,20 @@ struct e820_reservation { u32 type; }; +struct hpet_fw_entry +{ +u32 event_timer_block_id; +u64 address; +u16 min_tick; +u8 page_prot; +} __attribute__ ((packed)); +u16 qemu_cfg_first_file (QemuCfgFile *entry);u16 qemu_cfg_next_file (QemuCfgFile *entry);u32 qemu_cfg_read_file (QemuCfgFile *entry,void *dst,u32 maxlen);u32 qemu_cfg_e820_entries (void );void *qemu_cfg_e820_load_next (void *addr); +u32 qemu_cfg_hpet_entries (void ); +void qemu_cfg_hpet_load_next (struct hpet_fw_entry *e);#endif
--
Gleb.