From b0e1657b4f505ee66beb027e2a03928e4e0233d9 Mon Sep 17 00:00:00 2001 From: dongshen Date: Mon, 19 Nov 2018 17:58:57 -0800 Subject: [PATCH] HV: Adding partition mode support for cb2_dnv Adding partition mode support for cb2_dnv. Tracked-On: #1853 Signed-off-by: dongshen --- hypervisor/arch/x86/Kconfig | 2 +- hypervisor/arch/x86/configs/cb2_dnv.config | 7 + hypervisor/partition/cb2_dnv/mptable.c | 349 ++++++++++++++++++ hypervisor/partition/cb2_dnv/vm_description.c | 291 +++++++++++++++ 4 files changed, 648 insertions(+), 1 deletion(-) create mode 100644 hypervisor/arch/x86/configs/cb2_dnv.config create mode 100644 hypervisor/partition/cb2_dnv/mptable.c create mode 100644 hypervisor/partition/cb2_dnv/vm_description.c diff --git a/hypervisor/arch/x86/Kconfig b/hypervisor/arch/x86/Kconfig index ade1ce277..f391e9f2d 100644 --- a/hypervisor/arch/x86/Kconfig +++ b/hypervisor/arch/x86/Kconfig @@ -300,7 +300,7 @@ config CONSTANT_ACPI built-in tables after parsing the real ACPI tables at runtime. config DMAR_PARSE_ENABLED - bool + bool "Enable DMAR parsing" default n if PLATFORM_SBL default y if PLATFORM_UEFI help diff --git a/hypervisor/arch/x86/configs/cb2_dnv.config b/hypervisor/arch/x86/configs/cb2_dnv.config new file mode 100644 index 000000000..17cd06f03 --- /dev/null +++ b/hypervisor/arch/x86/configs/cb2_dnv.config @@ -0,0 +1,7 @@ +CONFIG_BOARD="cb2_dnv" +CONFIG_PLATFORM_SBL=y +CONFIG_PARTITION_MODE=y +CONFIG_SERIAL_PIO=y +CONFIG_SERIAL_PIO_BASE=0x1000 +CONFIG_DMAR_PARSE_ENABLED=y + diff --git a/hypervisor/partition/cb2_dnv/mptable.c b/hypervisor/partition/cb2_dnv/mptable.c new file mode 100644 index 000000000..0888cf2c9 --- /dev/null +++ b/hypervisor/partition/cb2_dnv/mptable.c @@ -0,0 +1,349 @@ +/* + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#define MPTABLE_BASE 0xF0000U + +/* + * floating pointer length + maximum length of configuration table + * ACRN uses contiguous guest memory from 0xF0000 to place floating pointer + * structure and config table. Maximum length of config table is 64K. So the + * maximum length of combined floating pointer and config table can go up to + * 64K + 16 bytes.Since we are left with only 64K from 0xF0000 to 0x100000(1MB) + * max length is limited to 64K. + */ +#define MPTABLE_MAX_LENGTH 65536U + +#define LAPIC_VERSION 16U + +#define MP_SPECREV 4U +#define MPFP_SIG "_MP_" + +/* Configuration header defines */ +#define MPCH_SIG "PCMP" +#define MPCH_OEMID "BHyVe " +#define MPCH_OEMID_LEN 8U +#define MPCH_PRODID "Hypervisor " +#define MPCH_PRODID_LEN 12U + +/* Processor entry defines */ +#define MPEP_SIG_FAMILY 6U +#define MPEP_SIG_MODEL 26U +#define MPEP_SIG_STEPPING 5U +#define MPEP_SIG \ + ((MPEP_SIG_FAMILY << 8U) | \ + (MPEP_SIG_MODEL << 4U) | \ + (MPEP_SIG_STEPPING)) + +#define MPEP_FEATURES 0xBFEBFBFFU /* XXX Intel i7 */ + +/* Number of local intr entries */ +#define MPEII_NUM_LOCAL_IRQ 2U + +/* Bus entry defines */ +#define MPE_NUM_BUSES 2U +#define MPE_BUSNAME_LEN 6U +#define MPE_BUSNAME_ISA "ISA " +#define MPE_BUSNAME_PCI "PCI " + +/* Base table entries */ + +#define MPCT_ENTRY_PROCESSOR 0U +#define MPCT_ENTRY_BUS 1U +#define MPCT_ENTRY_LOCAL_INT 4U + +#define PROCENTRY_FLAG_EN 0x01U +#define PROCENTRY_FLAG_BP 0x02U + +#define INTENTRY_TYPE_NMI 1U +#define INTENTRY_TYPE_EXTINT 3U + +#define INTENTRY_FLAGS_POLARITY_CONFORM 0x0U +#define INTENTRY_FLAGS_TRIGGER_CONFORM 0x0U + +#define VM1_NUM_CPUS 4U +#define VM2_NUM_CPUS 4U + +/* MP Floating Pointer Structure */ +struct mpfps { + uint8_t signature[4]; + uint32_t pap; + uint8_t length; + uint8_t spec_rev; + uint8_t checksum; + uint8_t config_type; + uint8_t mpfb2; + uint8_t mpfb3; + uint8_t mpfb4; + uint8_t mpfb5; +} __attribute__((packed)); + +/* MP Configuration Table Header */ +struct mpcth { + uint8_t signature[4]; + uint16_t base_table_length; + uint8_t spec_rev; + uint8_t checksum; + uint8_t oem_id[8]; + uint8_t product_id[12]; + uint32_t oem_table_pointer; + uint16_t oem_table_size; + uint16_t entry_count; + uint32_t apic_address; + uint16_t extended_table_length; + uint8_t extended_table_checksum; + uint8_t reserved; +} __attribute__((packed)); + +struct proc_entry { + uint8_t type; + uint8_t apic_id; + uint8_t apic_version; + uint8_t cpu_flags; + uint32_t cpu_signature; + uint32_t feature_flags; + uint32_t reserved1; + uint32_t reserved2; +} __attribute__((packed)); + +struct bus_entry { + uint8_t type; + uint8_t bus_id; + uint8_t bus_type[6]; +} __attribute__((packed)); + +struct int_entry { + uint8_t type; + uint8_t int_type; + uint16_t int_flags; + uint8_t src_bus_id; + uint8_t src_bus_irq; + uint8_t dst_apic_id; + uint8_t dst_apic_int; +} __attribute__((packed)); + +struct mptable_info { + struct mpfps mpfp; + struct mpcth mpch; + struct bus_entry bus_entry_array[MPE_NUM_BUSES]; + struct int_entry int_entry_array[MPEII_NUM_LOCAL_IRQ]; + struct proc_entry proc_entry_array[]; +}; + +struct mptable_info mptable_vm1 = { + .mpfp = { + .signature = MPFP_SIG, + .pap = MPTABLE_BASE + sizeof(struct mpfps), + .length = 1U, + .spec_rev = MP_SPECREV, + }, + .mpch = { + .signature = MPCH_SIG, + .spec_rev = MP_SPECREV, + .oem_id = MPCH_OEMID, + .product_id = MPCH_PRODID, + .apic_address = LAPIC_BASE, + .entry_count = (VM1_NUM_CPUS + MPE_NUM_BUSES \ + + MPEII_NUM_LOCAL_IRQ), + .base_table_length = (sizeof(struct mpcth) \ + + VM1_NUM_CPUS * sizeof(struct proc_entry) \ + + MPE_NUM_BUSES * sizeof(struct bus_entry) \ + + MPEII_NUM_LOCAL_IRQ * sizeof(struct int_entry)) + }, + .proc_entry_array = { + { + .type = MPCT_ENTRY_PROCESSOR, + .apic_id = 0U, + .apic_version = LAPIC_VERSION, + .cpu_flags = PROCENTRY_FLAG_EN | PROCENTRY_FLAG_BP, + .cpu_signature = MPEP_SIG, + .feature_flags = MPEP_FEATURES + }, + { + .type = MPCT_ENTRY_PROCESSOR, + .apic_id = 8U, + .apic_version = LAPIC_VERSION, + .cpu_flags = PROCENTRY_FLAG_EN, + .cpu_signature = MPEP_SIG, + .feature_flags = MPEP_FEATURES, + }, + { + .type = MPCT_ENTRY_PROCESSOR, + .apic_id = 16U, + .apic_version = LAPIC_VERSION, + .cpu_flags = PROCENTRY_FLAG_EN, + .cpu_signature = MPEP_SIG, + .feature_flags = MPEP_FEATURES, + }, + { + .type = MPCT_ENTRY_PROCESSOR, + .apic_id = 24U, + .apic_version = LAPIC_VERSION, + .cpu_flags = PROCENTRY_FLAG_EN, + .cpu_signature = MPEP_SIG, + .feature_flags = MPEP_FEATURES, + } + }, + .bus_entry_array = { + { + .type = MPCT_ENTRY_BUS, + .bus_id = 0U, + .bus_type = MPE_BUSNAME_PCI, + }, + { + .type = MPCT_ENTRY_BUS, + .bus_id = 1U, + .bus_type = MPE_BUSNAME_ISA, + }, + }, + .int_entry_array = { + { + .type = MPCT_ENTRY_LOCAL_INT, + .int_type = INTENTRY_TYPE_EXTINT, + .int_flags = INTENTRY_FLAGS_POLARITY_CONFORM \ + | INTENTRY_FLAGS_TRIGGER_CONFORM, + .dst_apic_id = 0xFFU, + .dst_apic_int = 0U, + }, + { + .type = MPCT_ENTRY_LOCAL_INT, + .int_type = INTENTRY_TYPE_NMI, + .int_flags = INTENTRY_FLAGS_POLARITY_CONFORM \ + | INTENTRY_FLAGS_TRIGGER_CONFORM, + .dst_apic_id = 0xFFU, + .dst_apic_int = 1U, + }, + }, +}; + +struct mptable_info mptable_vm2 = { + .mpfp = { + .signature = MPFP_SIG, + .pap = MPTABLE_BASE + sizeof(struct mpfps), + .length = 1U, + .spec_rev = MP_SPECREV, + }, + .mpch = { + .signature = MPCH_SIG, + .spec_rev = MP_SPECREV, + .oem_id = MPCH_OEMID, + .product_id = MPCH_PRODID, + .apic_address = LAPIC_BASE, + .entry_count = (VM2_NUM_CPUS + MPE_NUM_BUSES \ + + MPEII_NUM_LOCAL_IRQ), + .base_table_length = (sizeof(struct mpcth) \ + + VM2_NUM_CPUS * sizeof(struct proc_entry) \ + + MPE_NUM_BUSES * sizeof(struct bus_entry) \ + + MPEII_NUM_LOCAL_IRQ * sizeof(struct int_entry)) + }, + .proc_entry_array = { + { + .type = MPCT_ENTRY_PROCESSOR, + .apic_id = 28U, + .apic_version = LAPIC_VERSION, + .cpu_flags = PROCENTRY_FLAG_EN | PROCENTRY_FLAG_BP, + .cpu_signature = MPEP_SIG, + .feature_flags = MPEP_FEATURES + }, + { + .type = MPCT_ENTRY_PROCESSOR, + .apic_id = 20U, + .apic_version = LAPIC_VERSION, + .cpu_flags = PROCENTRY_FLAG_EN, + .cpu_signature = MPEP_SIG, + .feature_flags = MPEP_FEATURES, + }, + { + .type = MPCT_ENTRY_PROCESSOR, + .apic_id = 12U, + .apic_version = LAPIC_VERSION, + .cpu_flags = PROCENTRY_FLAG_EN , + .cpu_signature = MPEP_SIG, + .feature_flags = MPEP_FEATURES + }, + { + .type = MPCT_ENTRY_PROCESSOR, + .apic_id = 4U, + .apic_version = LAPIC_VERSION, + .cpu_flags = PROCENTRY_FLAG_EN, + .cpu_signature = MPEP_SIG, + .feature_flags = MPEP_FEATURES, + } + }, + .bus_entry_array = { + { + .type = MPCT_ENTRY_BUS, + .bus_id = 0U, + .bus_type = MPE_BUSNAME_PCI, + }, + { + .type = MPCT_ENTRY_BUS, + .bus_id = 1U, + .bus_type = MPE_BUSNAME_ISA, + }, + }, + .int_entry_array = { + { + .type = MPCT_ENTRY_LOCAL_INT, + .int_type = INTENTRY_TYPE_EXTINT, + .int_flags = INTENTRY_FLAGS_POLARITY_CONFORM \ + | INTENTRY_FLAGS_TRIGGER_CONFORM, + .dst_apic_id = 0xFFU, + .dst_apic_int = 0U, + }, + { + .type = MPCT_ENTRY_LOCAL_INT, + .int_type = INTENTRY_TYPE_NMI, + .int_flags = INTENTRY_FLAGS_POLARITY_CONFORM \ + | INTENTRY_FLAGS_TRIGGER_CONFORM, + .dst_apic_id = 0xFFU, + .dst_apic_int = 1U, + }, + }, +}; + +static uint8_t mpt_compute_checksum(void *base, size_t len) +{ + uint8_t *bytes; + uint8_t sum; + size_t length = len; + + for (bytes = base, sum = 0U; length > 0U; length--) { + sum += *bytes; + bytes++; + } + + return (256U - sum); +} + +int mptable_build(struct acrn_vm *vm) +{ + char *startaddr; + char *curraddr; + struct mpcth *mpch; + struct mpfps *mpfp; + size_t mptable_length, table_length; + + startaddr = (char *)gpa2hva(vm, MPTABLE_BASE); + + table_length = vm->vm_desc->mptable->mpch.base_table_length; + mptable_length = sizeof(struct mpfps) + table_length; + /* Copy mptable info into guest memory */ + (void)memcpy_s((void *)startaddr, MPTABLE_MAX_LENGTH, + (void *)vm->vm_desc->mptable, + mptable_length); + + curraddr = startaddr; + mpfp = (struct mpfps *)curraddr; + mpfp->checksum = mpt_compute_checksum(mpfp, sizeof(struct mpfps)); + curraddr += sizeof(struct mpfps); + + mpch = (struct mpcth *)curraddr; + mpch->checksum = mpt_compute_checksum(mpch, mpch->base_table_length); + + return 0U; +} diff --git a/hypervisor/partition/cb2_dnv/vm_description.c b/hypervisor/partition/cb2_dnv/vm_description.c new file mode 100644 index 000000000..6bc525bda --- /dev/null +++ b/hypervisor/partition/cb2_dnv/vm_description.c @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#define NUM_USER_VMS 2U + +/* Number of CPUs in VM1*/ +#define VM1_NUM_CPUS 4U + +/* Logical CPU IDs assigned to this VM */ +uint16_t VM1_CPUS[VM1_NUM_CPUS] = {0U, 2U, 4U, 6U}; + +/* Number of CPUs in VM2*/ +#define VM2_NUM_CPUS 4U + +/* Logical CPU IDs assigned with this VM */ +uint16_t VM2_CPUS[VM2_NUM_CPUS] = {7U, 5U, 3U, 1U}; + +static struct vpci_vdev_array vpci_vdev_array1 = { + .num_pci_vdev = 3, + .vpci_vdev_list = { + {/*vdev 0: hostbridge */ + .vbdf.bits = {.b = 0x00U, .d = 0x00U, .f = 0x0U}, + .ops = &pci_ops_vdev_hostbridge, + .bar = {}, + .pdev = { + .bdf.bits = {.b = 0x00U, .d = 0x00U, .f = 0x0U}, + } + }, + + {/*vdev 1: Ethernet*/ + .vbdf.bits = {.b = 0x00U, .d = 0x01U, .f = 0x0U}, + .ops = &pci_ops_vdev_pt, + .bar = { + [0] = { + .base = 0UL, + .size = 0x200000UL, + .type = PCIBAR_MEM32, + }, + [4] = { + .base = 0UL, + .size = 0x4000UL, + .type = PCIBAR_MEM32, + }, + }, + .pdev = { + .bdf.bits = {.b = 0x03U, .d = 0x00U, .f = 0x1U}, + .bar = { + [0] = { + .base = 0x80C00000, + .size = 0x200000UL, + .type = PCIBAR_MEM32, + }, + [4] = { + .base = 0x81000000, + .size = 0x4000UL, + .type = PCIBAR_MEM32, + }, + } + } + }, + + {/*vdev 2: USB*/ + .vbdf.bits = {.b = 0x00U, .d = 0x02U, .f = 0x0U}, + .ops = &pci_ops_vdev_pt, + .bar = { + [0] = { + .base = 0UL, + .size = 0x10000UL, + .type = PCIBAR_MEM32, + } + }, + .pdev = { + .bdf.bits = {.b = 0x00U, .d = 0x15U, .f = 0x0U}, + .bar = { + [0] = { + .base = 0x81340000, + .size = 0x10000UL, + .type = PCIBAR_MEM32, + } + } + } + }, + } +}; + +static struct vpci_vdev_array vpci_vdev_array2 = { + .num_pci_vdev = 3, + + .vpci_vdev_list = { + {/*vdev 0: hostbridge*/ + .vbdf.bits = {.b = 0x00U, .d = 0x00U, .f = 0x0U}, + .ops = &pci_ops_vdev_hostbridge, + .bar = {}, + .pdev = { + .bdf.bits = {.b = 0x00U, .d = 0x00U, .f = 0x0U}, + } + }, + + {/*vdev 1: SATA controller*/ + .vbdf.bits = {.b = 0x00U, .d = 0x05U, .f = 0x0U}, + .ops = &pci_ops_vdev_pt, + .bar = { + [0] = { + .base = 0UL, + .size = 0x2000UL, + .type = PCIBAR_MEM32 + }, + [1] = { + .base = 0UL, + .size = 0x1000UL, + .type = PCIBAR_MEM32 + }, + [5] = { + .base = 0UL, + .size = 0x1000UL, + .type = PCIBAR_MEM32 + }, + }, + .pdev = { + .bdf.bits = {.b = 0x00U, .d = 0x14U, .f = 0x0U}, + .bar = { + [0] = { + .base = 0x81354000, + .size = 0x2000UL, + .type = PCIBAR_MEM32 + }, + [1] = { + .base = 0x8135f000, + .size = 0x1000UL, + .type = PCIBAR_MEM32 + }, + [5] = { + .base = 0x8135e000, + .size = 0x1000UL, + .type = PCIBAR_MEM32 + }, + } + } + }, + + {/*vdev 2: Ethernet*/ + .vbdf.bits = {.b = 0x00U, .d = 0x06U, .f = 0x0U}, + .ops = &pci_ops_vdev_pt, + .bar = { + [0] = { + .base = 0UL, + .size = 0x200000UL, + .type = PCIBAR_MEM32, + }, + [4] = { + .base = 0UL, + .size = 0x4000UL, + .type = PCIBAR_MEM32, + }, + }, + + .pdev = { + .bdf.bits = {.b = 0x03U, .d = 0x00U, .f = 0x0U}, + .bar = { + [0] = { + .base = 0x80e00000, + .size = 0x200000UL, + .type = PCIBAR_MEM32, + }, + [4] = { + .base = 0x81004000, + .size = 0x4000UL, + .type = PCIBAR_MEM32, + } + } + } + + }, + + } +}; + +/*******************************/ +/* User Defined VM definitions */ +/*******************************/ +struct vm_description_array vm_desc_partition = { + /* Number of user virtual machines */ + .num_vm_desc = NUM_USER_VMS, + + /* Virtual Machine descriptions */ + .vm_desc_array = { + { + /* Internal variable, MUSTBE init to -1 */ + .vm_hw_num_cores = VM1_NUM_CPUS, + .vm_pcpu_ids = &VM1_CPUS[0], + .vm_id = 1U, + .start_hpa = 0x100000000UL, + .mem_size = 0x80000000UL, /* uses contiguous memory from host */ + .vm_vuart = true, + .bootargs = "root=/dev/sda rw rootwait noxsave maxcpus=4 nohpet console=hvc0 " \ + "console=ttyS0 no_timer_check ignore_loglevel log_buf_len=16M "\ + "consoleblank=0 tsc=reliable xapic_phys apic_debug", + .vpci_vdev_array = &vpci_vdev_array1, + .mptable = &mptable_vm1, + .lapic_pt = true, + }, + + { + /* Internal variable, MUSTBE init to -1 */ + .vm_hw_num_cores = VM2_NUM_CPUS, + .vm_pcpu_ids = &VM2_CPUS[0], + .vm_id = 2U, + .start_hpa = 0x180000000UL, + .mem_size = 0x80000000UL, /* uses contiguous memory from host */ + .vm_vuart = true, + .bootargs = "root=/dev/sda2 rw rootwait noxsave maxcpus=4 nohpet console=hvc0 "\ + "console=ttyS0 no_timer_check ignore_loglevel log_buf_len=16M "\ + "consoleblank=0 tsc=reliable xapic_phys apic_debug", + .vpci_vdev_array = &vpci_vdev_array2, + .mptable = &mptable_vm2, + .lapic_pt = true, + }, + } +}; + +const struct pcpu_vm_desc_mapping pcpu_vm_desc_map[] = { + { + .vm_desc_ptr = &vm_desc_partition.vm_desc_array[0], + .is_bsp = true, + }, + { + .vm_desc_ptr = &vm_desc_partition.vm_desc_array[1], + .is_bsp = false, + }, + { + .vm_desc_ptr = &vm_desc_partition.vm_desc_array[0], + .is_bsp = false, + }, + { + .vm_desc_ptr = &vm_desc_partition.vm_desc_array[1], + .is_bsp = false, + }, + { + .vm_desc_ptr = &vm_desc_partition.vm_desc_array[0], + .is_bsp = false, + }, + { + .vm_desc_ptr = &vm_desc_partition.vm_desc_array[1], + .is_bsp = false, + }, + { + .vm_desc_ptr = &vm_desc_partition.vm_desc_array[0], + .is_bsp = false, + }, + { + .vm_desc_ptr = &vm_desc_partition.vm_desc_array[1], + .is_bsp = true, + }, +}; + +const struct e820_entry e820_default_entries[NUM_E820_ENTRIES] = { + { /* 0 to mptable */ + .baseaddr = 0x0U, + .length = 0xEFFFFU, + .type = E820_TYPE_RAM + }, + + { /* mptable 65536U */ + .baseaddr = 0xF0000U, + .length = 0x10000U, + .type = E820_TYPE_RESERVED + }, + + { /* mptable to lowmem */ + .baseaddr = 0x100000U, + .length = 0x7FF00000U, + .type = E820_TYPE_RAM + }, + + { /* lowmem to PCI hole */ + .baseaddr = 0x80000000U, + .length = 0x40000000U, + .type = E820_TYPE_RESERVED + }, + + { /* PCI hole to 4G */ + .baseaddr = 0xe0000000U, + .length = 0x20000000U, + .type = E820_TYPE_RESERVED + }, +};