From a68204d8b8e2bfa4b2516814eefac56f4478bab4 Mon Sep 17 00:00:00 2001 From: "Najumon B.A" Date: Sun, 2 Jul 2023 15:27:24 +0530 Subject: [PATCH] arch: x86: update with new acpica lib interface The old acpi implimentation is replaced with acpica interface and updated x86 arch porting with the new interface. Signed-off-by: Najumon B.A --- arch/x86/Kconfig | 10 +- arch/x86/core/CMakeLists.txt | 2 +- arch/x86/core/intel64/cpu.c | 13 +- arch/x86/core/legacy_bios.c | 53 ++++++ arch/x86/core/pcie.c | 22 +-- arch/x86/core/prep_c.c | 2 +- drivers/interrupt_controller/intc_ioapic.c | 12 +- include/zephyr/acpi/acpi_osal.h | 16 ++ include/zephyr/arch/x86/acpi.h | 204 --------------------- include/zephyr/arch/x86/legacy_bios.h | 12 ++ include/zephyr/arch/x86/x86_acpi_osal.h | 29 +++ 11 files changed, 141 insertions(+), 234 deletions(-) create mode 100644 arch/x86/core/legacy_bios.c create mode 100644 include/zephyr/acpi/acpi_osal.h delete mode 100644 include/zephyr/arch/x86/acpi.h create mode 100644 include/zephyr/arch/x86/legacy_bios.h create mode 100644 include/zephyr/arch/x86/x86_acpi_osal.h diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 5f22707aed9..d7ccfca7ecd 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -227,22 +227,16 @@ choice Reboot via the RST_CNT register, going back to BIOS. endchoice -config X86_ACPI - bool "ACPI (Advanced Configuration and Power Interface) support" - depends on X86_PC_COMPATIBLE - help - Allow retrieval of platform configuration at runtime. - config PCIE_MMIO_CFG bool "Use MMIO PCI configuration space access" - select X86_ACPI + select ACPI help Selects the use of the memory-mapped PCI Express Extended Configuration Space instead of the traditional 0xCF8/0xCFC IO Port registers. config KERNEL_VM_SIZE - default 0x40000000 if X86_ACPI + default 0x40000000 if ACPI config X86_PC_COMPATIBLE bool diff --git a/arch/x86/core/CMakeLists.txt b/arch/x86/core/CMakeLists.txt index 4c4bfa98fe9..9268dc4cf4d 100644 --- a/arch/x86/core/CMakeLists.txt +++ b/arch/x86/core/CMakeLists.txt @@ -15,7 +15,7 @@ zephyr_library_sources_ifdef(CONFIG_PCIE pcie.c) zephyr_library_sources_ifdef(CONFIG_REBOOT_RST_CNT reboot_rst_cnt.c) zephyr_library_sources_ifdef(CONFIG_MULTIBOOT_INFO multiboot.c) zephyr_library_sources_ifdef(CONFIG_X86_EFI efi.c) -zephyr_library_sources_ifdef(CONFIG_X86_ACPI acpi.c) +zephyr_library_sources_ifdef(CONFIG_ACPI legacy_bios.c) zephyr_library_sources_ifdef(CONFIG_X86_MMU x86_mmu.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE userspace.c) zephyr_library_sources_ifdef(CONFIG_ARCH_CACHE cache.c) diff --git a/arch/x86/core/intel64/cpu.c b/arch/x86/core/intel64/cpu.c index 80e9e65b90d..db8b69b0d1e 100644 --- a/arch/x86/core/intel64/cpu.c +++ b/arch/x86/core/intel64/cpu.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include BUILD_ASSERT(CONFIG_MP_MAX_NUM_CPUS <= 4, "Only supports max 4 CPUs"); @@ -142,13 +142,12 @@ void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, uint8_t vector = ((unsigned long) x86_ap_start) >> 12; uint8_t apic_id; - if (IS_ENABLED(CONFIG_X86_ACPI)) { - struct acpi_cpu *cpu; + if (IS_ENABLED(CONFIG_ACPI)) { + struct acpi_madt_local_apic *lapic = acpi_local_apic_get(cpu_num); - cpu = z_acpi_get_cpu(cpu_num); - if (cpu != NULL) { - /* We update the apic_id, x86_ap_start will need it. */ - x86_cpu_loapics[cpu_num] = cpu->apic_id; + if (lapic != NULL) { + /* We update the apic_id, __start will need it. */ + x86_cpu_loapics[cpu_num] = lapic->Id; } } diff --git a/arch/x86/core/legacy_bios.c b/arch/x86/core/legacy_bios.c new file mode 100644 index 00000000000..6a7159a9b1c --- /dev/null +++ b/arch/x86/core/legacy_bios.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#define DATA_SIZE_K(n) (n * 1024u) +#define RSDP_SIGNATURE ((uint64_t)0x2052545020445352) +#define EBDA_ADD (0x040e) +#define BIOS_RODATA_ADD (0xe0000) +#define BIOS_EXT_DATA_LOW (0x80000UL) +#define BIOS_EXT_DATA_HIGH (0x100000UL) + +static uintptr_t bios_search_rsdp_buff(uintptr_t search_phy_add, uint32_t search_length) +{ + uint64_t *search_buff; + + z_phys_map((uint8_t **)&search_buff, search_phy_add, search_length, 0); + if (!search_buff) { + return 0; + } + + for (int i = 0; i < search_length / 8u; i++) { + if (search_buff[i] == RSDP_SIGNATURE) { + z_phys_unmap((uint8_t *)search_buff, search_length); + return (search_phy_add + (i * 8u)); + } + } + z_phys_unmap((uint8_t *)search_buff, search_length); + + return 0; +} + +void *bios_acpi_rsdp_get(void) +{ + uint8_t *bios_ext_data, *zero_page_base; + uintptr_t search_phy_add, rsdp_phy_add; + + z_phys_map(&zero_page_base, 0, DATA_SIZE_K(4u), 0); + bios_ext_data = EBDA_ADD + zero_page_base; + search_phy_add = (uintptr_t)((*(uint16_t *)bios_ext_data) << 4u); + z_phys_unmap(zero_page_base, DATA_SIZE_K(4u)); + + if ((search_phy_add >= BIOS_EXT_DATA_LOW) && (search_phy_add < BIOS_EXT_DATA_HIGH)) { + rsdp_phy_add = bios_search_rsdp_buff(search_phy_add, DATA_SIZE_K(1u)); + if (rsdp_phy_add) { + return (void *)rsdp_phy_add; + } + } + return (void *)bios_search_rsdp_buff(BIOS_RODATA_ADD, DATA_SIZE_K(128u)); +} diff --git a/arch/x86/core/pcie.c b/arch/x86/core/pcie.c index 47b78f990c1..5c1e83725bb 100644 --- a/arch/x86/core/pcie.c +++ b/arch/x86/core/pcie.c @@ -8,8 +8,8 @@ #include #include -#ifdef CONFIG_X86_ACPI -#include +#ifdef CONFIG_ACPI +#include #endif #ifdef CONFIG_PCIE_MSI @@ -35,26 +35,26 @@ static bool do_pcie_mmio_cfg; static void pcie_mm_init(void) { -#ifdef CONFIG_X86_ACPI - struct acpi_mcfg *m = z_acpi_find_table(ACPI_MCFG_SIGNATURE); +#ifdef CONFIG_ACPI + struct acpi_mcfg *m = acpi_table_get("MCFG", 0); if (m != NULL) { - int n = (m->sdt.length - sizeof(*m)) / sizeof(m->pci_segs[0]); + int n = (m->header.Length - sizeof(*m)) / sizeof(m->pci_segs[0]); for (int i = 0; i < n && i < MAX_PCI_BUS_SEGMENTS; i++) { size_t size; uintptr_t phys_addr; - bus_segs[i].start_bus = m->pci_segs[i].start_bus; - bus_segs[i].n_buses = 1 + m->pci_segs[i].end_bus - - m->pci_segs[i].start_bus; + bus_segs[i].start_bus = m->pci_segs[i].StartBusNumber; + bus_segs[i].n_buses = + 1 + m->pci_segs[i].EndBusNumber - m->pci_segs[i].StartBusNumber; - phys_addr = m->pci_segs[i].base_addr; + phys_addr = m->pci_segs[i].Address; /* 32 devices & 8 functions per bus, 4k per device */ size = bus_segs[i].n_buses * (32 * 8 * 4096); - device_map((mm_reg_t *)&bus_segs[i].mmio, phys_addr, - size, K_MEM_CACHE_NONE); + device_map((mm_reg_t *)&bus_segs[i].mmio, phys_addr, size, + K_MEM_CACHE_NONE); } do_pcie_mmio_cfg = true; diff --git a/arch/x86/core/prep_c.c b/arch/x86/core/prep_c.c index 70c3e844756..ffb4d6b019a 100644 --- a/arch/x86/core/prep_c.c +++ b/arch/x86/core/prep_c.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/interrupt_controller/intc_ioapic.c b/drivers/interrupt_controller/intc_ioapic.c index f889d0d2295..424f1d5332c 100644 --- a/drivers/interrupt_controller/intc_ioapic.c +++ b/drivers/interrupt_controller/intc_ioapic.c @@ -120,7 +120,7 @@ static void IoApicRedUpdateLo(unsigned int irq, uint32_t value, !defined(CONFIG_INTEL_VTD_ICTL_XAPIC_PASSTHROUGH) #include -#include +#include static const struct device *const vtd = DEVICE_DT_GET_OR_NULL(DT_INST(0, intel_vt_d)); @@ -129,11 +129,19 @@ static uint16_t ioapic_id; static bool get_vtd(void) { + union acpi_dmar_id *dmar_id; + int inst_cnt; + if (vtd != NULL) { return true; } - ioapic_id = z_acpi_get_dev_id_from_dmar(ACPI_DRHD_DEV_SCOPE_IOAPIC); + /* Assume only one PCH in system (say client platform). */ + if (!acpi_drhd_get(ACPI_DMAR_SCOPE_TYPE_IOAPIC, NULL, &dmar_id, &inst_cnt, 1u)) { + return false; + } + + ioapic_id = dmar_id->raw; return vtd == NULL ? false : true; } diff --git a/include/zephyr/acpi/acpi_osal.h b/include/zephyr/acpi/acpi_osal.h new file mode 100644 index 00000000000..92e0180bc45 --- /dev/null +++ b/include/zephyr/acpi/acpi_osal.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_ARCH_X86_INCLUDE_ACPI_OSAL_H_ +#define ZEPHYR_ARCH_X86_INCLUDE_ACPI_OSAL_H_ + +#if defined(CONFIG_X86 || CONFIG_X86_64) +#include "zephyr/acpi/x86_acpi_osal.h" +#else +#error "Currently only x86 Architecture support ACPI !!" +#endif + +#endif /* ZEPHYR_ARCH_X86_INCLUDE_ACPI_OSAL_H_ */ diff --git a/include/zephyr/arch/x86/acpi.h b/include/zephyr/arch/x86/acpi.h deleted file mode 100644 index df4a5dcc089..00000000000 --- a/include/zephyr/arch/x86/acpi.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2020 Intel Corporation - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_ARCH_X86_ACPI_H -#define ZEPHYR_INCLUDE_ARCH_X86_ACPI_H - -#ifndef _ASMLANGUAGE - -#define ACPI_RSDP_SIGNATURE 0x2052545020445352 /* == "RSD PTR " */ - -/* Root System Description Pointer */ -struct acpi_rsdp { - char signature[8]; - uint8_t chksum; - char oem_id[6]; - uint8_t revision; - uint32_t rsdt_ptr; - uint32_t length; - uint64_t xsdt_ptr; - uint8_t ext_chksum; - uint8_t _reserved[3]; -} __packed; - -/* Standard table header */ -struct acpi_sdt { - uint32_t signature; - uint32_t length; - uint8_t revision; - uint8_t chksum; - char oem_id[6]; - char oem_table_id[8]; - uint32_t oem_revision; - uint32_t creator_id; - uint32_t creator_revision; -} __packed; - -/* Root System Description Table */ -struct acpi_rsdt { - struct acpi_sdt sdt; - uint32_t table_ptrs[]; -} __packed; - -/* eXtended System Descriptor Table */ -struct acpi_xsdt { - struct acpi_sdt sdt; - uint64_t table_ptrs[]; -} __packed; - -/* MCFG table storing MMIO addresses for PCI configuration space */ - -#define ACPI_MCFG_SIGNATURE 0x4746434d /* 'MCFG' */ - -struct acpi_mcfg { - struct acpi_sdt sdt; - uint64_t _reserved; - struct { - uint64_t base_addr; - uint16_t seg_group_num; - uint8_t start_bus; - uint8_t end_bus; - } pci_segs[]; -} __packed; - -/* MADT table storing IO-APIC and multiprocessor configuration */ - -#define ACPI_MADT_SIGNATURE 0x43495041 /* 'APIC' */ - -struct acpi_madt_entry { - uint8_t type; /* See ACPI_MADT_ENTRY_* below */ - uint8_t length; -} __packed; - -#define ACPI_MADT_ENTRY_CPU 0 - -struct acpi_madt { - struct acpi_sdt sdt; - uint32_t loapic; /* local APIC MMIO address */ - uint32_t flags; /* see ACPI_MADT_FLAGS_* below */ - struct acpi_madt_entry entries[]; -} __packed; - -#define ACPI_MADT_FLAGS_PICS 0x01 /* legacy 8259s installed */ - -struct acpi_cpu { - struct acpi_madt_entry entry; - uint8_t acpi_id; - uint8_t apic_id; /* local APIC ID */ - uint8_t flags; /* see ACPI_CPU_FLAGS_* below */ -} __packed; - -#define ACPI_CPU_FLAGS_ENABLED 0x01 - -/* Generic DMA Remapping entry structure part */ -struct acpi_dmar_entry { - uint16_t type; /* See ACPI_DMAR_TYPE_* below */ - uint16_t length; -} __packed; - -#define ACPI_DMAR_TYPE_DRHD 0 /* DMA Remapping Hardware Unit Definition */ -#define ACPI_DMAR_TYPE_RMRR 1 /* Do not care atm (legacy usage) */ -#define ACPI_DMAR_TYPE_ATSR 2 /* Do not care atm (PCIE ATS support) */ -#define ACPI_DMAR_TYPE_RHSA 3 /* Do not care atm (NUMA specific ) */ -#define ACPI_DMAR_TYPE_ANDD 4 /* Do not care atm (ACPI DSDT related) */ -#define ACPI_DMAR_TYPE_SACT 5 /* Do not care atm */ - -/* PCI Device/Function Pair (forming the BDF, with start_bus_num below) */ -struct acpi_dmar_dev_path { - uint8_t device; - uint8_t function; -} __packed; - -#define ACPI_DMAR_DEV_PATH_SIZE 2 - -/* DMA Remapping Device Scope */ -struct acpi_dmar_dev_scope { - uint8_t type; /* See ACPI_DRHD_DEV_SCOPE_* below */ - uint8_t length; /* 6 + X where X is Path attribute size */ - uint16_t _reserved; - uint8_t enumeration_id; - uint8_t start_bus_num; /* PCI bus, forming BDF with each Path below */ - struct acpi_dmar_dev_path path[]; /* One is at least always found */ -} __packed; - -#define ACPI_DMAR_DEV_SCOPE_MIN_SIZE 6 - -#define ACPI_DRHD_DEV_SCOPE_PCI_EPD 0x01 -#define ACPI_DRHD_DEV_SCOPE_PCI_SUB_H 0x02 -#define ACPI_DRHD_DEV_SCOPE_IOAPIC 0x03 -#define ACPI_DRHD_DEV_SCOPE_MSI_CAP_HPET 0x04 -#define ACPI_DRHD_DEV_SCOPE_NAMESPACE_DEV 0x05 - -struct acpi_drhd { - struct acpi_dmar_entry entry; - uint8_t flags; /* See ACPI_DRHD_FLAG_* below */ - uint8_t _reserved; - uint16_t segment_num; /* Associated PCI segment */ - uint64_t base_address; /* Base address of the remapping hw */ - struct acpi_dmar_dev_scope device_scope[]; -} __packed; - -#define ACPI_DRHD_MIN_SIZE 16 - -#define ACPI_DRHD_FLAG_INCLUDE_PCI_ALL BIT(0) - -#define ACPI_DMAR_SIGNATURE 0x52414D44 /* 'DMAR' */ - -#define ACPI_DMAR_FLAG_INTR_REMAP BIT(0) -#define ACPI_DMAR_FLAG_X2APIC_OPT_OUT BIT(1) -#define ACPI_DMAR_FLAG_DMA_CTRL_PLATFORM_OPT_IN BIT(2) - -/* DMA Remapping reporting structure */ -struct acpi_dmar { - struct acpi_sdt sdt; - uint8_t host_addr_width; - uint8_t flags; - uint8_t _reserved[10]; - struct acpi_dmar_entry remap_entries[]; -} __packed; - -union acpi_dmar_id { - struct { - uint16_t function : 3; - uint16_t device : 5; - uint16_t bus : 8; - } bits; - - uint16_t raw; -}; - -#if defined(CONFIG_X86_ACPI) - -void *z_acpi_find_table(uint32_t signature); - -struct acpi_cpu *z_acpi_get_cpu(int n); - -struct acpi_dmar *z_acpi_find_dmar(void); - -struct acpi_drhd *z_acpi_find_drhds(int *n); - -struct acpi_dmar_dev_scope *z_acpi_get_drhd_dev_scopes(struct acpi_drhd *drhd, - int *n); - -struct acpi_dmar_dev_path * -z_acpi_get_dev_scope_paths(struct acpi_dmar_dev_scope *dev_scope, int *n); - -uint16_t z_acpi_get_dev_id_from_dmar(uint8_t dev_scope_type); - -#else /* CONFIG_X86_ACPI */ - -#define z_acpi_find_table(...) NULL -#define z_acpi_get_cpu(...) NULL -#define z_acpi_find_dmar(...) NULL -#define z_acpi_find_drhds(...) NULL -#define z_acpi_get_drhd_dev_scopes(...) NULL -#define z_acpi_get_dev_scope_paths(...) NULL -#define z_acpi_get_dev_id_from_dmar(...) USHRT_MAX - -#endif /* CONFIG_X86_ACPI */ - -#endif /* _ASMLANGUAGE */ - -#endif /* ZEPHYR_INCLUDE_ARCH_X86_ACPI_H */ diff --git a/include/zephyr/arch/x86/legacy_bios.h b/include/zephyr/arch/x86/legacy_bios.h new file mode 100644 index 00000000000..a5abd67d8c5 --- /dev/null +++ b/include/zephyr/arch/x86/legacy_bios.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_ARCH_X86_INCLUDE_LEGACY_BIOS_H_ +#define ZEPHYR_ARCH_X86_INCLUDE_LEGACY_BIOS_H_ + +void *bios_acpi_rsdp_get(void); + +#endif /* ZEPHYR_ARCH_X86_INCLUDE_LEGACY_BIOS_H_ */ diff --git a/include/zephyr/arch/x86/x86_acpi_osal.h b/include/zephyr/arch/x86/x86_acpi_osal.h new file mode 100644 index 00000000000..8f742b024b7 --- /dev/null +++ b/include/zephyr/arch/x86/x86_acpi_osal.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +#ifndef ZEPHYR_ARCH_X86_INCLUDE_X86_ACPI_H_ +#define ZEPHYR_ARCH_X86_INCLUDE_X86_ACPI_H_ + +#if defined(CONFIG_X86_EFI) +static inline void *acpi_rsdp_get(void) +{ + void *rsdp = efi_get_acpi_rsdp(); + + if (!rsdp) { + rsdp = bios_acpi_rsdp_get(); + } + + return rsdp; +} +#else +static inline void *acpi_rsdp_get(void) +{ + return bios_acpi_rsdp_get(); +} +#endif /* CONFIG_X86_EFI */ +#endif /* ZEPHYR_ARCH_X86_INCLUDE_X86_ACPI_H_ */