/* * Parse LAPIC entries in MADT * returns 0 on success, < 0 on error */ static int __init acpi_parse_madt_lapic_entries(void) { int count, x2count; if (!cpu_has_apic) return -ENODEV; /* * Note that the LAPIC address is obtained from the MADT (32-bit value) * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). */ count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE, acpi_parse_lapic_addr_ovr, 0); if (count < 0) { printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); return count; } mp_register_lapic_address(acpi_lapic_addr); BUILD_BUG_ON(MAX_APICS != MAX_LOCAL_APIC); count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, acpi_parse_lapic, MAX_APICS); x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC, acpi_parse_x2apic, MAX_APICS); if (!count && !x2count) { printk(KERN_ERR PREFIX "No LAPIC entries present\n"); /* TBD: Cleanup to allow fallback to MPS */ return -ENODEV; } else if (count < 0 || x2count < 0) { printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); /* TBD: Cleanup to allow fallback to MPS */ return count < 0 ? count : x2count; } count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0); x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC_NMI, acpi_parse_x2apic_nmi, 0); if (count < 0 || x2count < 0) { printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); /* TBD: Cleanup to allow fallback to MPS */ return count < 0 ? count : x2count; } return 0; }
/* Parse GIC cpu interface entries in MADT for SMP init */ void __init acpi_init_cpus(void) { int count, i; /* * do a partial walk of MADT to determine how many CPUs * we have including disabled CPUs, and get information * we need for SMP init */ count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, acpi_parse_gic_cpu_interface, 0); if (!count) { pr_err("No GIC CPU interface entries present\n"); return; } else if (count < 0) { pr_err("Error parsing GIC CPU interface entry\n"); return; } if (!bootcpu_valid) { pr_err("MADT missing boot CPU MPIDR, not enabling secondaries\n"); return; } for (i = 0; i < enabled_cpus; i++) set_cpu_possible(i, true); /* Make boot-up look pretty */ pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus); }
int __init early_acpi_boot_init(void) { int ret; /* * do a partial walk of MADT to determine how many CPUs * we have including offline CPUs */ if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) { printk(KERN_ERR PREFIX "Can't find MADT\n"); return 0; } ret = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, acpi_parse_lsapic, NR_CPUS); if (ret < 1) printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n"); #ifdef CONFIG_SMP if (available_cpus == 0) { printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n"); printk(KERN_INFO "CPU 0 (0x%04x)", hard_smp_processor_id()); smp_boot_data.cpu_phys_id[available_cpus] = hard_smp_processor_id(); available_cpus = 1; /* We've got at least one of these, no? */ } smp_boot_data.cpu_count = available_cpus; #endif /* Make boot-up look pretty */ printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus); return 0; }
int __init early_acpi_boot_init(void) { int ret; if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) { printk(KERN_ERR PREFIX "Can't find MADT\n"); return 0; } ret = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, acpi_parse_lsapic, NR_CPUS); if (ret < 1) printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n"); #ifdef CONFIG_SMP if (available_cpus == 0) { printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n"); printk(KERN_INFO "CPU 0 (0x%04x)", hard_smp_processor_id()); smp_boot_data.cpu_phys_id[available_cpus] = hard_smp_processor_id(); available_cpus = 1; } smp_boot_data.cpu_count = available_cpus; #endif printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus); return 0; }
int __init early_acpi_boot_init(void) { int ret; /* * do a partial walk of MADT to determine how many CPUs * we have including offline CPUs */ if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) { printk(KERN_ERR PREFIX "Can't find MADT\n"); return 0; } ret = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, acpi_parse_lsapic, NR_CPUS); if (ret < 1) printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n"); return 0; }
/* * Enumerate the possible CPU set from the device tree or ACPI and build the * cpu logical map array containing MPIDR values related to logical * cpus. Assumes that cpu_logical_map(0) has already been initialized. */ void __init smp_init_cpus(void) { int i; if (acpi_disabled) of_parse_and_init_cpus(); else /* * do a walk of MADT to determine how many CPUs * we have including disabled CPUs, and get information * we need for SMP init */ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, acpi_parse_gic_cpu_interface, 0); if (cpu_count > NR_CPUS) pr_warn("no. of cores (%d) greater than configured maximum of %d - clipping\n", cpu_count, NR_CPUS); if (!bootcpu_valid) { pr_err("missing boot CPU MPIDR, not enabling secondaries\n"); return; } /* * We need to set the cpu_logical_map entries before enabling * the cpus so that cpu processor description entries (DT cpu nodes * and ACPI MADT entries) can be retrieved by matching the cpu hwid * with entries in cpu_logical_map while initializing the cpus. * If the cpu set-up fails, invalidate the cpu_logical_map entry. */ for (i = 1; i < NR_CPUS; i++) { if (cpu_logical_map(i) != INVALID_HWID) { if (smp_cpu_setup(i)) cpu_logical_map(i) = INVALID_HWID; } } }
/* * Parse IOAPIC related entries in MADT * returns 0 on success, < 0 on error */ static int __init acpi_parse_madt_ioapic_entries(void) { int count; /* * ACPI interpreter is required to complete interrupt setup, * so if it is off, don't enumerate the io-apics with ACPI. * If MPS is present, it will handle them, * otherwise the system will stay in PIC mode */ if (acpi_disabled || acpi_noirq) { return -ENODEV; } if (!cpu_has_apic) return -ENODEV; /* * if "noapic" boot option, don't look for IO-APICs */ if (skip_ioapic_setup) { printk(KERN_INFO PREFIX "Skipping IOAPIC probe " "due to 'noapic' option.\n"); return -ENODEV; } count = acpi_table_parse_madt(ACPI_MADT_TYPE_IO_APIC, acpi_parse_ioapic, MAX_IO_APICS); if (!count) { printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); return -ENODEV; } else if (count < 0) { printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n"); return count; } count = acpi_table_parse_madt(ACPI_MADT_TYPE_INTERRUPT_OVERRIDE, acpi_parse_int_src_ovr, MAX_IRQ_SOURCES); if (count < 0) { printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); /* TBD: Cleanup to allow fallback to MPS */ return count; } /* Fill in identity legacy mapings where no override */ mp_config_acpi_legacy_irqs(); count = acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE, acpi_parse_nmi_src, MAX_IRQ_SOURCES); if (count < 0) { printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); /* TBD: Cleanup to allow fallback to MPS */ return count; } return 0; }
/* * acpi_boot_init() * called from setup_arch(), always. * 1. maps ACPI tables for later use * 2. enumerates lapics * 3. enumerates io-apics * * side effects: * acpi_lapic = 1 if LAPIC found * acpi_ioapic = 1 if IOAPIC found * if (acpi_lapic && acpi_ioapic) smp_found_config = 1; * if acpi_blacklisted() disable_acpi() * acpi_irq_model=... * ... * * return value: (currently ignored) * 0: success * !0: failure */ int __init acpi_boot_init (void) { int result = 0; if (acpi_disabled && !acpi_ht) return(1); /* * The default interrupt routing model is PIC (8259). This gets * overriden if IOAPICs are enumerated (below). */ acpi_irq_model = ACPI_IRQ_MODEL_PIC; /* * Initialize the ACPI boot-time table parser. */ result = acpi_table_init(); if (result) { disable_acpi(); return result; } #ifdef CONFIG_X86_IO_APIC check_acpi_pci(); #endif result = acpi_blacklisted(); if (result) { printk(KERN_NOTICE PREFIX "BIOS listed in blacklist, disabling ACPI support\n"); disable_acpi(); return result; } #ifdef CONFIG_ACPI_MMCONFIG result = acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); if (result < 0) { printk(KERN_ERR PREFIX "Error %d parsing MCFG\n", result); } else if (result > 1) { printk(KERN_WARNING PREFIX "Multiple MCFG tables exist\n"); } #endif #ifdef CONFIG_X86_LOCAL_APIC /* * MADT * ---- * Parse the Multiple APIC Description Table (MADT), if exists. * Note that this table provides platform SMP configuration * information -- the successor to MPS tables. */ result = acpi_table_parse(ACPI_APIC, acpi_parse_madt); if (!result) { return 0; } else if (result < 0) { printk(KERN_ERR PREFIX "Error parsing MADT\n"); return result; } else if (result > 1) printk(KERN_WARNING PREFIX "Multiple MADT tables exist\n"); /* * Local APIC * ---------- * Note that the LAPIC address is obtained from the MADT (32-bit value) * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). */ result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr); if (result < 0) { printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); return result; } mp_register_lapic_address(acpi_lapic_addr); result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic); if (!result) { printk(KERN_ERR PREFIX "No LAPIC entries present\n"); /* TBD: Cleanup to allow fallback to MPS */ return -ENODEV; } else if (result < 0) { printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); /* TBD: Cleanup to allow fallback to MPS */ return result; } result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi); if (result < 0) { printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); /* TBD: Cleanup to allow fallback to MPS */ return result; } acpi_lapic = 1; #endif /*CONFIG_X86_LOCAL_APIC*/ #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER) /* * I/O APIC * -------- */ /* * ACPI interpreter is required to complete interrupt setup, * so if it is off, don't enumerate the io-apics with ACPI. * If MPS is present, it will handle them, * otherwise the system will stay in PIC mode */ if (acpi_disabled || acpi_noirq) { return 1; } /* * if "noapic" boot option, don't look for IO-APICs */ if (ioapic_setup_disabled()) { printk(KERN_INFO PREFIX "Skipping IOAPIC probe " "due to 'noapic' option.\n"); return 1; } result = mp_irqs_alloc(); /* Dynamically allocate mp_irqs[] */ if (result < 0) { acpi_noirq = 1; return result; } result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic); if (!result) { printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); return -ENODEV; } else if (result < 0) { printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n"); return result; } /* Record sci_int for use when looking for MADT sci_int override */ acpi_table_parse(ACPI_FADT, acpi_parse_fadt); result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr); if (result < 0) { printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); /* TBD: Cleanup to allow fallback to MPS */ return result; } /* * If BIOS did not supply an INT_SRC_OVR for the SCI * pretend we got one so we can set the SCI flags. */ if (!acpi_sci_override_gsi) acpi_sci_ioapic_setup(acpi_fadt.sci_int, 0, 0); /* Fill in identity legacy mapings where no override */ mp_config_acpi_legacy_irqs(); result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src); if (result < 0) { printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); /* TBD: Cleanup to allow fallback to MPS */ return result; } acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; acpi_irq_balance_set(NULL); acpi_ioapic = 1; if (acpi_lapic && acpi_ioapic) smp_found_config = 1; #endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/ return 0; }
int __init acpi_boot_init(void) { /* * MADT * ---- * Parse the Multiple APIC Description Table (MADT), if exists. * Note that this table provides platform SMP configuration * information -- the successor to MPS tables. */ if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) { printk(KERN_ERR PREFIX "Can't find MADT\n"); goto skip_madt; } /* Local APIC */ if (acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE, acpi_parse_lapic_addr_ovr, 0) < 0) printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); if (acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, acpi_parse_lsapic, NR_CPUS) < 1) printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n"); if (acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0) < 0) printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); /* I/O APIC */ if (acpi_table_parse_madt (ACPI_MADT_TYPE_IO_SAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1) { if (!ia64_platform_is("sn2")) printk(KERN_ERR PREFIX "Error parsing MADT - no IOSAPIC entries\n"); } /* System-Level Interrupt Routing */ if (acpi_table_parse_madt (ACPI_MADT_TYPE_INTERRUPT_SOURCE, acpi_parse_plat_int_src, ACPI_MAX_PLATFORM_INTERRUPTS) < 0) printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n"); if (acpi_table_parse_madt (ACPI_MADT_TYPE_INTERRUPT_OVERRIDE, acpi_parse_int_src_ovr, 0) < 0) printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); if (acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE, acpi_parse_nmi_src, 0) < 0) printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); skip_madt: /* * FADT says whether a legacy keyboard controller is present. * The FADT also contains an SCI_INT line, by which the system * gets interrupts such as power and sleep buttons. If it's not * on a Legacy interrupt, it needs to be setup. */ if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt)) printk(KERN_ERR PREFIX "Can't find FADT\n"); #ifdef CONFIG_SMP if (available_cpus == 0) { printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n"); printk(KERN_INFO "CPU 0 (0x%04x)", hard_smp_processor_id()); smp_boot_data.cpu_phys_id[available_cpus] = hard_smp_processor_id(); available_cpus = 1; /* We've got at least one of these, no? */ } smp_boot_data.cpu_count = available_cpus; smp_build_cpu_map(); # ifdef CONFIG_ACPI_NUMA if (srat_num_cpus == 0) { int cpu, i = 1; for (cpu = 0; cpu < smp_boot_data.cpu_count; cpu++) if (smp_boot_data.cpu_phys_id[cpu] != hard_smp_processor_id()) node_cpuid[i++].phys_id = smp_boot_data.cpu_phys_id[cpu]; } # endif #endif #ifdef CONFIG_ACPI_NUMA build_cpu_to_node_map(); #endif /* Make boot-up look pretty */ printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus); return 0; }
static int __init pvh_setup_acpi_madt(struct domain *d, paddr_t *addr) { struct acpi_table_madt *madt; struct acpi_table_header *table; struct acpi_madt_io_apic *io_apic; struct acpi_madt_local_x2apic *x2apic; acpi_status status; unsigned long size; unsigned int i, max_vcpus; int rc; /* Count number of interrupt overrides in the MADT. */ acpi_table_parse_madt(ACPI_MADT_TYPE_INTERRUPT_OVERRIDE, acpi_count_intr_ovr, UINT_MAX); /* Count number of NMI sources in the MADT. */ acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE, acpi_count_nmi_src, UINT_MAX); max_vcpus = dom0_max_vcpus(); /* Calculate the size of the crafted MADT. */ size = sizeof(*madt); size += sizeof(*io_apic) * nr_ioapics; size += sizeof(*intsrcovr) * acpi_intr_overrides; size += sizeof(*nmisrc) * acpi_nmi_sources; size += sizeof(*x2apic) * max_vcpus; madt = xzalloc_bytes(size); if ( !madt ) { printk("Unable to allocate memory for MADT table\n"); rc = -ENOMEM; goto out; } /* Copy the native MADT table header. */ status = acpi_get_table(ACPI_SIG_MADT, 0, &table); if ( !ACPI_SUCCESS(status) ) { printk("Failed to get MADT ACPI table, aborting.\n"); rc = -EINVAL; goto out; } madt->header = *table; madt->address = APIC_DEFAULT_PHYS_BASE; /* * NB: this is currently set to 4, which is the revision in the ACPI * spec 6.1. Sadly ACPICA doesn't provide revision numbers for the * tables described in the headers. */ madt->header.revision = min_t(unsigned char, table->revision, 4); /* Setup the IO APIC entries. */ io_apic = (void *)(madt + 1); for ( i = 0; i < nr_ioapics; i++ ) { io_apic->header.type = ACPI_MADT_TYPE_IO_APIC; io_apic->header.length = sizeof(*io_apic); io_apic->id = domain_vioapic(d, i)->id; io_apic->address = domain_vioapic(d, i)->base_address; io_apic->global_irq_base = domain_vioapic(d, i)->base_gsi; io_apic++; } x2apic = (void *)io_apic; for ( i = 0; i < max_vcpus; i++ ) { x2apic->header.type = ACPI_MADT_TYPE_LOCAL_X2APIC; x2apic->header.length = sizeof(*x2apic); x2apic->uid = i; x2apic->local_apic_id = i * 2; x2apic->lapic_flags = ACPI_MADT_ENABLED; x2apic++; } /* Setup interrupt overrides. */ intsrcovr = (void *)x2apic; acpi_table_parse_madt(ACPI_MADT_TYPE_INTERRUPT_OVERRIDE, acpi_set_intr_ovr, acpi_intr_overrides); /* Setup NMI sources. */ nmisrc = (void *)intsrcovr; acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE, acpi_set_nmi_src, acpi_nmi_sources); ASSERT(((void *)nmisrc - (void *)madt) == size); madt->header.length = size; /* * Calling acpi_tb_checksum here is a layering violation, but * introducing a wrapper for such simple usage seems overkill. */ madt->header.checksum -= acpi_tb_checksum(ACPI_CAST_PTR(u8, madt), size); /* Place the new MADT in guest memory space. */ if ( pvh_steal_ram(d, size, 0, GB(4), addr) ) { printk("Unable to find allocate guest RAM for MADT\n"); rc = -ENOMEM; goto out; } /* Mark this region as E820_ACPI. */ if ( pvh_add_mem_range(d, *addr, *addr + size, E820_ACPI) ) printk("Unable to add MADT region to memory map\n"); rc = hvm_copy_to_guest_phys(*addr, madt, size, d->vcpu[0]); if ( rc ) { printk("Unable to copy MADT into guest memory\n"); goto out; } rc = 0; out: xfree(madt); return rc; }
static int __init its_pci_acpi_msi_init(void) { acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR, its_pci_msi_parse_madt, 0); return 0; }
int __init acpi_boot_init(void) { if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) { printk(KERN_ERR PREFIX "Can't find MADT\n"); goto skip_madt; } if (acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE, acpi_parse_lapic_addr_ovr, 0) < 0) printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); if (acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0) < 0) printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); if (acpi_table_parse_madt (ACPI_MADT_TYPE_IO_SAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1) { if (!ia64_platform_is("sn2")) printk(KERN_ERR PREFIX "Error parsing MADT - no IOSAPIC entries\n"); } if (acpi_table_parse_madt (ACPI_MADT_TYPE_INTERRUPT_SOURCE, acpi_parse_plat_int_src, ACPI_MAX_PLATFORM_INTERRUPTS) < 0) printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n"); if (acpi_table_parse_madt (ACPI_MADT_TYPE_INTERRUPT_OVERRIDE, acpi_parse_int_src_ovr, 0) < 0) printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); if (acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE, acpi_parse_nmi_src, 0) < 0) printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); skip_madt: if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt)) printk(KERN_ERR PREFIX "Can't find FADT\n"); #ifdef CONFIG_ACPI_NUMA #ifdef CONFIG_SMP if (srat_num_cpus == 0) { int cpu, i = 1; for (cpu = 0; cpu < smp_boot_data.cpu_count; cpu++) if (smp_boot_data.cpu_phys_id[cpu] != hard_smp_processor_id()) node_cpuid[i++].phys_id = smp_boot_data.cpu_phys_id[cpu]; } #endif build_cpu_to_node_map(); #endif return 0; }