Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | /*
* SPDX-License-Identifier: Apache-2.0
* Copyright (c) 2019 Intel Corp.
*/
#include <zephyr.h>
#include <arch/x86/acpi.h>
static void vtd_dev_scope_info(struct acpi_dmar_dev_scope *dev_scope)
{
struct acpi_dmar_dev_path *path;
int n_path;
printk("\t\t\t. Type: ");
switch (dev_scope->type) {
case ACPI_DRHD_DEV_SCOPE_PCI_EPD:
printk("PCI Endpoint");
break;
case ACPI_DRHD_DEV_SCOPE_PCI_SUB_H:
printk("PCI Sub-hierarchy");
break;
case ACPI_DRHD_DEV_SCOPE_IOAPIC:
printk("IOAPIC");
break;
case ACPI_DRHD_DEV_SCOPE_MSI_CAP_HPET:
printk("MSI Capable HPET");
break;
case ACPI_DRHD_DEV_SCOPE_NAMESPACE_DEV:
printk("ACPI name-space enumerated");
break;
default:
printk("unknown\n");
return;
}
printk("\n");
printk("\t\t\t. Enumeration ID %u\n", dev_scope->enumeration_id);
printk("\t\t\t. PCI Bus %u\n", dev_scope->start_bus_num);
path = z_acpi_get_dev_scope_paths(dev_scope, &n_path);
for (; n_path > 0; n_path--) {
printk("\t\t\t. Path D:%u F:%u\n",
path->device, path->function);
path = (struct acpi_dmar_dev_path *)(POINTER_TO_UINT(path) +
ACPI_DMAR_DEV_PATH_SIZE);
}
printk("\n");
}
static void vtd_drhd_info(struct acpi_drhd *drhd)
{
struct acpi_dmar_dev_scope *dev_scope;
int n_ds, i;
if (drhd->flags & ACPI_DRHD_FLAG_INCLUDE_PCI_ALL) {
printk("\t\t- Includes all PCI devices");
} else {
printk("\t\t- Includes only listed PCI devices");
}
printk(" under given Segment\n");
printk("\t\t- Segment number %u\n", drhd->segment_num);
printk("\t\t- Base Address 0x%llx\n", drhd->base_address);
dev_scope = z_acpi_get_drhd_dev_scopes(drhd, &n_ds);
if (dev_scope == NULL) {
printk("\t\t- No device scopes\n");
return;
}
printk("\t\t- Device Scopes:\n");
for (i = 0; i < n_ds; i++) {
vtd_dev_scope_info(dev_scope);
dev_scope = (struct acpi_dmar_dev_scope *)(
POINTER_TO_UINT(dev_scope) + dev_scope->length);
}
printk("\n");
}
static void vtd_info(void)
{
struct acpi_dmar *dmar;
dmar = z_acpi_find_dmar();
if (dmar == NULL) {
printk("\tIntel VT-D not supported or exposed\n");
return;
}
printk("\tIntel VT-D Supported:\n");
printk("\t-> X2APIC ");
if (dmar->flags & ACPI_DMAR_FLAG_X2APIC_OPT_OUT) {
printk("should be opted out\n");
} else {
printk("does not need to be opted out\n");
}
if (dmar->flags & ACPI_DMAR_FLAG_INTR_REMAP) {
struct acpi_drhd *drhd;
int hw_n, i;
printk("\t-> Interrupt remapping supported\n");
drhd = z_acpi_find_drhds(&hw_n);
printk("\t-> %u remapping hardware found:\n", hw_n);
for (i = 0; i < hw_n; i++) {
printk("\t\tDRHD %u:\n", i);
vtd_drhd_info(drhd);
drhd = (struct acpi_drhd *)(POINTER_TO_UINT(drhd) +
drhd->entry.length);
}
} else {
printk("\t-> Interrupt remapping not supported\n");
}
}
void acpi(void)
{
int nr_cpus;
for (nr_cpus = 0; z_acpi_get_cpu(nr_cpus); ++nr_cpus) {
/* count number of CPUs present */
}
if (nr_cpus == 0) {
printk("ACPI: no RSDT/MADT found\n\n");
} else {
printk("ACPI: %d CPUs found\n", nr_cpus);
for (int i = 0; i < nr_cpus; ++i) {
struct acpi_cpu *cpu = z_acpi_get_cpu(i);
printk("\tCPU #%d: APIC ID 0x%02x\n", i, cpu->apic_id);
}
}
printk("\n");
vtd_info();
printk("\n");
}
|