diff --git a/devicemodel/Makefile b/devicemodel/Makefile index 3da842612..1920ccc19 100644 --- a/devicemodel/Makefile +++ b/devicemodel/Makefile @@ -108,6 +108,7 @@ SRCS += hw/platform/pty_vuart.c SRCS += hw/platform/acpi/acpi.c SRCS += hw/platform/acpi/rtct.c SRCS += hw/platform/acpi/acpi_pm.c +SRCS += hw/platform/acpi/acpi_parser.c SRCS += hw/platform/rpmb/rpmb_sim.c SRCS += hw/platform/rpmb/rpmb_backend.c SRCS += hw/platform/rpmb/att_keybox.c diff --git a/devicemodel/core/main.c b/devicemodel/core/main.c index f88cad144..3f3fbcb86 100644 --- a/devicemodel/core/main.c +++ b/devicemodel/core/main.c @@ -1012,6 +1012,11 @@ main(int argc, char *argv[]) exit(1); } + if (parse_madt()) { + pr_err("parse madt failed\n"); + exit(1); + } + if (!init_hugetlb()) { pr_err("init_hugetlb failed\n"); exit(1); diff --git a/devicemodel/hw/platform/acpi/acpi.c b/devicemodel/hw/platform/acpi/acpi.c index e0d7f74e2..cca44e931 100644 --- a/devicemodel/hw/platform/acpi/acpi.c +++ b/devicemodel/hw/platform/acpi/acpi.c @@ -272,11 +272,6 @@ int pcpuid_from_vcpuid(uint64_t guest_pcpu_bitmask, int vcpu_id) return find_nth_set_bit_index(guest_pcpu_bitmask, vcpu_id); } -int lapicid_from_pcpuid(struct acrn_platform_info *plat_info, int pcpu_id) -{ - return plat_info->hw.lapic_ids[pcpu_id]; -} - static int basl_fwrite_madt(FILE *fp, struct vmctx *ctx) { @@ -343,7 +338,11 @@ basl_fwrite_madt(FILE *fp, struct vmctx *ctx) return -1; } - lapic_id = lapicid_from_pcpuid(&plat_info, pcpu_id); + lapic_id = lapicid_from_pcpuid(pcpu_id); + if (lapic_id == -1) { + pr_err("Get lapic id fail.\n"); + return -1; + } EFPRINTF(fp, "[0001]\t\tSubtable Type : 00\n"); EFPRINTF(fp, "[0001]\t\tLength : 08\n"); diff --git a/devicemodel/hw/platform/acpi/acpi_parser.c b/devicemodel/hw/platform/acpi/acpi_parser.c new file mode 100644 index 000000000..afe5ad31f --- /dev/null +++ b/devicemodel/hw/platform/acpi/acpi_parser.c @@ -0,0 +1,131 @@ +/*- + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dm.h" +#include "log.h" +#include "hsm_ioctl_defs.h" +#include "acpi.h" + +static uint8_t lapic_ids[ACRN_PLATFORM_LAPIC_IDS_MAX] = {0xff}; + +int lapicid_from_pcpuid(int pcpu_id) +{ + if (pcpu_id < 0 || pcpu_id >= ACRN_PLATFORM_LAPIC_IDS_MAX || lapic_ids[pcpu_id] == 0xff) { + return -1; + } + return (int)lapic_ids[pcpu_id]; +} + +static int +local_parse_madt(struct acpi_table_madt *madt) +{ + uint16_t pcpu_num = 0U; + int ret = 0; + struct acpi_madt_local_apic *processor; + struct acpi_table_madt *madt_ptr; + void *first, *end, *iterator; + struct acpi_subtable_header *entry; + + madt_ptr = madt; + + first = madt_ptr + 1; + end = (void *)madt_ptr + madt_ptr->header.length; + + for (iterator = first; (iterator) < (end); iterator += entry->length) { + entry = (struct acpi_subtable_header *)iterator; + if (entry->length < sizeof(struct acpi_subtable_header)) { + break; + } + + if (entry->type == ACPI_MADT_TYPE_LOCAL_APIC) { + processor = (struct acpi_madt_local_apic *)iterator; + if ((processor->lapic_flags & ACPI_MADT_ENABLED) != 0U) { + if (pcpu_num < ACRN_PLATFORM_LAPIC_IDS_MAX) { + lapic_ids[pcpu_num] = processor->id; + } + pcpu_num++; + } + } + } + + if (pcpu_num == 0) { + ret = -1; + } + return ret; +} + +/* + * There has an assumption. The SOS owned pcpu starts from physical cpu 0, + * otherwise SOS doesn't know the mapping relationship between its vcpu0 + * and pcpu_id. + */ +int parse_madt(void) +{ + int ret = 0U; + ssize_t size; + struct acpi_table_madt *madt; + struct stat file_state; + + int fd = open("/sys/firmware/acpi/tables/APIC", O_RDONLY); + if (fd < 0) { + pr_err("Fail to open sos APIC file!\n"); + return -1; + } + + if (fstat(fd, &file_state) == -1) { + pr_err("Fail to get apic file state!\n"); + close(fd); + return -1; + } + + madt = (struct acpi_table_madt *)malloc(file_state.st_size); + size = read(fd, madt, file_state.st_size); + if (size == file_state.st_size) { + ret = local_parse_madt(madt); + } else { + pr_err("Fail to read sos madt info!"); + ret = -1; + } + + free(madt); + close(fd); + return ret; +} diff --git a/devicemodel/hw/platform/acpi/rtct.c b/devicemodel/hw/platform/acpi/rtct.c index 8fc66d2aa..d57bde08c 100644 --- a/devicemodel/hw/platform/acpi/rtct.c +++ b/devicemodel/hw/platform/acpi/rtct.c @@ -409,7 +409,11 @@ static int init_guest_lapicid_tbl(struct acrn_platform_info *platform_info, uint if (pcpu_id < 0) return -1; - guest_lapicid_tbl[vcpu_id] = lapicid_from_pcpuid(platform_info, pcpu_id); + guest_lapicid_tbl[vcpu_id] = lapicid_from_pcpuid(pcpu_id); + if (guest_lapicid_tbl[vcpu_id] == -1) { + pr_err("Get lapic id fail.\n"); + return -1; + } } return 0; } diff --git a/devicemodel/include/acpi.h b/devicemodel/include/acpi.h index 04a939905..f17847177 100644 --- a/devicemodel/include/acpi.h +++ b/devicemodel/include/acpi.h @@ -41,6 +41,11 @@ #define IO_PMTMR 0x0 /* PM Timer is disabled in ACPI */ +#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 + struct acpi_table_hdr { /* ASCII table signature */ char signature[4]; @@ -62,6 +67,29 @@ struct acpi_table_hdr { uint32_t asl_compiler_revision; } __attribute__((packed)); +struct acpi_table_madt { + /* Common ACPI table header */ + struct acpi_table_hdr 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; + + /* All dynamic table entry no. */ #define NHLT_ENTRY_NO 8 @@ -89,6 +117,7 @@ void power_button_init(struct vmctx *ctx); void power_button_deinit(struct vmctx *ctx); int pcpuid_from_vcpuid(uint64_t guest_pcpu_bitmask, int vcpu_id); -int lapicid_from_pcpuid(struct acrn_platform_info *plat_info, int pcpu_id); +int lapicid_from_pcpuid(int pcpu_id); +int parse_madt(void); #endif /* _ACPI_H_ */