#include <asm/sal.h>
#include <asm/cyclone.h>
+#define BAD_MADT_ENTRY(entry, end) ( \
+ (!entry) || (unsigned long)entry + sizeof(*entry) > end || \
+ ((acpi_table_entry_header *)entry)->length != sizeof(*entry))
#define PREFIX "ACPI: "
void (*pm_idle) (void);
EXPORT_SYMBOL(pm_idle);
void (*pm_power_off) (void);
+EXPORT_SYMBOL(pm_power_off);
unsigned char acpi_kbd_controller_present = 1;
unsigned char acpi_legacy_devices;
+#define MAX_SAPICS 256
+u16 ia64_acpiid_to_sapicid[MAX_SAPICS] =
+ { [0 ... MAX_SAPICS - 1] = -1 };
+EXPORT_SYMBOL(ia64_acpiid_to_sapicid);
+
const char *
acpi_get_sysname (void)
{
static int __init
-acpi_parse_lapic_addr_ovr (acpi_table_entry_header *header)
+acpi_parse_lapic_addr_ovr (
+ acpi_table_entry_header *header, const unsigned long end)
{
struct acpi_table_lapic_addr_ovr *lapic;
lapic = (struct acpi_table_lapic_addr_ovr *) header;
- if (!lapic)
- return -EINVAL;
- acpi_table_print_madt_entry(header);
+ if (BAD_MADT_ENTRY(lapic, end))
+ return -EINVAL;
if (lapic->address) {
- iounmap((void *) ipi_base_addr);
- ipi_base_addr = (unsigned long) ioremap(lapic->address, 0);
+ iounmap(ipi_base_addr);
+ ipi_base_addr = ioremap(lapic->address, 0);
}
return 0;
}
static int __init
-acpi_parse_lsapic (acpi_table_entry_header *header)
+acpi_parse_lsapic (acpi_table_entry_header *header, const unsigned long end)
{
struct acpi_table_lsapic *lsapic;
lsapic = (struct acpi_table_lsapic *) header;
- if (!lsapic)
- return -EINVAL;
- acpi_table_print_madt_entry(header);
-
- printk(KERN_INFO "CPU %d (0x%04x)", total_cpus, (lsapic->id << 8) | lsapic->eid);
+ if (BAD_MADT_ENTRY(lsapic, end))
+ return -EINVAL;
- if (!lsapic->flags.enabled)
- printk(" disabled");
- else {
- printk(" enabled");
+ if (lsapic->flags.enabled) {
#ifdef CONFIG_SMP
smp_boot_data.cpu_phys_id[available_cpus] = (lsapic->id << 8) | lsapic->eid;
- if (hard_smp_processor_id()
- == (unsigned int) smp_boot_data.cpu_phys_id[available_cpus])
- printk(" (BSP)");
#endif
+ ia64_acpiid_to_sapicid[lsapic->acpi_id] = (lsapic->id << 8) | lsapic->eid;
++available_cpus;
}
- printk("\n");
-
total_cpus++;
return 0;
}
static int __init
-acpi_parse_lapic_nmi (acpi_table_entry_header *header)
+acpi_parse_lapic_nmi (acpi_table_entry_header *header, const unsigned long end)
{
struct acpi_table_lapic_nmi *lacpi_nmi;
lacpi_nmi = (struct acpi_table_lapic_nmi*) header;
- if (!lacpi_nmi)
- return -EINVAL;
- acpi_table_print_madt_entry(header);
+ if (BAD_MADT_ENTRY(lacpi_nmi, end))
+ return -EINVAL;
/* TBD: Support lapic_nmi entries */
return 0;
static int __init
-acpi_parse_iosapic (acpi_table_entry_header *header)
+acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end)
{
struct acpi_table_iosapic *iosapic;
iosapic = (struct acpi_table_iosapic *) header;
- if (!iosapic)
- return -EINVAL;
- acpi_table_print_madt_entry(header);
+ if (BAD_MADT_ENTRY(iosapic, end))
+ return -EINVAL;
iosapic_init(iosapic->address, iosapic->global_irq_base);
static int __init
-acpi_parse_plat_int_src (acpi_table_entry_header *header)
+acpi_parse_plat_int_src (
+ acpi_table_entry_header *header, const unsigned long end)
{
struct acpi_table_plat_int_src *plintsrc;
int vector;
plintsrc = (struct acpi_table_plat_int_src *) header;
- if (!plintsrc)
- return -EINVAL;
- acpi_table_print_madt_entry(header);
+ if (BAD_MADT_ENTRY(plintsrc, end))
+ return -EINVAL;
/*
* Get vector assignment for this interrupt, set attributes,
static int __init
-acpi_parse_int_src_ovr (acpi_table_entry_header *header)
+acpi_parse_int_src_ovr (
+ acpi_table_entry_header *header, const unsigned long end)
{
struct acpi_table_int_src_ovr *p;
p = (struct acpi_table_int_src_ovr *) header;
- if (!p)
- return -EINVAL;
- acpi_table_print_madt_entry(header);
+ if (BAD_MADT_ENTRY(p, end))
+ return -EINVAL;
iosapic_override_isa_irq(p->bus_irq, p->global_irq,
(p->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
static int __init
-acpi_parse_nmi_src (acpi_table_entry_header *header)
+acpi_parse_nmi_src (acpi_table_entry_header *header, const unsigned long end)
{
struct acpi_table_nmi_src *nmi_src;
nmi_src = (struct acpi_table_nmi_src*) header;
- if (!nmi_src)
- return -EINVAL;
- acpi_table_print_madt_entry(header);
+ if (BAD_MADT_ENTRY(nmi_src, end))
+ return -EINVAL;
/* TBD: Support nimsrc entries */
return 0;
}
-/* Hook from generic ACPI tables.c */
-void __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+static void __init
+acpi_madt_oem_check (char *oem_id, char *oem_table_id)
{
if (!strncmp(oem_id, "IBM", 3) &&
- (!strncmp(oem_table_id, "SERMOW", 6))){
+ (!strncmp(oem_table_id, "SERMOW", 6))) {
- /* Unfortunatly ITC_DRIFT is not yet part of the
+ /*
+ * Unfortunately ITC_DRIFT is not yet part of the
* official SAL spec, so the ITC_DRIFT bit is not
* set by the BIOS on this hardware.
*/
sal_platform_features |= IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT;
- /*Start cyclone clock*/
- cyclone_setup(0);
+ cyclone_setup();
}
}
/* Get base address of IPI Message Block */
if (acpi_madt->lapic_address)
- ipi_base_addr = (unsigned long) ioremap(acpi_madt->lapic_address, 0);
+ ipi_base_addr = ioremap(acpi_madt->lapic_address, 0);
- printk(KERN_INFO PREFIX "Local APIC address 0x%lx\n", ipi_base_addr);
+ printk(KERN_INFO PREFIX "Local APIC address %p\n", ipi_base_addr);
acpi_madt_oem_check(acpi_madt->header.oem_id,
acpi_madt->header.oem_table_id);
{
int i, j, node_from, node_to;
- /* If there's no SRAT, fix the phys_id */
+ /* If there's no SRAT, fix the phys_id and mark node 0 online */
if (srat_num_cpus == 0) {
+ node_set_online(0);
node_cpuid[0].phys_id = hard_smp_processor_id();
return;
}
#endif /* CONFIG_ACPI_NUMA */
unsigned int
-acpi_register_gsi (u32 gsi, int polarity, int trigger)
+acpi_register_gsi (u32 gsi, int edge_level, int active_high_low)
{
- return acpi_register_irq(gsi, polarity, trigger);
+ if (has_8259 && gsi < 16)
+ return isa_irq_to_vector(gsi);
+
+ return iosapic_register_intr(gsi,
+ (active_high_low == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
+ (edge_level == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
}
EXPORT_SYMBOL(acpi_register_gsi);
if (fadt->iapc_boot_arch & BAF_LEGACY_DEVICES)
acpi_legacy_devices = 1;
- acpi_register_gsi(fadt->sci_int, ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE);
+ acpi_register_gsi(fadt->sci_int, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
return 0;
}
return 0;
}
-/* deprecated in favor of acpi_gsi_to_irq */
-int
-acpi_irq_to_vector (u32 gsi)
-{
- if (has_8259 && gsi < 16)
- return isa_irq_to_vector(gsi);
-
- return gsi_to_vector(gsi);
-}
-
int
acpi_gsi_to_irq (u32 gsi, unsigned int *irq)
{
return 0;
}
-int
-acpi_register_irq (u32 gsi, u32 polarity, u32 trigger)
+#ifdef CONFIG_NUMA
+acpi_status __init
+acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
{
- if (has_8259 && gsi < 16)
- return isa_irq_to_vector(gsi);
+ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+ union acpi_object *obj;
+ struct acpi_table_iosapic *iosapic;
+ unsigned int gsi_base;
+ int node;
- return iosapic_register_intr(gsi,
- (polarity == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
- (trigger == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
-}
-EXPORT_SYMBOL(acpi_register_irq);
+ /* Only care about objects w/ a method that returns the MADT */
+ if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
+ return AE_OK;
+
+ if (!buffer.length || !buffer.pointer)
+ return AE_OK;
+
+ obj = buffer.pointer;
+ if (obj->type != ACPI_TYPE_BUFFER ||
+ obj->buffer.length < sizeof(*iosapic)) {
+ acpi_os_free(buffer.pointer);
+ return AE_OK;
+ }
+
+ iosapic = (struct acpi_table_iosapic *)obj->buffer.pointer;
+
+ if (iosapic->header.type != ACPI_MADT_IOSAPIC) {
+ acpi_os_free(buffer.pointer);
+ return AE_OK;
+ }
+
+ gsi_base = iosapic->global_irq_base;
+
+ acpi_os_free(buffer.pointer);
+ buffer.length = ACPI_ALLOCATE_BUFFER;
+ buffer.pointer = NULL;
+
+ /*
+ * OK, it's an IOSAPIC MADT entry, look for a _PXM method to tell
+ * us which node to associate this with.
+ */
+ if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PXM", NULL, &buffer)))
+ return AE_OK;
+
+ if (!buffer.length || !buffer.pointer)
+ return AE_OK;
+ obj = buffer.pointer;
+
+ if (obj->type != ACPI_TYPE_INTEGER ||
+ obj->integer.value >= MAX_PXM_DOMAINS) {
+ acpi_os_free(buffer.pointer);
+ return AE_OK;
+ }
+
+ node = pxm_to_nid_map[obj->integer.value];
+ acpi_os_free(buffer.pointer);
+
+ if (node >= MAX_NUMNODES || !node_online(node) ||
+ cpus_empty(node_to_cpumask(node)))
+ return AE_OK;
+
+ /* We know a gsi to node mapping! */
+ map_iosapic_to_node(gsi_base, node);
+ return AE_OK;
+}
+#endif /* CONFIG_NUMA */
#endif /* CONFIG_ACPI_BOOT */