Commit 47637d5d authored by Len Brown's avatar Len Brown

ACPI: merge andy-2.6 into lenb-2.6

parents 140f0045 cf899a69
......@@ -124,8 +124,8 @@ module state. Dependency expressions have the following syntax:
<symbol> '!=' <symbol> (3)
'(' <expr> ')' (4)
'!' <expr> (5)
<expr> '||' <expr> (6)
<expr> '&&' <expr> (7)
<expr> '&&' <expr> (6)
<expr> '||' <expr> (7)
Expressions are listed in decreasing order of precedence.
......
......@@ -85,13 +85,10 @@ running once the system is up.
See also Documentation/scsi/ncr53c7xx.txt.
acpi= [HW,ACPI] Advanced Configuration and Power Interface
Format: off
off -- disables both ACPI table parsing and interpreter init
See also Documentation/pm.txt.
acpismp= [IA-32] Early setup parse and use ACPI SMP table.
Format: force
force -- force use of ACPI table parsing and interpreter init
Format: { force | off | ht }
force -- enables ACPI for systems with default off
off -- disabled ACPI for systems with default on
ht -- run only enough ACPI to enable Hyper Threading
See also Documentation/pm.txt.
ad1816= [HW,OSS]
......@@ -619,8 +616,6 @@ running once the system is up.
instruction doesn't work correctly and not to
use it.
noht [SMP,IA-32] Disables P4 Xeon(tm) HyperThreading.
noirqdebug [IA-32] Disables the code which attempts to detect and
disable unhandled interrupt sources.
......
......@@ -846,8 +846,11 @@ config SOFTWARE_SUSPEND
source "drivers/acpi/Kconfig"
menu "APM (Advanced Power Management) BIOS Support"
depends on PM
config APM
tristate "Advanced Power Management BIOS support"
tristate "APM (Advanced Power Management) BIOS support"
depends on PM
---help---
APM is a BIOS specification for saving power using several different
......@@ -991,6 +994,8 @@ config APM_REAL_MODE_POWER_OFF
a work-around for a number of buggy BIOSes. Switch this option on if
your computer crashes instead of powering off properly.
endmenu
source "arch/i386/kernel/cpu/cpufreq/Kconfig"
endmenu
......
......@@ -11,7 +11,7 @@ obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
obj-y += cpu/
obj-y += timers/
obj-$(CONFIG_ACPI) += acpi/
obj-$(CONFIG_ACPI_BOOT) += acpi/
obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o
obj-$(CONFIG_MCA) += mca.o
obj-$(CONFIG_X86_MSR) += msr.o
......
obj-$(CONFIG_ACPI_HT_ONLY) := acpitable.o
obj-$(CONFIG_ACPI_BOOT) := boot.o
obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o
/*
* acpitable.c - IA32-specific ACPI boot-time initialization (Revision: 1)
*
* Copyright (C) 1999 Andrew Henroid
* Copyright (C) 2001 Richard Schaal
* Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
* Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
* Copyright (C) 2001 Arjan van de Ven <arjanv@redhat.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* $Id: acpitable.c,v 1.7 2001/11/04 12:21:18 fenrus Exp $
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <asm/mpspec.h>
#include <asm/io.h>
#include <asm/apic.h>
#include <asm/apicdef.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include "acpitable.h"
static acpi_table_handler acpi_boot_ops[ACPI_TABLE_COUNT];
int acpi_lapic;
static unsigned char __init
acpi_checksum(void *buffer, int length)
{
int i;
unsigned char *bytebuffer;
unsigned char sum = 0;
if (!buffer || length <= 0)
return 0;
bytebuffer = (unsigned char *) buffer;
for (i = 0; i < length; i++)
sum += *(bytebuffer++);
return sum;
}
static void __init
acpi_print_table_header(acpi_table_header * header)
{
if (!header)
return;
printk(KERN_INFO "ACPI table found: %.4s v%d [%.6s %.8s %d.%d]\n",
header->signature, header->revision, header->oem_id,
header->oem_table_id, header->oem_revision >> 16,
header->oem_revision & 0xffff);
return;
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_scan_memory_for_rsdp
*
* PARAMETERS: address - Starting pointer for search
* length - Maximum length to search
*
* RETURN: Pointer to the RSDP if found and valid, otherwise NULL.
*
* DESCRIPTION: Search a block of memory for the RSDP signature
*
******************************************************************************/
static void *__init
acpi_tb_scan_memory_for_rsdp(void *address, int length)
{
u32 offset;
if (length <= 0)
return NULL;
/* Search from given start addr for the requested length */
offset = 0;
while (offset < length) {
/* The signature must match and the checksum must be correct */
if (strncmp(address, RSDP_SIG, sizeof(RSDP_SIG) - 1) == 0 &&
acpi_checksum(address, RSDP_CHECKSUM_LENGTH) == 0) {
/* If so, we have found the RSDP */
printk(KERN_INFO "ACPI: RSDP located at physical address %p\n",
address);
return address;
}
offset += RSDP_SCAN_STEP;
address += RSDP_SCAN_STEP;
}
/* Searched entire block, no RSDP was found */
printk(KERN_INFO "ACPI: Searched entire block, no RSDP was found.\n");
return NULL;
}
/*******************************************************************************
*
* FUNCTION: acpi_find_root_pointer
*
* PARAMETERS: none
*
* RETURN: physical address of the RSDP
*
* DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor
* pointer structure. If it is found, set *RSDP to point to it.
*
* NOTE: The RSDP must be either in the first 1_k of the Extended
* BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section
* 5.2.2; assertion #421).
*
******************************************************************************/
static struct acpi_table_rsdp * __init
acpi_find_root_pointer(void)
{
struct acpi_table_rsdp * rsdp;
/*
* Physical address is given
*/
/*
* Region 1) Search EBDA (low memory) paragraphs
*/
rsdp = acpi_tb_scan_memory_for_rsdp(__va(LO_RSDP_WINDOW_BASE),
LO_RSDP_WINDOW_SIZE);
if (rsdp)
return rsdp;
/*
* Region 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
*/
rsdp = acpi_tb_scan_memory_for_rsdp(__va(HI_RSDP_WINDOW_BASE),
HI_RSDP_WINDOW_SIZE);
if (rsdp)
return rsdp;
printk(KERN_ERR "ACPI: System description tables not found\n");
return NULL;
}
/*
* Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
* to map the target physical address. The problem is that set_fixmap()
* provides a single page, and it is possible that the page is not
* sufficient.
* By using this area, we can map up to MAX_IO_APICS pages temporarily,
* i.e. until the next __va_range() call.
*
* Important Safety Note: The fixed I/O APIC page numbers are *subtracted*
* from the fixed base. That's why we start at FIX_IO_APIC_BASE_END and
* count idx down while incrementing the phys address.
*/
static __init char *
__va_range(unsigned long phys, unsigned long size)
{
unsigned long base, offset, mapped_size;
int idx;
offset = phys & (PAGE_SIZE - 1);
mapped_size = PAGE_SIZE - offset;
set_fixmap(FIX_IO_APIC_BASE_END, phys);
base = fix_to_virt(FIX_IO_APIC_BASE_END);
dprintk("__va_range(0x%lx, 0x%lx): idx=%d mapped at %lx\n", phys, size,
FIX_IO_APIC_BASE_END, base);
/*
* Most cases can be covered by the below.
*/
idx = FIX_IO_APIC_BASE_END;
while (mapped_size < size) {
if (--idx < FIX_IO_APIC_BASE_0)
return 0; /* cannot handle this */
phys += PAGE_SIZE;
set_fixmap(idx, phys);
mapped_size += PAGE_SIZE;
}
return ((unsigned char *) base + offset);
}
static int __init acpi_tables_init(void)
{
int result = -ENODEV;
acpi_table_header *header = NULL;
struct acpi_table_rsdp *rsdp = NULL;
struct acpi_table_rsdt *rsdt = NULL;
struct acpi_table_rsdt saved_rsdt;
int tables = 0;
int type = 0;
int i = 0;
rsdp = (struct acpi_table_rsdp *) acpi_find_root_pointer();
if (!rsdp)
return -ENODEV;
printk(KERN_INFO "%.8s v%d [%.6s]\n", rsdp->signature, rsdp->revision,
rsdp->oem_id);
if (strncmp(rsdp->signature, RSDP_SIG,strlen(RSDP_SIG))) {
printk(KERN_WARNING "RSDP table signature incorrect\n");
return -EINVAL;
}
rsdt = (struct acpi_table_rsdt *)
__va_range(rsdp->rsdt_address, sizeof(struct acpi_table_rsdt));
if (!rsdt) {
printk(KERN_WARNING "ACPI: Invalid root system description tables (RSDT)\n");
return -ENODEV;
}
header = & rsdt->header;
acpi_print_table_header(header);
if (strncmp(header->signature, RSDT_SIG, strlen(RSDT_SIG))) {
printk(KERN_WARNING "ACPI: RSDT signature incorrect\n");
return -ENODEV;
}
/*
* The number of tables is computed by taking the
* size of all entries (header size minus total
* size of RSDT) divided by the size of each entry
* (4-byte table pointers).
*/
tables = (header->length - sizeof(acpi_table_header)) / 4;
memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt));
if (saved_rsdt.header.length > sizeof(saved_rsdt)) {
printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n", saved_rsdt.header.length);
return -ENODEV;
}
for (i = 0; i < tables; i++) {
/* Map in header, then map in full table length. */
header = (acpi_table_header *)
__va_range(saved_rsdt.entry[i],
sizeof(acpi_table_header));
if (!header)
break;
header = (acpi_table_header *)
__va_range(saved_rsdt.entry[i], header->length);
if (!header)
break;
acpi_print_table_header(header);
if (acpi_checksum(header,header->length)) {
printk(KERN_WARNING "ACPI %s has invalid checksum\n",
acpi_table_signatures[i]);
continue;
}
for (type = 0; type < ACPI_TABLE_COUNT; type++)
if (!strncmp((char *) &header->signature,
acpi_table_signatures[type],strlen(acpi_table_signatures[type])))
break;
if (type >= ACPI_TABLE_COUNT) {
printk(KERN_WARNING "ACPI: Unsupported table %.4s\n",
header->signature);
continue;
}
if (!acpi_boot_ops[type])
continue;
result = acpi_boot_ops[type] (header,
(unsigned long) saved_rsdt.
entry[i]);
}
return result;
}
static int total_cpus __initdata = 0;
int have_acpi_tables;
extern void __init MP_processor_info(struct mpc_config_processor *);
static void __init
acpi_parse_lapic(struct acpi_table_lapic *local_apic)
{
struct mpc_config_processor proc_entry;
int ix = 0;
if (!local_apic)
return;
printk(KERN_INFO "LAPIC (acpi_id[0x%04x] id[0x%x] enabled[%d])\n",
local_apic->acpi_id, local_apic->id, local_apic->flags.enabled);
printk(KERN_INFO "CPU %d (0x%02x00)", total_cpus, local_apic->id);
if (local_apic->flags.enabled) {
printk(" enabled");
ix = local_apic->id;
if (ix >= MAX_APICS) {
printk(KERN_WARNING
"Processor #%d INVALID - (Max ID: %d).\n", ix,
MAX_APICS);
return;
}
/*
* Fill in the info we want to save. Not concerned about
* the processor ID. Processor features aren't present in
* the table.
*/
proc_entry.mpc_type = MP_PROCESSOR;
proc_entry.mpc_apicid = local_apic->id;
proc_entry.mpc_cpuflag = CPU_ENABLED;
if (proc_entry.mpc_apicid == boot_cpu_physical_apicid) {
printk(" (BSP)");
proc_entry.mpc_cpuflag |= CPU_BOOTPROCESSOR;
}
proc_entry.mpc_cpufeature =
(boot_cpu_data.x86 << 8) |
(boot_cpu_data.x86_model << 4) |
boot_cpu_data.x86_mask;
proc_entry.mpc_featureflag = boot_cpu_data.x86_capability[0];
proc_entry.mpc_reserved[0] = 0;
proc_entry.mpc_reserved[1] = 0;
proc_entry.mpc_apicver = 0x10; /* integrated APIC */
MP_processor_info(&proc_entry);
} else {
printk(" disabled");
}
printk("\n");
total_cpus++;
return;
}
static void __init
acpi_parse_ioapic(struct acpi_table_ioapic *ioapic)
{
if (!ioapic)
return;
printk(KERN_INFO
"IOAPIC (id[0x%x] address[0x%x] global_irq_base[0x%x])\n",
ioapic->id, ioapic->address, ioapic->global_irq_base);
if (nr_ioapics >= MAX_IO_APICS) {
printk(KERN_WARNING
"Max # of I/O APICs (%d) exceeded (found %d).\n",
MAX_IO_APICS, nr_ioapics);
/* panic("Recompile kernel with bigger MAX_IO_APICS!\n"); */
}
}
/* Interrupt source overrides inform the machine about exceptions
to the normal "PIC" mode interrupt routing */
static void __init
acpi_parse_int_src_ovr(struct acpi_table_int_src_ovr *intsrc)
{
if (!intsrc)
return;
printk(KERN_INFO
"INT_SRC_OVR (bus[%d] irq[0x%x] global_irq[0x%x] polarity[0x%x] trigger[0x%x])\n",
intsrc->bus, intsrc->bus_irq, intsrc->global_irq,
intsrc->flags.polarity, intsrc->flags.trigger);
}
/*
* At this point, we look at the interrupt assignment entries in the MPS
* table.
*/
static void __init acpi_parse_nmi_src(struct acpi_table_nmi_src *nmisrc)
{
if (!nmisrc)
return;
printk(KERN_INFO
"NMI_SRC (polarity[0x%x] trigger[0x%x] global_irq[0x%x])\n",
nmisrc->flags.polarity, nmisrc->flags.trigger,
nmisrc->global_irq);
}
static void __init
acpi_parse_lapic_nmi(struct acpi_table_lapic_nmi *localnmi)
{
if (!localnmi)
return;
printk(KERN_INFO
"LAPIC_NMI (acpi_id[0x%04x] polarity[0x%x] trigger[0x%x] lint[0x%x])\n",
localnmi->acpi_id, localnmi->flags.polarity,
localnmi->flags.trigger, localnmi->lint);
}
static void __init
acpi_parse_lapic_addr_ovr(struct acpi_table_lapic_addr_ovr *lapic_addr_ovr)
{
if (!lapic_addr_ovr)
return;
printk(KERN_INFO "LAPIC_ADDR_OVR (address[0x%lx])\n",
(unsigned long) lapic_addr_ovr->address);
}
static void __init
acpi_parse_plat_int_src(struct acpi_table_plat_int_src *plintsrc)
{
if (!plintsrc)
return;
printk(KERN_INFO
"PLAT_INT_SRC (polarity[0x%x] trigger[0x%x] type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n",
plintsrc->flags.polarity, plintsrc->flags.trigger,
plintsrc->type, plintsrc->id, plintsrc->eid,
plintsrc->iosapic_vector, plintsrc->global_irq);
}
static int __init
acpi_parse_madt(acpi_table_header * header, unsigned long phys)
{
struct acpi_table_madt *madt;
acpi_madt_entry_header *entry_header;
int table_size;
madt = (struct acpi_table_madt *) __va_range(phys, header->length);
if (!madt)
return -EINVAL;
table_size = (int) (header->length - sizeof(*madt));
entry_header =
(acpi_madt_entry_header *) ((void *) madt + sizeof(*madt));
while (entry_header && (table_size > 0)) {
switch (entry_header->type) {
case ACPI_MADT_LAPIC:
acpi_parse_lapic((struct acpi_table_lapic *)
entry_header);
break;
case ACPI_MADT_IOAPIC:
acpi_parse_ioapic((struct acpi_table_ioapic *)
entry_header);
break;
case ACPI_MADT_INT_SRC_OVR:
acpi_parse_int_src_ovr((struct acpi_table_int_src_ovr *)
entry_header);
break;
case ACPI_MADT_NMI_SRC:
acpi_parse_nmi_src((struct acpi_table_nmi_src *)
entry_header);
break;
case ACPI_MADT_LAPIC_NMI:
acpi_parse_lapic_nmi((struct acpi_table_lapic_nmi *)
entry_header);
break;
case ACPI_MADT_LAPIC_ADDR_OVR:
acpi_parse_lapic_addr_ovr((struct
acpi_table_lapic_addr_ovr *)
entry_header);
break;
case ACPI_MADT_PLAT_INT_SRC:
acpi_parse_plat_int_src((struct acpi_table_plat_int_src
*) entry_header);
break;
default:
printk(KERN_WARNING
"Unsupported MADT entry type 0x%x\n",
entry_header->type);
break;
}
table_size -= entry_header->length;
entry_header =
(acpi_madt_entry_header *) ((void *) entry_header +
entry_header->length);
}
if (!total_cpus) {
printk("ACPI: No Processors found in the APCI table.\n");
return -EINVAL;
}
printk(KERN_INFO "%d CPUs total\n", total_cpus);
if (madt->lapic_address)
mp_lapic_addr = madt->lapic_address;
else
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
printk(KERN_INFO "Local APIC address %x\n", madt->lapic_address);
return 0;
}
/*
* Configure the processor info using MADT in the ACPI tables. If we fail to
* configure that, then we use the MPS tables.
*/
void __init
acpi_boot_init(void)
{
memset(&acpi_boot_ops, 0, sizeof(acpi_boot_ops));
acpi_boot_ops[ACPI_APIC] = acpi_parse_madt;
/*
* Only do this when requested, either because of CPU/Bios type or from the command line
*/
if (!acpi_tables_init())
acpi_lapic = 1;
}
/*
* acpitable.c - IA32-specific ACPI boot-time initialization (Revision: 1)
*
* Copyright (C) 1999 Andrew Henroid
* Copyright (C) 2001 Richard Schaal
* Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
* Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
* Copyright (C) 2001 Arjan van de Ven <arjanv@redhat.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* $Id: acpitable.h,v 1.3 2001/11/03 22:41:34 fenrus Exp $
*/
/*
* The following codes are cut&pasted from drivers/acpi. Part of the code
* there can be not updated or delivered yet.
* To avoid conflicts when CONFIG_ACPI is defined, the following codes are
* modified so that they are self-contained in this file.
* -- jun
*/
#ifndef _HEADER_ACPITABLE_H_
#define _HEADER_ACPITABLE_H_
#define dprintk printk
typedef unsigned int ACPI_TBLPTR;
typedef struct { /* ACPI common table header */
char signature[4]; /* identifies type of table */
u32 length; /* length of table,
in bytes, * including header */
u8 revision; /* specification minor version # */
u8 checksum; /* to make sum of entire table == 0 */
char oem_id[6]; /* OEM identification */
char oem_table_id[8]; /* OEM table identification */
u32 oem_revision; /* OEM revision number */
char asl_compiler_id[4]; /* ASL compiler vendor ID */
u32 asl_compiler_revision; /* ASL compiler revision number */
} acpi_table_header __attribute__ ((packed));;
enum {
ACPI_APIC = 0,
ACPI_BOOT,
ACPI_DBGP,
ACPI_DSDT,
ACPI_ECDT,
ACPI_ETDT,
ACPI_FACP,
ACPI_FACS,
ACPI_OEMX,
ACPI_PSDT,
ACPI_SBST,
ACPI_SLIT,
ACPI_SPCR,
ACPI_SRAT,
ACPI_SSDT,
ACPI_SPMI,
ACPI_XSDT,
ACPI_TABLE_COUNT
};
static char *acpi_table_signatures[ACPI_TABLE_COUNT] = {
"APIC",
"BOOT",
"DBGP",
"DSDT",
"ECDT",
"ETDT",
"FACP",
"FACS",
"OEM",
"PSDT",
"SBST",
"SLIT",
"SPCR",
"SRAT",
"SSDT",
"SPMI",
"XSDT"
};
struct acpi_table_madt {
acpi_table_header header;
u32 lapic_address;
struct {
u32 pcat_compat:1;
u32 reserved:31;
} flags __attribute__ ((packed));
} __attribute__ ((packed));;
enum {
ACPI_MADT_LAPIC = 0,
ACPI_MADT_IOAPIC,
ACPI_MADT_INT_SRC_OVR,
ACPI_MADT_NMI_SRC,
ACPI_MADT_LAPIC_NMI,
ACPI_MADT_LAPIC_ADDR_OVR,
ACPI_MADT_IOSAPIC,
ACPI_MADT_LSAPIC,
ACPI_MADT_PLAT_INT_SRC,
ACPI_MADT_ENTRY_COUNT
};
#define RSDP_SIG "RSD PTR "
#define RSDT_SIG "RSDT"
#define ACPI_DEBUG_PRINT(pl)
#define ACPI_MEMORY_MODE 0x01
#define ACPI_LOGICAL_ADDRESSING 0x00
#define ACPI_PHYSICAL_ADDRESSING 0x01
#define LO_RSDP_WINDOW_BASE 0 /* Physical Address */
#define HI_RSDP_WINDOW_BASE 0xE0000 /* Physical Address */
#define LO_RSDP_WINDOW_SIZE 0x400
#define HI_RSDP_WINDOW_SIZE 0x20000
#define RSDP_SCAN_STEP 16
#define RSDP_CHECKSUM_LENGTH 20
typedef int (*acpi_table_handler) (acpi_table_header * header, unsigned long);
struct acpi_table_rsdp {
char signature[8];
u8 checksum;
char oem_id[6];
u8 revision;
u32 rsdt_address;
} __attribute__ ((packed));
struct acpi_table_rsdt {
acpi_table_header header;
u32 entry[ACPI_TABLE_COUNT];
} __attribute__ ((packed));
typedef struct {
u8 type;
u8 length;
} acpi_madt_entry_header __attribute__ ((packed));
typedef struct {
u16 polarity:2;
u16 trigger:2;
u16 reserved:12;
} acpi_madt_int_flags __attribute__ ((packed));
struct acpi_table_lapic {
acpi_madt_entry_header header;
u8 acpi_id;
u8 id;
struct {
u32 enabled:1;
u32 reserved:31;
} flags __attribute__ ((packed));
} __attribute__ ((packed));
struct acpi_table_ioapic {
acpi_madt_entry_header header;
u8 id;
u8 reserved;
u32 address;
u32 global_irq_base;
} __attribute__ ((packed));
struct acpi_table_int_src_ovr {
acpi_madt_entry_header header;
u8 bus;
u8 bus_irq;
u32 global_irq;
acpi_madt_int_flags flags;
} __attribute__ ((packed));
struct acpi_table_nmi_src {
acpi_madt_entry_header header;
acpi_madt_int_flags flags;
u32 global_irq;
} __attribute__ ((packed));
struct acpi_table_lapic_nmi {
acpi_madt_entry_header header;
u8 acpi_id;
acpi_madt_int_flags flags;
u8 lint;
} __attribute__ ((packed));
struct acpi_table_lapic_addr_ovr {
acpi_madt_entry_header header;
u8 reserved[2];
u64 address;
} __attribute__ ((packed));
struct acpi_table_iosapic {
acpi_madt_entry_header header;
u8 id;
u8 reserved;
u32 global_irq_base;
u64 address;
} __attribute__ ((packed));
struct acpi_table_lsapic {
acpi_madt_entry_header header;
u8 acpi_id;
u8 id;
u8 eid;
u8 reserved[3];
struct {
u32 enabled:1;
u32 reserved:31;
} flags;
} __attribute__ ((packed));
struct acpi_table_plat_int_src {
acpi_madt_entry_header header;
acpi_madt_int_flags flags;
u8 type;
u8 id;
u8 eid;
u8 iosapic_vector;
u32 global_irq;
u32 reserved;
} __attribute__ ((packed));
/*
* ACPI Table Descriptor. One per ACPI table
*/
typedef struct acpi_table_desc {
struct acpi_table_desc *prev;
struct acpi_table_desc *next;
struct acpi_table_desc *installed_desc;
acpi_table_header *pointer;
void *base_pointer;
u8 *aml_pointer;
u64 physical_address;
u32 aml_length;
u32 length;
u32 count;
u16 table_id;
u8 type;
u8 allocation;
u8 loaded_into_namespace;
} acpi_table_desc __attribute__ ((packed));;
#endif
......@@ -39,6 +39,7 @@
#define PREFIX "ACPI: "
extern int acpi_disabled;
extern int acpi_ht;
/* --------------------------------------------------------------------------
Boot-time Configuration
......@@ -157,7 +158,7 @@ acpi_parse_lapic_addr_ovr (
return 0;
}
#ifndef CONFIG_ACPI_HT_ONLY
#ifdef CONFIG_ACPI
static int __init
acpi_parse_lapic_nmi (
......@@ -177,7 +178,7 @@ acpi_parse_lapic_nmi (
return 0;
}
#endif /*CONFIG_ACPI_HT_ONLY*/
#endif /*CONFIG_ACPI*/
#endif /*CONFIG_X86_LOCAL_APIC*/
......@@ -185,7 +186,7 @@ acpi_parse_lapic_nmi (
int acpi_ioapic;
#ifndef CONFIG_ACPI_HT_ONLY
#ifdef CONFIG_ACPI
static int __init
acpi_parse_ioapic (
......@@ -247,7 +248,7 @@ acpi_parse_nmi_src (
return 0;
}
#endif /*!CONFIG_ACPI_HT_ONLY*/
#endif /*CONFIG_ACPI*/
#endif /*CONFIG_X86_IO_APIC*/
......@@ -289,12 +290,34 @@ acpi_find_rsdp (void)
return rsdp_phys;
}
/*
* 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() acpi_disabled = 1;
* 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).
......@@ -308,14 +331,14 @@ acpi_boot_init (void)
if (result)
return result;
#ifdef CONFIG_ACPI
result = acpi_blacklisted();
if (result) {
printk(KERN_WARNING PREFIX "BIOS listed in blacklist, disabling ACPI support\n");
acpi_disabled = 1;
return result;
}
else
printk(KERN_NOTICE PREFIX "BIOS not listed in blacklist\n");
#endif
#ifdef CONFIG_X86_LOCAL_APIC
......@@ -366,27 +389,37 @@ acpi_boot_init (void)
return result;
}
#ifndef CONFIG_ACPI_HT_ONLY
#ifdef CONFIG_ACPI
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;
}
#endif /*!CONFIG_ACPI_HT_ONLY*/
#endif /*CONFIG_ACPI*/
acpi_lapic = 1;
#endif /*CONFIG_X86_LOCAL_APIC*/
#ifdef CONFIG_X86_IO_APIC
#ifndef CONFIG_ACPI_HT_ONLY
#ifdef CONFIG_ACPI
/*
* 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) {
return 1;
}
result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic);
if (!result) {
printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
......@@ -418,7 +451,7 @@ acpi_boot_init (void)
acpi_ioapic = 1;
#endif /*!CONFIG_ACPI_HT_ONLY*/
#endif /*CONFIG_ACPI*/
#endif /*CONFIG_X86_IO_APIC*/
#ifdef CONFIG_X86_LOCAL_APIC
......
......@@ -11,7 +11,6 @@
#include "cpu.h"
static int disable_P4_HT __initdata = 0;
extern int trap_init_f00f_bug(void);
#ifdef CONFIG_X86_INTEL_USERCOPY
......@@ -68,13 +67,6 @@ int __init ppro_with_ram_bug(void)
return 0;
}
static int __init P4_disable_ht(char *s)
{
disable_P4_HT = 1;
return 1;
}
__setup("noht", P4_disable_ht);
#define LVL_1_INST 1
#define LVL_1_DATA 2
#define LVL_2 3
......@@ -281,7 +273,7 @@ static void __init init_intel(struct cpuinfo_x86 *c)
strcpy(c->x86_model_id, p);
#ifdef CONFIG_X86_HT
if (cpu_has(c, X86_FEATURE_HT) && !disable_P4_HT) {
if (cpu_has(c, X86_FEATURE_HT)) {
extern int phys_proc_id[NR_CPUS];
u32 eax, ebx, ecx, edx;
......@@ -329,8 +321,6 @@ static void __init init_intel(struct cpuinfo_x86 *c)
}
too_many_siblings:
if (disable_P4_HT)
clear_bit(X86_FEATURE_HT, c->x86_capability);
#endif
/* Work around errata */
......
......@@ -129,10 +129,10 @@ static int __init dmi_iterate(void (*decode)(struct dmi_header *))
* the SMBIOS version, which we don't know at this point.
*/
if(buf[14]!=0)
dmi_printk((KERN_INFO "DMI %d.%d present.\n",
buf[14]>>4, buf[14]&0x0F));
printk(KERN_INFO "DMI %d.%d present.\n",
buf[14]>>4, buf[14]&0x0F);
else
dmi_printk((KERN_INFO "DMI present.\n"));
printk(KERN_INFO "DMI present.\n");
dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n",
num, len));
dmi_printk((KERN_INFO "DMI table at 0x%08X.\n",
......@@ -162,6 +162,20 @@ enum
static char *dmi_ident[DMI_STRING_MAX];
/* print some information suitable for a blacklist entry. */
void dmi_dump_system(void)
{
printk("DMI: BIOS: %.40s, %.40s, %.40s\n",
dmi_ident[DMI_BIOS_VENDOR], dmi_ident[DMI_BIOS_VERSION],
dmi_ident[DMI_BIOS_DATE]);
printk("DMI: System: %.40s, %.40s, %.40s\n",
dmi_ident[DMI_SYS_VENDOR], dmi_ident[DMI_PRODUCT_NAME],
dmi_ident[DMI_PRODUCT_VERSION]);
printk("DMI: Board: %.40s, %.40s, %.40s\n",
dmi_ident[DMI_BOARD_VENDOR], dmi_ident[DMI_BOARD_NAME],
dmi_ident[DMI_BOARD_VERSION]);
}
/*
* Save a DMI string
*/
......@@ -341,6 +355,31 @@ static __init int fix_broken_hp_bios_irq9(struct dmi_blacklist *d)
return 0;
}
/* Some BIOS / motherboard combinations require the APIC to be enabled
* even on UP systems or will exhibit instability. */
static int __init abit_apic_required(struct dmi_blacklist *d)
{
#ifdef CONFIG_X86_LOCAL_APIC
#ifndef CONFIG_SMP
extern int enable_apic_up;
extern int dont_enable_local_apic;
extern int skip_ioapic_setup;
if (!enable_apic_up) {
printk(KERN_WARNING " *** %s: APIC forcibly enabled to avoid "
"RANDOM CRASHES.\n", d->ident);
printk(KERN_WARNING " *** PLEASE add 'apic' to the kernel "
"commandline AND enable it in the BIOS! ***\n");
dont_enable_local_apic=0;
enable_apic_up=1;
skip_ioapic_setup=0;
}
#endif
#endif
return 0;
}
/*
* Check for clue free BIOS implementations who use
* the following QA technique
......@@ -415,6 +454,17 @@ static __init int broken_pirq(struct dmi_blacklist *d)
return 0;
}
/*
* ASUS K7V-RM has broken ACPI table defining sleep modes
*/
static __init int broken_acpi_Sx(struct dmi_blacklist *d)
{
printk(KERN_WARNING "Detected ASUS mainboard with broken ACPI sleep table\n");
dmi_broken |= BROKEN_ACPI_Sx;
return 0;
}
/*
* Toshiba keyboard likes to repeat keys when they are not repeated.
*/
......@@ -489,6 +539,63 @@ static __init int print_if_true(struct dmi_blacklist *d)
return 0;
}
extern int acpi_disabled, acpi_force;
extern int enable_apic_up, skip_ioapic_setup;
static __init __attribute__((unused)) int acpi_disable(struct dmi_blacklist *d)
{
if (!acpi_force) {
printk(KERN_NOTICE "%s detected: acpi off\n",d->ident);
acpi_disabled = 1;
} else {
printk(KERN_NOTICE
"Warning: DMI blacklist says broken, but acpi forced\n");
}
return 0;
}
#ifdef CONFIG_ACPI_BOOT
extern int acpi_ht;
/*
* Limit ACPI to CPU enumeration for HT
*/
static __init __attribute__((unused)) int force_acpi_ht(struct dmi_blacklist *d)
{
if (!acpi_force) {
printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident);
acpi_disabled = 1;
acpi_ht = 1;
} else {
printk(KERN_NOTICE
"Warning: acpi=force overrules DMI blacklist: acpi=ht\n");
}
return 0;
}
#endif
#ifdef CONFIG_ACPI_PCI
static __init int disable_acpi_pci(struct dmi_blacklist *d)
{
extern __init void pci_disable_acpi(void) ;
printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", d->ident);
pci_disable_acpi();
return 0;
}
#endif
#ifndef CONFIG_SMP
static __init int force_apic(struct dmi_blacklist *d)
{
printk(KERN_NOTICE "%s detected: force APIC\n", d->ident);
enable_apic_up = 1;
skip_ioapic_setup = 0;
return 0;
}
#endif
/*
* Process the DMI blacklists
*/
......@@ -551,6 +658,11 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={
MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"),
NO_MATCH, NO_MATCH
} },
{ apm_is_horked, "ABIT KX7-333[R]", { /* APM blows on shutdown */
MATCH(DMI_BOARD_VENDOR, "ABIT"),
MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"),
NO_MATCH, NO_MATCH,
} },
{ apm_is_horked, "Trigem Delhi3", { /* APM crashes */
MATCH(DMI_SYS_VENDOR, "TriGem Computer, Inc"),
MATCH(DMI_PRODUCT_NAME, "Delhi3"),
......@@ -699,6 +811,12 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={
NO_MATCH, NO_MATCH
} },
{ abit_apic_required, "ABIT KX7-333[R]", { /* Will crash randomly w/o */
MATCH(DMI_BOARD_VENDOR, "ABIT"),
MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"),
NO_MATCH, NO_MATCH,
} },
/* Problem Intel 440GX bioses */
{ broken_pirq, "SABR1 Bios", { /* Bad $PIR */
......@@ -734,6 +852,12 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={
NO_MATCH, NO_MATCH, NO_MATCH
} },
{ broken_acpi_Sx, "ASUS K7V-RM", { /* Bad ACPI Sx table */
MATCH(DMI_BIOS_VERSION,"ASUS K7V-RM ACPI BIOS Revision 1003A"),
MATCH(DMI_BOARD_NAME, "<K7V-RM>"),
NO_MATCH, NO_MATCH
} },
{ broken_toshiba_keyboard, "Toshiba Satellite 4030cdt", { /* Keyboard generates spurious repeats */
MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
NO_MATCH, NO_MATCH, NO_MATCH
......@@ -792,6 +916,122 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={
NO_MATCH, NO_MATCH,
} },
/*
* Boxes that need ACPI disabled
*/
{ acpi_disable, "IBM Thinkpad", {
MATCH(DMI_BOARD_VENDOR, "IBM"),
MATCH(DMI_BOARD_NAME, "2629H1G"),
NO_MATCH, NO_MATCH }},
#ifdef CONFIG_ACPI_BOOT
/*
* Boxes that need acpi=ht
*/
{ force_acpi_ht, "FSC Primergy T850", {
MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
NO_MATCH, NO_MATCH }},
{ force_acpi_ht, "DELL GX240", {
MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
NO_MATCH, NO_MATCH }},
{ force_acpi_ht, "HP VISUALIZE NT Workstation", {
MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
NO_MATCH, NO_MATCH }},
{ force_acpi_ht, "Compaq ProLiant DL380 G2", {
MATCH(DMI_SYS_VENDOR, "Compaq"),
MATCH(DMI_PRODUCT_NAME, "ProLiant DL380 G2"),
NO_MATCH, NO_MATCH }},
{ force_acpi_ht, "Compaq ProLiant ML530 G2", {
MATCH(DMI_SYS_VENDOR, "Compaq"),
MATCH(DMI_PRODUCT_NAME, "ProLiant ML530 G2"),
NO_MATCH, NO_MATCH }},
{ force_acpi_ht, "Compaq ProLiant ML350 G3", {
MATCH(DMI_SYS_VENDOR, "Compaq"),
MATCH(DMI_PRODUCT_NAME, "ProLiant ML350 G3"),
NO_MATCH, NO_MATCH }},
{ force_acpi_ht, "Compaq Workstation W8000", {
MATCH(DMI_SYS_VENDOR, "Compaq"),
MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
NO_MATCH, NO_MATCH }},
{ force_acpi_ht, "ASUS P4B266", {
MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
MATCH(DMI_BOARD_NAME, "P4B266"),
NO_MATCH, NO_MATCH }},
{ force_acpi_ht, "ASUS P2B-DS", {
MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
MATCH(DMI_BOARD_NAME, "P2B-DS"),
NO_MATCH, NO_MATCH }},
{ force_acpi_ht, "ASUS CUR-DLS", {
MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
MATCH(DMI_BOARD_NAME, "CUR-DLS"),
NO_MATCH, NO_MATCH }},
{ force_acpi_ht, "ASUS A7V", {
MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
MATCH(DMI_BOARD_NAME, "<A7V>"),
MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1011"), NO_MATCH }},
{ force_acpi_ht, "ABIT i440BX-W83977", {
MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
NO_MATCH, NO_MATCH }},
{ force_acpi_ht, "IBM Bladecenter", {
MATCH(DMI_BOARD_VENDOR, "IBM"),
MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
NO_MATCH, NO_MATCH }},
{ force_acpi_ht, "IBM eServer xSeries 360", {
MATCH(DMI_BOARD_VENDOR, "IBM"),
MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
NO_MATCH, NO_MATCH }},
{ force_acpi_ht, "IBM eserver xSeries 330", {
MATCH(DMI_BOARD_VENDOR, "IBM"),
MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
NO_MATCH, NO_MATCH }},
{ force_acpi_ht, "IBM eserver xSeries 440", {
MATCH(DMI_BOARD_VENDOR, "IBM"),
MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
NO_MATCH, NO_MATCH }},
#endif // CONFIG_ACPI_BOOT
#ifdef CONFIG_ACPI_PCI
/*
* Boxes that need ACPI PCI IRQ routing disabled
*/
{ disable_acpi_pci, "ASUS A7V", {
MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
MATCH(DMI_BOARD_NAME, "<A7V>"),
MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"), NO_MATCH }},
#endif
#ifndef CONFIG_SMP
/*
* Enable APIC on UP kernels.
*/
{ force_apic, "Supermicro P4DC6", {
MATCH(DMI_BOARD_VENDOR, "Supermicro"),
MATCH(DMI_BOARD_NAME, "P4DC6"),
NO_MATCH, NO_MATCH } },
#endif
{ NULL, }
};
......@@ -801,11 +1041,31 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={
* returns 1 or we hit the end.
*/
#define ACPI_BLACKLIST_CUTOFF_YEAR 2001
static __init void dmi_check_blacklist(void)
{
struct dmi_blacklist *d;
int i;
if (dmi_ident[DMI_BIOS_DATE]) {
char *s = strrchr(dmi_ident[DMI_BIOS_DATE], '/');
if (s) {
int year, disable = 0;
s++;
year = simple_strtoul(s,NULL,0);
if (year >= 1000)
disable = year < ACPI_BLACKLIST_CUTOFF_YEAR;
else if (year < 1 || (year > 90 && year <= 99))
disable = 1;
if (disable && !acpi_force) {
printk(KERN_NOTICE "ACPI disabled because your bios is from %s and too old\n", s);
printk(KERN_NOTICE "You can enable it with acpi=force\n");
acpi_disabled = 1;
}
}
}
d=&dmi_blacklist[0];
while(d->callback)
{
......@@ -885,6 +1145,8 @@ void __init dmi_scan_machine(void)
int err = dmi_iterate(dmi_decode);
if(err == 0)
dmi_check_blacklist();
else
printk(KERN_INFO "DMI not present.\n");
}
EXPORT_SYMBOL(is_unsafe_smbus);
......@@ -620,7 +620,7 @@ void __init get_smp_config (void)
/*
* ACPI may be used to obtain the entire SMP configuration or just to
* enumerate/configure processors (CONFIG_ACPI_HT_ONLY). Note that
* enumerate/configure processors (CONFIG_ACPI_HT). Note that
* ACPI supports both logical (e.g. Hyper-Threading) and physical
* processors, where MPS only supports physical.
*/
......@@ -1011,8 +1011,9 @@ void __init mp_config_acpi_legacy_irqs (void)
panic("Max # of irq sources exceeded!\n");
}
}
#endif /* CONFIG_X86_IO_APIC */
#ifndef CONFIG_ACPI_HT_ONLY
#ifdef CONFIG_ACPI
/* Ensure the ACPI SCI interrupt level is active low, edge-triggered */
......@@ -1067,8 +1068,7 @@ void __init mp_config_ioapic_for_sci(int irq)
io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 1, 1); // Active low, level triggered
}
#endif /*CONFIG_ACPI_HT_ONLY*/
#endif /* CONFIG_ACPI */
#ifdef CONFIG_ACPI_PCI
......@@ -1149,6 +1149,4 @@ void __init mp_parse_prt (void)
#endif /*CONFIG_ACPI_PCI*/
#endif /*CONFIG_X86_IO_APIC*/
#endif /*CONFIG_ACPI_BOOT*/
......@@ -62,13 +62,20 @@ struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
unsigned long mmu_cr4_features;
EXPORT_SYMBOL_GPL(mmu_cr4_features);
#ifdef CONFIG_ACPI_HT_ONLY
int acpi_disabled = 1;
#ifdef CONFIG_ACPI
int acpi_disabled __initdata = 0;
#else
int acpi_disabled = 0;
int acpi_disabled __initdata = 1;
#endif
EXPORT_SYMBOL(acpi_disabled);
#ifdef CONFIG_ACPI_BOOT
int acpi_ht __initdata = 1; /* enable HT */
#endif
int acpi_force __initdata = 0;
int MCA_bus;
/* for MCA, but anyone else can use it if they want */
unsigned int machine_id;
......@@ -516,13 +523,26 @@ static void __init parse_cmdline_early (char ** cmdline_p)
}
}
/* "acpi=off" disables both ACPI table parsing and interpreter init */
if (c == ' ' && !memcmp(from, "acpi=off", 8))
#ifdef CONFIG_ACPI_BOOT
/* "acpi=off" disables both ACPI table parsing and interpreter */
else if (!memcmp(from, "acpi=off", 8)) {
acpi_ht = 0;
acpi_disabled = 1;
}
/* "acpismp=force" turns on ACPI again */
if (c == ' ' && !memcmp(from, "acpismp=force", 13))
/* acpi=force to over-ride black-list */
else if (!memcmp(from, "acpi=force", 10)) {
acpi_force = 1;
acpi_ht=1;
acpi_disabled = 0;
}
/* Limit ACPI just to boot-time to enable HT */
else if (!memcmp(from, "acpi=ht", 7)) {
acpi_ht = 1;
if (!acpi_force) acpi_disabled = 1;
}
#endif
/*
* highmem=size forces highmem to be exactly 'size' bytes.
......@@ -978,12 +998,11 @@ void __init setup_arch(char **cmdline_p)
generic_apic_probe(*cmdline_p);
#endif
#ifdef CONFIG_ACPI
#ifdef CONFIG_ACPI_BOOT
/*
* Parse the ACPI tables for possible boot-time SMP configuration.
*/
if (!acpi_disabled)
acpi_boot_init();
(void) acpi_boot_init();
#endif
#ifdef CONFIG_X86_LOCAL_APIC
if (smp_found_config)
......
......@@ -954,7 +954,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
* If we couldn't find an SMP configuration at boot time,
* get out of here now!
*/
if (!smp_found_config) {
if (!smp_found_config && !acpi_lapic) {
printk(KERN_NOTICE "SMP motherboard not detected.\n");
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = 1;
......
......@@ -32,4 +32,14 @@ static int __init pci_acpi_init(void)
return 0;
}
/*
* pci_disable_acpi()
* act like pci=noacpi seen on command line
* called by DMI blacklist code
*/
__init void pci_disable_acpi(void)
{
pci_probe |= PCI_NO_ACPI_ROUTING;
}
subsys_initcall(pci_acpi_init);
......@@ -7,7 +7,7 @@
obj-$(CONFIG_PCI) += pci/
obj-$(CONFIG_PARISC) += parisc/
obj-$(CONFIG_ACPI) += acpi/
obj-$(CONFIG_ACPI_BOOT) += acpi/
# PnP must come after ACPI since it will eventually need to check if acpi
# was used and do nothing if so
obj-$(CONFIG_PNP) += pnp/
......
......@@ -2,12 +2,36 @@
# ACPI Configuration
#
menu "ACPI Support"
menu "ACPI (Advanced Configuration and Power Interface) Support"
config ACPI_HT
bool "ACPI Processor Enumeration for HT"
depends on (X86 && X86_LOCAL_APIC)
default y
---help---
ACPI enumerates both logical (a.k.a. Hyper-Threaded -- HT)
and physical processors. It is designed to obsolete several older
specifications, including the MultiProcessor Specification (MPS),
which supported only physical processors.
CONFIG_ACPI_HT includes the minimal ACPI boot-time code
necessary to enumerate logical processors and enable HT.
CONFIG_ACPI includes CONFIG_ACPI_HT, plus IO APIC enumeration,
and the hooks to run the ACPI AML interpreter for run-time events.
When CONFIG_ACPI is selected, the command-line option "acpi=ht"
is available to run just the ACPI boot-time code -- just as if
only CONFIG_ACPI_HT were selected.
Note that "acpi=off" can be used to disable all ACPI code in the kernel.
config ACPI
bool "ACPI Support" if X86
bool "Full ACPI Support"
depends on !X86_VISWS
default y if IA64 && (!IA64_HP_SIM || IA64_SGI_SN)
depends on !IA64_HP_SIM
depends on IA64 || (X86 && ACPI_HT)
default y
---help---
Advanced Configuration and Power Interface (ACPI) support for
Linux requires an ACPI compliant platform (hardware/firmware),
......@@ -36,30 +60,16 @@ config ACPI
available at:
<http://www.acpi.info>
config ACPI_HT_ONLY
bool "CPU Enumeration Only"
depends on X86 && ACPI && X86_LOCAL_APIC
---help---
This option enables limited ACPI support -- just enough to
enumerate processors from the ACPI Multiple APIC Description
Table (MADT). Note that ACPI supports both logical (e.g. Hyper-
Threading) and physical processors, where the MultiProcessor
Specification (MPS) table only supports physical processors.
Full ACPI support (CONFIG_ACPI) is preferred. Use this option
only if you wish to limit ACPI's role to processor enumeration.
In this configuration, ACPI defaults to off. It must be enabled
on the command-line with the "acpismp=force" option.
config ACPI_BOOT
bool
depends on IA64 && (!IA64_HP_SIM || IA64_SGI_SN) || X86 && ACPI && !ACPI_HT_ONLY
depends on ACPI || ACPI_HT
default y
config ACPI_SLEEP
bool "Sleep States (EXPERIMENTAL)"
depends on X86 && ACPI && !ACPI_HT_ONLY && EXPERIMENTAL
bool "Sleep States"
depends on X86 && ACPI
depends on SOFTWARE_SUSPEND
default y
---help---
This option adds support for ACPI suspend states.
......@@ -83,7 +93,8 @@ config ACPI_SLEEP_PROC_FS
config ACPI_AC
tristate "AC Adapter"
depends on X86 && ACPI && !ACPI_HT_ONLY
depends on X86 && ACPI
default m
help
This driver adds support for the AC Adapter object, which indicates
whether a system is on AC, or not. Typically, only mobile systems
......@@ -91,7 +102,8 @@ config ACPI_AC
config ACPI_BATTERY
tristate "Battery"
depends on X86 && ACPI && !ACPI_HT_ONLY
depends on X86 && ACPI
default m
help
This driver adds support for battery information through
/proc/acpi/battery. If you have a mobile system with a battery,
......@@ -99,7 +111,9 @@ config ACPI_BATTERY
config ACPI_BUTTON
tristate "Button"
depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
depends on ACPI
depends on !IA64_SGI_SN
default m
help
This driver registers for events based on buttons, such as the
power, sleep, and lid switch. In the future, a daemon will read
......@@ -109,14 +123,18 @@ config ACPI_BUTTON
config ACPI_FAN
tristate "Fan"
depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
depends on ACPI
depends on !IA64_SGI_SN
default m
help
This driver adds support for ACPI fan devices, allowing user-mode
applications to perform basic fan control (on, off, status).
config ACPI_PROCESSOR
tristate "Processor"
depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
depends on ACPI
depends on !IA64_SGI_SN
default m
help
This driver installs ACPI as the idle handler for Linux, and uses
ACPI C2 and C3 processor states to save power, on systems that
......@@ -125,6 +143,7 @@ config ACPI_PROCESSOR
config ACPI_THERMAL
tristate "Thermal Zone"
depends on ACPI_PROCESSOR
default m
help
This driver adds support for ACPI thermal zones. Most mobile and
some desktop systems support ACPI thermal zones. It is HIGHLY
......@@ -132,12 +151,16 @@ config ACPI_THERMAL
may be damaged without it.
config ACPI_NUMA
bool "NUMA support" if NUMA && (IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY && !X86_64)
bool "NUMA support"
depends on ACPI
depends on NUMA
depends on !X86_64
default y if IA64_GENERIC || IA64_SGI_SN2
config ACPI_ASUS
tristate "ASUS/Medion Laptop Extras"
depends on X86 && ACPI && !ACPI_HT_ONLY
depends on X86 && ACPI
default m
---help---
This driver provides support for extra features of ACPI-compatible
ASUS laptops. As some of Medion laptops are made by ASUS, it may also
......@@ -162,7 +185,8 @@ config ACPI_ASUS
config ACPI_TOSHIBA
tristate "Toshiba Laptop Extras"
depends on X86 && ACPI && !ACPI_HT_ONLY
depends on X86 && ACPI
default m
---help---
This driver adds support for access to certain system settings
on "legacy free" Toshiba laptops. These laptops can be recognized by
......@@ -188,7 +212,9 @@ config ACPI_TOSHIBA
config ACPI_DEBUG
bool "Debug Statements"
depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
depends on ACPI
depends on !IA64_SGI_SN
default n
help
The ACPI driver can optionally report errors with a great deal
of verbosity. Saying Y enables these statements. This will increase
......@@ -196,17 +222,19 @@ config ACPI_DEBUG
config ACPI_BUS
bool
depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
depends on ACPI
depends on !IA64_SGI_SN
default y
config ACPI_INTERPRETER
bool
depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
depends on ACPI
depends on !IA64_SGI_SN
default y
config ACPI_EC
bool
depends on X86 && ACPI && !ACPI_HT_ONLY
depends on X86 && ACPI
default y
help
This driver is required on some systems for the proper operation of
......@@ -215,17 +243,20 @@ config ACPI_EC
config ACPI_POWER
bool
depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
depends on ACPI
depends on !IA64_SGI_SN
default y
config ACPI_PCI
bool
depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
depends on ACPI
depends on !IA64_SGI_SN
default PCI
config ACPI_SYSTEM
bool
depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
depends on ACPI
depends on !IA64_SGI_SN
default y
help
This driver will enable your system to shut down using ACPI, and
......@@ -233,7 +264,8 @@ config ACPI_SYSTEM
config ACPI_EFI
bool
depends on IA64 && (!IA64_HP_SIM || IA64_SGI_SN)
depends on ACPI
depends on IA64
default y
endmenu
......
......@@ -12,12 +12,13 @@ endif
EXTRA_CFLAGS += $(ACPI_CFLAGS)
obj-y := acpi_ksyms.o
obj-$(CONFIG_ACPI) := acpi_ksyms.o
#
# ACPI Boot-Time Table Parsing
#
obj-$(CONFIG_ACPI_BOOT) += tables.o blacklist.o
obj-$(CONFIG_ACPI_BOOT) += tables.o
obj-$(CONFIG_ACPI) += blacklist.o
#
# ACPI Core Subsystem (Interpreter)
......
......@@ -691,7 +691,7 @@ static int __init acpi_init (void)
acpi_set_debug(ACPI_DEBUG_LOW);
if (acpi_disabled) {
printk(KERN_INFO PREFIX "Disabled via command line (acpi=off)\n");
printk(KERN_INFO PREFIX "Interpreter disabled.\n");
return -ENODEV;
}
......
......@@ -96,10 +96,11 @@ acpi_table_print (
else
name = header->signature;
printk(KERN_INFO PREFIX "%.4s (v%3.3d %6.6s %8.8s %5.5d.%5.5d) @ 0x%p\n",
printk(KERN_INFO PREFIX "%.4s (v%3.3d %6.6s %8.8s 0x%08x %.4s 0x%08x) @ 0x%p\n",
name, header->revision, header->oem_id,
header->oem_table_id, header->oem_revision >> 16,
header->oem_revision & 0xffff, (void *) phys_addr);
header->oem_table_id, header->oem_revision,
header->asl_compiler_id, header->asl_compiler_revision,
(void *) phys_addr);
}
......@@ -219,12 +220,16 @@ acpi_table_compute_checksum (
return (sum & 0xFF);
}
/*
* acpi_get_table_header_early()
* for acpi_blacklisted(), acpi_table_get_sdt()
*/
int __init
acpi_get_table_header_early (
enum acpi_table_id id,
struct acpi_table_header **header)
{
int i;
unsigned int i;
enum acpi_table_id temp_id;
/* DSDT is different from the rest */
......@@ -281,7 +286,7 @@ acpi_table_parse_madt_family (
acpi_table_entry_header *entry = NULL;
unsigned long count = 0;
unsigned long madt_end = 0;
int i = 0;
unsigned int i = 0;
if (!handler)
return -EINVAL;
......@@ -343,7 +348,7 @@ acpi_table_parse (
acpi_table_handler handler)
{
int count = 0;
int i = 0;
unsigned int i = 0;
if (!handler)
return -EINVAL;
......@@ -364,7 +369,7 @@ acpi_table_get_sdt (
struct acpi_table_rsdp *rsdp)
{
struct acpi_table_header *header = NULL;
int i, id = 0;
unsigned int i, id = 0;
if (!rsdp)
return -EINVAL;
......@@ -550,7 +555,7 @@ acpi_table_init (void)
return -ENODEV;
}
printk(KERN_INFO PREFIX "RSDP (v%3.3d %6.6s ) @ 0x%p\n",
printk(KERN_INFO PREFIX "RSDP (v%3.3d %6.6s ) @ 0x%p\n",
rsdp->revision, rsdp->oem_id, (void *) rsdp_phys);
if (rsdp->revision < 2)
......
......@@ -106,30 +106,22 @@
:"0"(n_hi), "1"(n_lo))
#ifdef CONFIG_ACPI_HT_ONLY
extern int acpi_lapic;
#define acpi_ioapic 0
#if defined(CONFIG_ACPI_BOOT) && defined(CONFIG_X86_LOCAL_APIC)
extern int acpi_lapic;
#else
#ifndef CONFIG_ACPI_BOOT
#define acpi_lapic 0
#define acpi_ioapic 0
#else
#ifdef CONFIG_X86_LOCAL_APIC
extern int acpi_lapic;
#else
#define acpi_lapic 0
#define acpi_lapic 0
#endif
#ifdef CONFIG_X86_IO_APIC
extern int acpi_ioapic;
#if defined(CONFIG_ACPI_BOOT) && defined(CONFIG_X86_IO_APIC)
extern int acpi_ioapic;
#else
#define acpi_ioapic 0
#endif
#define acpi_ioapic 0
#endif
#ifdef CONFIG_ACPI_BOOT
/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
#define FIX_ACPI_PAGES 4
#endif /*CONFIG_ACPI_BOOT*/
#endif
#ifdef CONFIG_ACPI_SLEEP
......
......@@ -37,7 +37,7 @@
#include <asm/acpi.h>
#ifdef CONFIG_ACPI
#ifdef CONFIG_ACPI_BOOT
enum acpi_irq_model_id {
ACPI_IRQ_MODEL_PIC = 0,
......@@ -369,11 +369,11 @@ void acpi_numa_arch_fixup(void);
extern int acpi_mp_config;
#else
#else /*!CONFIG_ACPI_BOOT*/
#define acpi_mp_config 0
#endif
#endif /*!CONFIG_ACPI_BOOT*/
#ifdef CONFIG_ACPI_PCI
......
......@@ -273,6 +273,16 @@ void __init mount_block_root(char *name, int flags)
printk("VFS: Cannot open root device \"%s\" or %s\n",
root_device_name, b);
printk("Please append a correct \"root=\" boot option\n");
#ifdef __i386__
{
extern void dmi_dump_system(void);
printk ("You may want to retry boot with pci=noacpi, "
"acpi=ht, or acpi=off on the command line.\n");
printk ("If one of them helps please report it with "
"the following lines:\n");
dmi_dump_system();
}
#endif
panic("VFS: Unable to mount root fs on %s", b);
}
panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment