mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-05-01 13:14:02 +00:00
On some platforms CPUID.0x15:ECX is zero and CPUID.0x16 can only return the TSC frequency in MHZ which is not accurate. For example the TSC frequency obtained by CPUID.0x16 is 2300 MHZ and the TSC frequency calibrated by HPET is 2303.998 MHZ which is much closer to the actual TSC frequency 2304.000 MHZ. This patch adds the support of using HPET to calibrate TSC when HPET is available and CPUID.0x15:ECX is zero. v3->v4: - move calc_tsc_by_hpet into hpet_calibrate_tsc v2->v3: - remove the NULL check in hpet_init - remove ""& 0xFFFFFFFFU" in tsc_read_hpet - add comment for the counter wrap in the low 32 bits in calc_tsc_by_hpet - use a dedicated function for hpet_calibrate_tsc v1->v2: - change native_calibrate_tsc_cpuid_0x15/0x16 to native_calculate_tsc_cpuid_0x15/0x16 - move hpet_init to BSP init - encapsulate both HPET and PIT calibration to one function - revise the commit message with an example" Tracked-On: #7876 Signed-off-by: Jian Jun Chen <jian.jun.chen@intel.com> Reviewed-by: Fei Li <fei1.li@intel.com>
268 lines
8.4 KiB
C
268 lines
8.4 KiB
C
/*
|
|
* Copyright (C) 2018-2022 Intel Corporation.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#ifndef ACPI_H
|
|
#define ACPI_H
|
|
|
|
#include <board_info.h>
|
|
|
|
#define ACPI_RSDP_CHECKSUM_LENGTH 20U
|
|
#define ACPI_RSDP_XCHECKSUM_LENGTH 36U
|
|
|
|
#define ACPI_NAME_SIZE 4U
|
|
#define ACPI_OEM_ID_SIZE 6U
|
|
#define ACPI_OEM_TABLE_ID_SIZE 8U
|
|
|
|
#define ACPI_MADT_TYPE_LOCAL_APIC 0U
|
|
#define ACPI_MADT_TYPE_IOAPIC 1U
|
|
#define ACPI_MADT_ENABLED 1U
|
|
#define ACPI_MADT_TYPE_LOCAL_APIC_NMI 4U
|
|
|
|
#define ACPI_DMAR_TYPE_HARDWARE_UNIT 0U
|
|
#define ACPI_DMAR_TYPE_RESERVED_MEMORY 1U
|
|
#define ACPI_DMAR_TYPE_ROOT_ATS 2U
|
|
#define ACPI_DMAR_TYPE_HARDWARE_AFFINITY 3U
|
|
#define ACPI_DMAR_TYPE_NAMESPACE 4U
|
|
#define ACPI_DMAR_TYPE_RESERVED 5U
|
|
|
|
/* FACP field offsets */
|
|
#define OFFSET_FACS_ADDR 36U
|
|
#define OFFSET_RESET_REGISTER 116U
|
|
#define OFFSET_RESET_VALUE 128U
|
|
#define OFFSET_FACS_X_ADDR 132U
|
|
#define OFFSET_PM1A_EVT 148U
|
|
#define OFFSET_PM1A_CNT 172U
|
|
|
|
/* FACS field offsets */
|
|
#define OFFSET_FACS_SIGNATURE 0U
|
|
#define OFFSET_FACS_LENGTH 4U
|
|
#define OFFSET_WAKE_VECTOR_32 12U
|
|
#define OFFSET_WAKE_VECTOR_64 24U
|
|
|
|
/* MCFG field offsets */
|
|
#define OFFSET_MCFG_LENGTH 4U
|
|
#define OFFSET_MCFG_ENTRY0 44U
|
|
#define OFFSET_MCFG_ENTRY0_BASE 44U
|
|
#define OFFSET_MCFG_ENTRY1 60U
|
|
|
|
#define ACPI_SIG_FADT "FACP" /* Fixed ACPI Description Table */
|
|
#define ACPI_SIG_FACS 0x53434146U /* "FACS" */
|
|
#define ACPI_SIG_RSDP "RSD PTR " /* Root System Description Ptr */
|
|
#define ACPI_SIG_XSDT "XSDT" /* Extended System Description Table */
|
|
#define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */
|
|
#define ACPI_SIG_DMAR "DMAR"
|
|
#define ACPI_SIG_MCFG "MCFG" /* Memory Mapped Configuration table */
|
|
#define ACPI_SIG_DSDT "DSDT" /* Differentiated System Description Table */
|
|
#define ACPI_SIG_TPM2 "TPM2" /* Trusted Platform Module hardware interface table */
|
|
#define ACPI_SIG_RTCT "PTCT" /* Platform Tuning Configuration Table (Real-Time Configuration Table) */
|
|
#define ACPI_SIG_RTCT_V2 "RTCT" /* Platform Tuning Configuration Table (Real-Time Configuration Table) V2 */
|
|
#define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */
|
|
|
|
struct packed_gas {
|
|
uint8_t space_id;
|
|
uint8_t bit_width;
|
|
uint8_t bit_offset;
|
|
uint8_t access_size;
|
|
uint64_t address;
|
|
} __packed;
|
|
|
|
struct acpi_table_header {
|
|
/* ASCII table signature */
|
|
char signature[4];
|
|
/* Length of table in bytes, including this header */
|
|
uint32_t length;
|
|
/* ACPI Specification minor version number */
|
|
uint8_t revision;
|
|
/* To make sum of entire table == 0 */
|
|
uint8_t checksum;
|
|
/* ASCII OEM identification */
|
|
char oem_id[6];
|
|
/* ASCII OEM table identification */
|
|
char oem_table_id[8];
|
|
/* OEM revision number */
|
|
uint32_t oem_revision;
|
|
/* ASCII ASL compiler vendor ID */
|
|
char asl_compiler_id[4];
|
|
/* ASL compiler version */
|
|
uint32_t asl_compiler_revision;
|
|
} __packed;
|
|
|
|
struct acpi_table_rsdp {
|
|
/* ACPI signature, contains "RSD PTR " */
|
|
char signature[8];
|
|
/* ACPI 1.0 checksum */
|
|
uint8_t checksum;
|
|
/* OEM identification */
|
|
char oem_id[ACPI_OEM_ID_SIZE];
|
|
/* Must be (0) for ACPI 1.0 or (2) for ACPI 2.0+ */
|
|
uint8_t revision;
|
|
/* 32-bit physical address of the RSDT */
|
|
uint32_t rsdt_physical_address;
|
|
/* Table length in bytes, including header (ACPI 2.0+) */
|
|
uint32_t length;
|
|
/* 64-bit physical address of the XSDT (ACPI 2.0+) */
|
|
uint64_t xsdt_physical_address;
|
|
/* Checksum of entire table (ACPI 2.0+) */
|
|
uint8_t extended_checksum;
|
|
/* Reserved, must be zero */
|
|
uint8_t reserved[3];
|
|
} __packed;
|
|
|
|
struct acpi_table_rsdt {
|
|
/* Common ACPI table header */
|
|
struct acpi_table_header header;
|
|
/* Array of pointers to ACPI tables */
|
|
uint32_t table_offset_entry[1];
|
|
} __packed;
|
|
|
|
struct acpi_table_xsdt {
|
|
/* Common ACPI table header */
|
|
struct acpi_table_header header;
|
|
/* Array of pointers to ACPI tables */
|
|
uint64_t table_offset_entry[1];
|
|
} __packed;
|
|
|
|
struct acpi_table_fadt {
|
|
struct acpi_table_header header;/* Common ACPI table header */
|
|
uint32_t facs; /* 32-bit physical address of FACS */
|
|
uint32_t dsdt; /* 32-bit physical address of DSDT */
|
|
uint8_t unused0[12]; /* ACRN doesn't use these fields */
|
|
uint32_t pm1a_event_block; /* 32-bit port address of Power Mgt 1a Event Reg Blk */
|
|
uint32_t pm1b_event_block; /* 32-bit port address of Power Mgt 1b Event Reg Blk */
|
|
uint32_t pm1a_control_block; /* 32-bit port address of Power Mgt 1a Control Reg Blk */
|
|
uint32_t pm1b_control_block; /* 32-bit port address of Power Mgt 1b Control Reg Blk */
|
|
uint8_t unused1[16]; /* ACRN doesn't use these fields */
|
|
uint8_t pm1_event_length; /* Byte Length of ports at pm1x_event_block */
|
|
uint8_t pm1_control_length; /* Byte Length of ports at pm1x_control_block */
|
|
uint8_t unused2[22]; /* ACRN doesn't use these fields */
|
|
uint32_t flags; /* Miscellaneous flag bits (see below for individual flags) */
|
|
uint8_t unused3[128]; /* ACRN doesn't use these fields */
|
|
} __packed;
|
|
|
|
struct acpi_table_mcfg {
|
|
struct acpi_table_header header; /* Common ACPI table header */
|
|
uint8_t reserved[8];
|
|
} __packed;
|
|
|
|
struct acpi_mcfg_allocation {
|
|
uint64_t address; /* Base address, processor-relative */
|
|
uint16_t pci_segment; /* PCI segment group number */
|
|
uint8_t start_bus_number; /* Starting PCI Bus number */
|
|
uint8_t end_bus_number; /* Final PCI Bus number */
|
|
uint32_t reserved;
|
|
} __packed;
|
|
|
|
struct acpi_table_madt {
|
|
/* Common ACPI table header */
|
|
struct acpi_table_header header;
|
|
/* Physical address of local APIC */
|
|
uint32_t address;
|
|
uint32_t flags;
|
|
} __packed;
|
|
|
|
struct acpi_subtable_header {
|
|
uint8_t type;
|
|
uint8_t length;
|
|
} __packed;
|
|
|
|
struct acpi_madt_local_apic {
|
|
struct acpi_subtable_header header;
|
|
/* ACPI processor id */
|
|
uint8_t processor_id;
|
|
/* Processor's local APIC id */
|
|
uint8_t id;
|
|
uint32_t lapic_flags;
|
|
} __packed;
|
|
|
|
struct acpi_madt_local_apic_nmi {
|
|
struct acpi_subtable_header header;
|
|
uint8_t processor_id;
|
|
uint16_t flags;
|
|
uint8_t lint;
|
|
} __packed;
|
|
|
|
struct acpi_madt_ioapic {
|
|
struct acpi_subtable_header header;
|
|
/* IOAPIC id */
|
|
uint8_t id;
|
|
uint8_t rsvd;
|
|
uint32_t addr;
|
|
uint32_t gsi_base;
|
|
} __packed;
|
|
|
|
struct acpi_table_dmar {
|
|
/* Common ACPI table header */
|
|
struct acpi_table_header header;
|
|
/* Host address Width */
|
|
uint8_t width;
|
|
uint8_t flags;
|
|
uint8_t reserved[10];
|
|
} __packed;
|
|
|
|
/* DMAR subtable header */
|
|
struct acpi_dmar_header {
|
|
uint16_t type;
|
|
uint16_t length;
|
|
} __packed;
|
|
|
|
struct acpi_dmar_hardware_unit {
|
|
struct acpi_dmar_header header;
|
|
uint8_t flags;
|
|
uint8_t reserved;
|
|
uint16_t segment;
|
|
/* register base address */
|
|
uint64_t address;
|
|
} __packed;
|
|
|
|
struct acpi_dmar_pci_path {
|
|
uint8_t device;
|
|
uint8_t function;
|
|
} __packed;
|
|
|
|
struct acpi_dmar_device_scope {
|
|
uint8_t entry_type;
|
|
uint8_t length;
|
|
uint16_t reserved;
|
|
uint8_t enumeration_id;
|
|
uint8_t bus;
|
|
} __packed;
|
|
|
|
struct acpi_table_tpm2 {
|
|
struct acpi_table_header header;
|
|
uint16_t platform_class;
|
|
uint16_t reserved;
|
|
uint64_t control_address;
|
|
uint32_t start_method;
|
|
#ifdef CONFIG_SECURITY_VM_FIXUP
|
|
uint8_t start_method_spec_para[12];
|
|
uint32_t laml;
|
|
uint64_t lasa;
|
|
#endif
|
|
} __packed;
|
|
|
|
struct acpi_table_hpet {
|
|
struct acpi_table_header header;
|
|
uint32_t id;
|
|
struct packed_gas address;
|
|
uint8_t sequence;
|
|
uint16_t minimum_tick;
|
|
uint8_t flags;
|
|
} __packed;
|
|
|
|
void init_acpi(void);
|
|
void *get_acpi_tbl(const char *signature);
|
|
|
|
struct ioapic_info;
|
|
uint16_t parse_madt(uint32_t lapic_id_array[MAX_PCPU_NUM]);
|
|
uint8_t parse_madt_ioapic(struct ioapic_info *ioapic_id_array);
|
|
void *parse_hpet(void);
|
|
|
|
#ifdef CONFIG_ACPI_PARSE_ENABLED
|
|
int32_t acpi_fixup(void);
|
|
#endif
|
|
|
|
#endif /* !ACPI_H */
|