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 <najumon.ba@intel.com>
This commit is contained in:
Najumon B.A 2023-07-02 15:27:24 +05:30 committed by Carles Cufí
commit a68204d8b8
11 changed files with 141 additions and 234 deletions

View file

@ -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

View file

@ -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)

View file

@ -11,7 +11,7 @@
#include <zephyr/arch/x86/multiboot.h>
#include <x86_mmu.h>
#include <zephyr/drivers/interrupt_controller/loapic.h>
#include <zephyr/arch/x86/acpi.h>
#include <zephyr/acpi/acpi.h>
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;
}
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2023 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#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));
}

View file

@ -8,8 +8,8 @@
#include <zephyr/sys/device_mmio.h>
#include <zephyr/drivers/pcie/pcie.h>
#ifdef CONFIG_X86_ACPI
#include <zephyr/arch/x86/acpi.h>
#ifdef CONFIG_ACPI
#include <zephyr/acpi/acpi.h>
#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;

View file

@ -6,7 +6,7 @@
#include <zephyr/kernel.h>
#include <kernel_internal.h>
#include <zephyr/arch/x86/acpi.h>
#include <zephyr/acpi/acpi.h>
#include <zephyr/arch/x86/multiboot.h>
#include <zephyr/arch/x86/efi.h>
#include <x86_mmu.h>

View file

@ -120,7 +120,7 @@ static void IoApicRedUpdateLo(unsigned int irq, uint32_t value,
!defined(CONFIG_INTEL_VTD_ICTL_XAPIC_PASSTHROUGH)
#include <zephyr/drivers/interrupt_controller/intel_vtd.h>
#include <zephyr/arch/x86/acpi.h>
#include <zephyr/acpi/acpi.h>
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;
}

View file

@ -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_ */

View file

@ -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 */

View file

@ -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_ */

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2023 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/arch/x86/efi.h>
#include <zephyr/arch/x86/legacy_bios.h>
#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_ */