ia64/xen-unstable

changeset 226:8554489b6ce4

bitkeeper revision 1.84 (3e5636ebE3jkdhUuagMAm36uQrxNnA)

acpitable.h, acpitable.c:
new file
author kaf24@labyrinth.cl.cam.ac.uk
date Fri Feb 21 14:25:47 2003 +0000 (2003-02-21)
parents 0fd36a1adb1d
children ef5e27f96b09
files .rootkeys xen-2.4.16/arch/i386/acpitable.c xen-2.4.16/arch/i386/acpitable.h
line diff
     1.1 --- a/.rootkeys	Fri Feb 21 14:25:12 2003 +0000
     1.2 +++ b/.rootkeys	Fri Feb 21 14:25:47 2003 +0000
     1.3 @@ -16,6 +16,8 @@ 3ddb79bcCa2VbsMp7mWKlhgwLQUQGA xen-2.4.1
     1.4  3ddb79bcWnTwYsQRWl_PaneJfa6p0w xen-2.4.16/Rules.mk
     1.5  3ddb79bcZbRBzT3elFWSX7u6NtMagQ xen-2.4.16/arch/i386/Makefile
     1.6  3ddb79bcBQF85CfLS4i1WGZ4oLLaCA xen-2.4.16/arch/i386/Rules.mk
     1.7 +3e5636e5FAYZ5_vQnmgwFJfSdmO5Mw xen-2.4.16/arch/i386/acpitable.c
     1.8 +3e5636e7NRe-LqmOmyagUFWr70bcag xen-2.4.16/arch/i386/acpitable.h
     1.9  3ddb79bcsjinG9k1KcvbVBuas1R2dA xen-2.4.16/arch/i386/apic.c
    1.10  3ddb79bcSC_LvnmFlX-T5iTgaR0SKg xen-2.4.16/arch/i386/boot/boot.S
    1.11  3ddb79bcUrk2EIaM5VsT6wUudH1kkg xen-2.4.16/arch/i386/delay.c
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/xen-2.4.16/arch/i386/acpitable.c	Fri Feb 21 14:25:47 2003 +0000
     2.3 @@ -0,0 +1,549 @@
     2.4 +/*
     2.5 + *  acpitable.c - IA32-specific ACPI boot-time initialization (Revision: 1)
     2.6 + *
     2.7 + *  Copyright (C) 1999 Andrew Henroid
     2.8 + *  Copyright (C) 2001 Richard Schaal
     2.9 + *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
    2.10 + *  Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
    2.11 + *  Copyright (C) 2001 Arjan van de Ven <arjanv@redhat.com>
    2.12 + *
    2.13 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    2.14 + *
    2.15 + *  This program is free software; you can redistribute it and/or modify
    2.16 + *  it under the terms of the GNU General Public License as published by
    2.17 + *  the Free Software Foundation; either version 2 of the License, or
    2.18 + *  (at your option) any later version.
    2.19 + *
    2.20 + *  This program is distributed in the hope that it will be useful,
    2.21 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.22 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.23 + *  GNU General Public License for more details.
    2.24 + *
    2.25 + *  You should have received a copy of the GNU General Public License
    2.26 + *  along with this program; if not, write to the Free Software
    2.27 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    2.28 + *
    2.29 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    2.30 + *
    2.31 + * $Id: acpitable.c,v 1.7 2001/11/04 12:21:18 fenrus Exp $
    2.32 + */
    2.33 +#include <xeno/config.h>
    2.34 +#include <xeno/kernel.h>
    2.35 +#include <xeno/init.h>
    2.36 +#include <xeno/types.h>
    2.37 +/*#include <xeno/stddef.h>*/
    2.38 +#include <xeno/slab.h>
    2.39 +#include <xeno/pci.h>
    2.40 +#include <asm/mpspec.h>
    2.41 +#include <asm/io.h>
    2.42 +#include <asm/apic.h>
    2.43 +#include <asm/apicdef.h>
    2.44 +#include <asm/page.h>
    2.45 +/*#include <asm/pgtable.h>*/
    2.46 +
    2.47 +#include "acpitable.h"
    2.48 +
    2.49 +static acpi_table_handler acpi_boot_ops[ACPI_TABLE_COUNT];
    2.50 +
    2.51 +
    2.52 +static unsigned char __init
    2.53 +acpi_checksum(void *buffer, int length)
    2.54 +{
    2.55 +	int i;
    2.56 +	unsigned char *bytebuffer;
    2.57 +	unsigned char sum = 0;
    2.58 +
    2.59 +	if (!buffer || length <= 0)
    2.60 +		return 0;
    2.61 +
    2.62 +	bytebuffer = (unsigned char *) buffer;
    2.63 +
    2.64 +	for (i = 0; i < length; i++)
    2.65 +		sum += *(bytebuffer++);
    2.66 +
    2.67 +	return sum;
    2.68 +}
    2.69 +
    2.70 +static void __init
    2.71 +acpi_print_table_header(acpi_table_header * header)
    2.72 +{
    2.73 +	if (!header)
    2.74 +		return;
    2.75 +
    2.76 +	printk(KERN_INFO "ACPI table found: %.4s v%d [%.6s %.8s %d.%d]\n",
    2.77 +	       header->signature, header->revision, header->oem_id,
    2.78 +	       header->oem_table_id, header->oem_revision >> 16,
    2.79 +	       header->oem_revision & 0xffff);
    2.80 +
    2.81 +	return;
    2.82 +}
    2.83 +
    2.84 +/*******************************************************************************
    2.85 + *
    2.86 + * FUNCTION:    acpi_tb_scan_memory_for_rsdp
    2.87 + *
    2.88 + * PARAMETERS:  address       - Starting pointer for search
    2.89 + *              length        - Maximum length to search
    2.90 + *
    2.91 + * RETURN:      Pointer to the RSDP if found and valid, otherwise NULL.
    2.92 + *
    2.93 + * DESCRIPTION: Search a block of memory for the RSDP signature
    2.94 + *
    2.95 + ******************************************************************************/
    2.96 +
    2.97 +static void *__init
    2.98 +acpi_tb_scan_memory_for_rsdp(void *address, int length)
    2.99 +{
   2.100 +	u32 offset;
   2.101 +
   2.102 +	if (length <= 0)
   2.103 +		return NULL;
   2.104 +
   2.105 +	/* Search from given start addr for the requested length  */
   2.106 +
   2.107 +	offset = 0;
   2.108 +
   2.109 +	while (offset < length) {
   2.110 +		/* The signature must match and the checksum must be correct */
   2.111 +		if (strncmp(address, RSDP_SIG, sizeof(RSDP_SIG) - 1) == 0 &&
   2.112 +		    acpi_checksum(address, RSDP_CHECKSUM_LENGTH) == 0) {
   2.113 +			/* If so, we have found the RSDP */
   2.114 +			printk(KERN_INFO "ACPI: RSDP located at physical address %p\n",
   2.115 +			       address);
   2.116 +			return address;
   2.117 +		}
   2.118 +		offset += RSDP_SCAN_STEP;
   2.119 +		address += RSDP_SCAN_STEP;
   2.120 +	}
   2.121 +
   2.122 +	/* Searched entire block, no RSDP was found */
   2.123 +	printk(KERN_INFO "ACPI: Searched entire block, no RSDP was found.\n");
   2.124 +	return NULL;
   2.125 +}
   2.126 +
   2.127 +/*******************************************************************************
   2.128 + *
   2.129 + * FUNCTION:    acpi_find_root_pointer
   2.130 + *
   2.131 + * PARAMETERS:  none
   2.132 + *
   2.133 + * RETURN:      physical address of the RSDP 
   2.134 + *
   2.135 + * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor
   2.136 + *              pointer structure.  If it is found, set *RSDP to point to it.
   2.137 + *
   2.138 + *              NOTE: The RSDP must be either in the first 1_k of the Extended
   2.139 + *              BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section
   2.140 + *              5.2.2; assertion #421).
   2.141 + *
   2.142 + ******************************************************************************/
   2.143 +
   2.144 +static struct acpi_table_rsdp * __init
   2.145 +acpi_find_root_pointer(void)
   2.146 +{
   2.147 +	struct acpi_table_rsdp * rsdp;
   2.148 +
   2.149 +	/*
   2.150 +	 * Physical address is given
   2.151 +	 */
   2.152 +	/*
   2.153 +	 * Region 1) Search EBDA (low memory) paragraphs
   2.154 +	 */
   2.155 +	rsdp = acpi_tb_scan_memory_for_rsdp(__va(LO_RSDP_WINDOW_BASE),
   2.156 +					 LO_RSDP_WINDOW_SIZE);
   2.157 +
   2.158 +	if (rsdp)
   2.159 +		return rsdp;
   2.160 +
   2.161 +	/*
   2.162 +	 * Region 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
   2.163 +	 */
   2.164 +	rsdp = acpi_tb_scan_memory_for_rsdp(__va(HI_RSDP_WINDOW_BASE),
   2.165 +					       HI_RSDP_WINDOW_SIZE);
   2.166 +
   2.167 +	
   2.168 +					     
   2.169 +	if (rsdp)
   2.170 +		return rsdp;
   2.171 +
   2.172 +	printk(KERN_ERR "ACPI: System description tables not found\n");
   2.173 +	return NULL;
   2.174 +}
   2.175 +
   2.176 +
   2.177 +/*
   2.178 + * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
   2.179 + * to map the target physical address. The problem is that set_fixmap()
   2.180 + * provides a single page, and it is possible that the page is not
   2.181 + * sufficient.
   2.182 + * By using this area, we can map up to MAX_IO_APICS pages temporarily,
   2.183 + * i.e. until the next __va_range() call.
   2.184 + *
   2.185 + * Important Safety Note:  The fixed I/O APIC page numbers are *subtracted*
   2.186 + * from the fixed base.  That's why we start at FIX_IO_APIC_BASE_END and
   2.187 + * count idx down while incrementing the phys address.
   2.188 + */
   2.189 +static __init char *
   2.190 +__va_range(unsigned long phys, unsigned long size)
   2.191 +{
   2.192 +	unsigned long base, offset, mapped_size;
   2.193 +	int idx;
   2.194 +
   2.195 +	offset = phys & (PAGE_SIZE - 1);
   2.196 +	mapped_size = PAGE_SIZE - offset;
   2.197 +	set_fixmap(FIX_IO_APIC_BASE_END, phys);
   2.198 +	base = fix_to_virt(FIX_IO_APIC_BASE_END);
   2.199 +	dprintk("__va_range(0x%lx, 0x%lx): idx=%d mapped at %lx\n", phys, size,
   2.200 +		FIX_IO_APIC_BASE_END, base);
   2.201 +
   2.202 +	/*
   2.203 +	 * Most cases can be covered by the below.
   2.204 +	 */
   2.205 +	idx = FIX_IO_APIC_BASE_END;
   2.206 +	while (mapped_size < size) {
   2.207 +		if (--idx < FIX_IO_APIC_BASE_0)
   2.208 +			return 0;	/* cannot handle this */
   2.209 +		phys += PAGE_SIZE;
   2.210 +		set_fixmap(idx, phys);
   2.211 +		mapped_size += PAGE_SIZE;
   2.212 +	}
   2.213 +
   2.214 +	return ((unsigned char *) base + offset);
   2.215 +}
   2.216 +
   2.217 +static int __init acpi_tables_init(void)
   2.218 +{
   2.219 +	int result = -ENODEV;
   2.220 +	acpi_table_header *header = NULL;
   2.221 +	struct acpi_table_rsdp *rsdp = NULL;
   2.222 +	struct acpi_table_rsdt *rsdt = NULL;
   2.223 +	struct acpi_table_rsdt saved_rsdt;
   2.224 +	int tables = 0;
   2.225 +	int type = 0;
   2.226 +	int i = 0;
   2.227 +
   2.228 +
   2.229 +	rsdp = (struct acpi_table_rsdp *) acpi_find_root_pointer();
   2.230 +
   2.231 +	if (!rsdp)
   2.232 +		return -ENODEV;
   2.233 +		
   2.234 +	printk(KERN_INFO "%.8s v%d [%.6s]\n", rsdp->signature, rsdp->revision,
   2.235 +	       rsdp->oem_id);
   2.236 +	       
   2.237 +	if (strncmp(rsdp->signature, RSDP_SIG,strlen(RSDP_SIG))) {
   2.238 +		printk(KERN_WARNING "RSDP table signature incorrect\n");
   2.239 +		return -EINVAL;
   2.240 +	}
   2.241 +
   2.242 +	rsdt = (struct acpi_table_rsdt *)
   2.243 +	    __va_range(rsdp->rsdt_address, sizeof(struct acpi_table_rsdt));
   2.244 +
   2.245 +	if (!rsdt) {
   2.246 +		printk(KERN_WARNING "ACPI: Invalid root system description tables (RSDT)\n");
   2.247 +		return -ENODEV;
   2.248 +	}
   2.249 +	
   2.250 +	header = & rsdt->header;
   2.251 +	acpi_print_table_header(header);
   2.252 +	
   2.253 +	if (strncmp(header->signature, RSDT_SIG, strlen(RSDT_SIG))) {
   2.254 +		printk(KERN_WARNING "ACPI: RSDT signature incorrect\n");
   2.255 +		return -ENODEV;
   2.256 +	}
   2.257 +		
   2.258 +	/* 
   2.259 +	 * The number of tables is computed by taking the 
   2.260 +	 * size of all entries (header size minus total 
   2.261 +	 * size of RSDT) divided by the size of each entry
   2.262 +	 * (4-byte table pointers).
   2.263 +	 */
   2.264 +	tables = (header->length - sizeof(acpi_table_header)) / 4;
   2.265 +		    
   2.266 +	memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt));
   2.267 +
   2.268 +	if (saved_rsdt.header.length > sizeof(saved_rsdt)) {
   2.269 +		printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n", saved_rsdt.header.length);
   2.270 +		return -ENODEV;
   2.271 +	}
   2.272 +
   2.273 +	for (i = 0; i < tables; i++) {
   2.274 +		/* Map in header, then map in full table length. */
   2.275 +		header = (acpi_table_header *)
   2.276 +			    __va_range(saved_rsdt.entry[i],
   2.277 +				       sizeof(acpi_table_header));
   2.278 +		if (!header)
   2.279 +			break;
   2.280 +		header = (acpi_table_header *)
   2.281 +			    __va_range(saved_rsdt.entry[i], header->length);
   2.282 +		if (!header)
   2.283 +			break;
   2.284 +
   2.285 +		acpi_print_table_header(header);
   2.286 +		
   2.287 +		if (acpi_checksum(header,header->length)) {
   2.288 +			printk(KERN_WARNING "ACPI %s has invalid checksum\n", 
   2.289 +				acpi_table_signatures[i]);
   2.290 +			continue;
   2.291 +		}
   2.292 +		
   2.293 +		for (type = 0; type < ACPI_TABLE_COUNT; type++)
   2.294 +			if (!strncmp((char *) &header->signature,
   2.295 +			     acpi_table_signatures[type],strlen(acpi_table_signatures[type])))
   2.296 +				break;
   2.297 +
   2.298 +		if (type >= ACPI_TABLE_COUNT) {
   2.299 +			printk(KERN_WARNING "ACPI: Unsupported table %.4s\n",
   2.300 +			       header->signature);
   2.301 +			continue;
   2.302 +		}
   2.303 +
   2.304 +
   2.305 +		if (!acpi_boot_ops[type])
   2.306 +			continue;
   2.307 +			
   2.308 +		result = acpi_boot_ops[type] (header,
   2.309 +						 (unsigned long) saved_rsdt.
   2.310 +						 entry[i]);
   2.311 +	}
   2.312 +
   2.313 +	return result;
   2.314 +}
   2.315 +
   2.316 +static int total_cpus __initdata = 0;
   2.317 +int have_acpi_tables;
   2.318 +
   2.319 +extern void __init MP_processor_info(struct mpc_config_processor *);
   2.320 +
   2.321 +static void __init
   2.322 +acpi_parse_lapic(struct acpi_table_lapic *local_apic)
   2.323 +{
   2.324 +	struct mpc_config_processor proc_entry;
   2.325 +	int ix = 0;
   2.326 +
   2.327 +	if (!local_apic)
   2.328 +		return;
   2.329 +
   2.330 +	printk(KERN_INFO "LAPIC (acpi_id[0x%04x] id[0x%x] enabled[%d])\n",
   2.331 +		local_apic->acpi_id, local_apic->id, local_apic->flags.enabled);
   2.332 +
   2.333 +	printk(KERN_INFO "CPU %d (0x%02x00)", total_cpus, local_apic->id);
   2.334 +
   2.335 +	if (local_apic->flags.enabled) {
   2.336 +		printk(" enabled");
   2.337 +		ix = local_apic->id;
   2.338 +		if (ix >= MAX_APICS) {
   2.339 +			printk(KERN_WARNING
   2.340 +			       "Processor #%d INVALID - (Max ID: %d).\n", ix,
   2.341 +			       MAX_APICS);
   2.342 +			return;
   2.343 +		}
   2.344 +		/* 
   2.345 +		 * Fill in the info we want to save.  Not concerned about 
   2.346 +		 * the processor ID.  Processor features aren't present in 
   2.347 +		 * the table.
   2.348 +		 */
   2.349 +		proc_entry.mpc_type = MP_PROCESSOR;
   2.350 +		proc_entry.mpc_apicid = local_apic->id;
   2.351 +		proc_entry.mpc_cpuflag = CPU_ENABLED;
   2.352 +		if (proc_entry.mpc_apicid == boot_cpu_physical_apicid) {
   2.353 +			printk(" (BSP)");
   2.354 +			proc_entry.mpc_cpuflag |= CPU_BOOTPROCESSOR;
   2.355 +		}
   2.356 +		proc_entry.mpc_cpufeature =
   2.357 +		    (boot_cpu_data.x86 << 8) | 
   2.358 +		    (boot_cpu_data.x86_model << 4) | 
   2.359 +		     boot_cpu_data.x86_mask;
   2.360 +		proc_entry.mpc_featureflag = boot_cpu_data.x86_capability[0];
   2.361 +		proc_entry.mpc_reserved[0] = 0;
   2.362 +		proc_entry.mpc_reserved[1] = 0;
   2.363 +		proc_entry.mpc_apicver = 0x10;	/* integrated APIC */
   2.364 +		MP_processor_info(&proc_entry);
   2.365 +	} else {
   2.366 +		printk(" disabled");
   2.367 +	}
   2.368 +	printk("\n");
   2.369 +
   2.370 +	total_cpus++;
   2.371 +	return;
   2.372 +}
   2.373 +
   2.374 +static void __init
   2.375 +acpi_parse_ioapic(struct acpi_table_ioapic *ioapic)
   2.376 +{
   2.377 +
   2.378 +	if (!ioapic)
   2.379 +		return;
   2.380 +
   2.381 +	printk(KERN_INFO
   2.382 +	       "IOAPIC (id[0x%x] address[0x%x] global_irq_base[0x%x])\n",
   2.383 +	       ioapic->id, ioapic->address, ioapic->global_irq_base);
   2.384 +
   2.385 +	if (nr_ioapics >= MAX_IO_APICS) {
   2.386 +		printk(KERN_WARNING
   2.387 +		       "Max # of I/O APICs (%d) exceeded (found %d).\n",
   2.388 +		       MAX_IO_APICS, nr_ioapics);
   2.389 +/*		panic("Recompile kernel with bigger MAX_IO_APICS!\n");   */
   2.390 +	}
   2.391 +}
   2.392 +
   2.393 +
   2.394 +/* Interrupt source overrides inform the machine about exceptions
   2.395 +   to the normal "PIC" mode interrupt routing */
   2.396 +   
   2.397 +static void __init
   2.398 +acpi_parse_int_src_ovr(struct acpi_table_int_src_ovr *intsrc)
   2.399 +{
   2.400 +	if (!intsrc)
   2.401 +		return;
   2.402 +
   2.403 +	printk(KERN_INFO
   2.404 +	       "INT_SRC_OVR (bus[%d] irq[0x%x] global_irq[0x%x] polarity[0x%x] trigger[0x%x])\n",
   2.405 +	       intsrc->bus, intsrc->bus_irq, intsrc->global_irq,
   2.406 +	       intsrc->flags.polarity, intsrc->flags.trigger);
   2.407 +}
   2.408 +
   2.409 +/*
   2.410 + * At this point, we look at the interrupt assignment entries in the MPS
   2.411 + * table.
   2.412 + */ 
   2.413 + 
   2.414 +static void __init acpi_parse_nmi_src(struct acpi_table_nmi_src *nmisrc)
   2.415 +{
   2.416 +	if (!nmisrc)
   2.417 +		return;
   2.418 +
   2.419 +	printk(KERN_INFO
   2.420 +	       "NMI_SRC (polarity[0x%x] trigger[0x%x] global_irq[0x%x])\n",
   2.421 +	       nmisrc->flags.polarity, nmisrc->flags.trigger,
   2.422 +	       nmisrc->global_irq);
   2.423 +
   2.424 +}
   2.425 +static void __init
   2.426 +acpi_parse_lapic_nmi(struct acpi_table_lapic_nmi *localnmi)
   2.427 +{
   2.428 +	if (!localnmi)
   2.429 +		return;
   2.430 +
   2.431 +	printk(KERN_INFO
   2.432 +	       "LAPIC_NMI (acpi_id[0x%04x] polarity[0x%x] trigger[0x%x] lint[0x%x])\n",
   2.433 +	       localnmi->acpi_id, localnmi->flags.polarity,
   2.434 +	       localnmi->flags.trigger, localnmi->lint);
   2.435 +}
   2.436 +static void __init
   2.437 +acpi_parse_lapic_addr_ovr(struct acpi_table_lapic_addr_ovr *lapic_addr_ovr)
   2.438 +{
   2.439 +	if (!lapic_addr_ovr)
   2.440 +		return;
   2.441 +
   2.442 +	printk(KERN_INFO "LAPIC_ADDR_OVR (address[0x%lx])\n",
   2.443 +	       (unsigned long) lapic_addr_ovr->address);
   2.444 +
   2.445 +}
   2.446 +
   2.447 +static void __init
   2.448 +acpi_parse_plat_int_src(struct acpi_table_plat_int_src *plintsrc)
   2.449 +{
   2.450 +	if (!plintsrc)
   2.451 +		return;
   2.452 +
   2.453 +	printk(KERN_INFO
   2.454 +	       "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",
   2.455 +	       plintsrc->flags.polarity, plintsrc->flags.trigger,
   2.456 +	       plintsrc->type, plintsrc->id, plintsrc->eid,
   2.457 +	       plintsrc->iosapic_vector, plintsrc->global_irq);
   2.458 +}
   2.459 +static int __init
   2.460 +acpi_parse_madt(acpi_table_header * header, unsigned long phys)
   2.461 +{
   2.462 +
   2.463 +	struct acpi_table_madt *madt;	    
   2.464 +	acpi_madt_entry_header *entry_header;
   2.465 +	int table_size;
   2.466 +	
   2.467 +	madt = (struct acpi_table_madt *) __va_range(phys, header->length);
   2.468 +
   2.469 +	if (!madt)
   2.470 +		return -EINVAL;
   2.471 +
   2.472 +	table_size = (int) (header->length - sizeof(*madt));
   2.473 +	entry_header =
   2.474 +	    (acpi_madt_entry_header *) ((void *) madt + sizeof(*madt));
   2.475 +
   2.476 +	while (entry_header && (table_size > 0)) {
   2.477 +		switch (entry_header->type) {
   2.478 +		case ACPI_MADT_LAPIC:
   2.479 +			acpi_parse_lapic((struct acpi_table_lapic *)
   2.480 +					 entry_header);
   2.481 +			break;
   2.482 +		case ACPI_MADT_IOAPIC:
   2.483 +			acpi_parse_ioapic((struct acpi_table_ioapic *)
   2.484 +					  entry_header);
   2.485 +			break;
   2.486 +		case ACPI_MADT_INT_SRC_OVR:
   2.487 +			acpi_parse_int_src_ovr((struct acpi_table_int_src_ovr *)
   2.488 +					       entry_header);
   2.489 +			break;
   2.490 +		case ACPI_MADT_NMI_SRC:
   2.491 +			acpi_parse_nmi_src((struct acpi_table_nmi_src *)
   2.492 +					   entry_header);
   2.493 +			break;
   2.494 +		case ACPI_MADT_LAPIC_NMI:
   2.495 +			acpi_parse_lapic_nmi((struct acpi_table_lapic_nmi *)
   2.496 +					     entry_header);
   2.497 +			break;
   2.498 +		case ACPI_MADT_LAPIC_ADDR_OVR:
   2.499 +			acpi_parse_lapic_addr_ovr((struct
   2.500 +						   acpi_table_lapic_addr_ovr *)
   2.501 +						  entry_header);
   2.502 +			break;
   2.503 +		case ACPI_MADT_PLAT_INT_SRC:
   2.504 +			acpi_parse_plat_int_src((struct acpi_table_plat_int_src
   2.505 +						 *) entry_header);
   2.506 +			break;
   2.507 +		default:
   2.508 +			printk(KERN_WARNING
   2.509 +			       "Unsupported MADT entry type 0x%x\n",
   2.510 +			       entry_header->type);
   2.511 +			break;
   2.512 +		}
   2.513 +		table_size -= entry_header->length;
   2.514 +		entry_header =
   2.515 +		    (acpi_madt_entry_header *) ((void *) entry_header +
   2.516 +						entry_header->length);
   2.517 +	}
   2.518 +
   2.519 +	if (!total_cpus) {
   2.520 +		printk("ACPI: No Processors found in the APCI table.\n");
   2.521 +		return -EINVAL;
   2.522 +	}
   2.523 +
   2.524 +	printk(KERN_INFO "%d CPUs total\n", total_cpus);
   2.525 +
   2.526 +	if (madt->lapic_address)
   2.527 +		mp_lapic_addr = madt->lapic_address;
   2.528 +	else
   2.529 +		mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
   2.530 +
   2.531 +	printk(KERN_INFO "Local APIC address %x\n", madt->lapic_address);
   2.532 +
   2.533 +	return 0;
   2.534 +}
   2.535 +
   2.536 +extern int opt_noacpi;
   2.537 +
   2.538 +/*
   2.539 + * Configure the processor info using MADT in the ACPI tables. If we fail to
   2.540 + * configure that, then we use the MPS tables.
   2.541 + */
   2.542 +void __init
   2.543 +config_acpi_tables(void)
   2.544 +{
   2.545 +	memset(&acpi_boot_ops, 0, sizeof(acpi_boot_ops));
   2.546 +	acpi_boot_ops[ACPI_APIC] = acpi_parse_madt;
   2.547 +
   2.548 +	if (!opt_noacpi && !acpi_tables_init()) {
   2.549 +		have_acpi_tables = 1;
   2.550 +		printk("Enabling the CPU's according to the ACPI table\n");
   2.551 +	}
   2.552 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xen-2.4.16/arch/i386/acpitable.h	Fri Feb 21 14:25:47 2003 +0000
     3.3 @@ -0,0 +1,260 @@
     3.4 +/*
     3.5 + *  acpitable.c - IA32-specific ACPI boot-time initialization (Revision: 1)
     3.6 + *
     3.7 + *  Copyright (C) 1999 Andrew Henroid
     3.8 + *  Copyright (C) 2001 Richard Schaal
     3.9 + *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
    3.10 + *  Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
    3.11 + *  Copyright (C) 2001 Arjan van de Ven <arjanv@redhat.com>
    3.12 + *
    3.13 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    3.14 + *
    3.15 + *  This program is free software; you can redistribute it and/or modify
    3.16 + *  it under the terms of the GNU General Public License as published by
    3.17 + *  the Free Software Foundation; either version 2 of the License, or
    3.18 + *  (at your option) any later version.
    3.19 + *
    3.20 + *  This program is distributed in the hope that it will be useful,
    3.21 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.22 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.23 + *  GNU General Public License for more details.
    3.24 + *
    3.25 + *  You should have received a copy of the GNU General Public License
    3.26 + *  along with this program; if not, write to the Free Software
    3.27 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    3.28 + *
    3.29 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    3.30 + *
    3.31 + * $Id: acpitable.h,v 1.3 2001/11/03 22:41:34 fenrus Exp $
    3.32 + */
    3.33 +
    3.34 +/*
    3.35 + * The following codes are cut&pasted from drivers/acpi. Part of the code
    3.36 + * there can be not updated or delivered yet.
    3.37 + * To avoid conflicts when CONFIG_ACPI is defined, the following codes are
    3.38 + * modified so that they are self-contained in this file.
    3.39 + * -- jun
    3.40 + */
    3.41 + 
    3.42 +#ifndef _HEADER_ACPITABLE_H_
    3.43 +#define _HEADER_ACPITABLE_H_
    3.44 +
    3.45 +#define dprintk printk
    3.46 +typedef unsigned int ACPI_TBLPTR;
    3.47 +
    3.48 +typedef struct {		/* ACPI common table header */
    3.49 +	char signature[4];	/* identifies type of table */
    3.50 +	u32 length;		/* length of table,
    3.51 +				   in bytes, * including header */
    3.52 +	u8 revision;		/* specification minor version # */
    3.53 +	u8 checksum;		/* to make sum of entire table == 0 */
    3.54 +	char oem_id[6];		/* OEM identification */
    3.55 +	char oem_table_id[8];	/* OEM table identification */
    3.56 +	u32 oem_revision;	/* OEM revision number */
    3.57 +	char asl_compiler_id[4];	/* ASL compiler vendor ID */
    3.58 +	u32 asl_compiler_revision;	/* ASL compiler revision number */
    3.59 +} acpi_table_header __attribute__ ((packed));;
    3.60 +
    3.61 +enum {
    3.62 +	ACPI_APIC = 0,
    3.63 +	ACPI_BOOT,
    3.64 +	ACPI_DBGP,
    3.65 +	ACPI_DSDT,
    3.66 +	ACPI_ECDT,
    3.67 +	ACPI_ETDT,
    3.68 +	ACPI_FACP,
    3.69 +	ACPI_FACS,
    3.70 +	ACPI_OEMX,
    3.71 +	ACPI_PSDT,
    3.72 +	ACPI_SBST,
    3.73 +	ACPI_SLIT,
    3.74 +	ACPI_SPCR,
    3.75 +	ACPI_SRAT,
    3.76 +	ACPI_SSDT,
    3.77 +	ACPI_SPMI,
    3.78 +	ACPI_XSDT,
    3.79 +	ACPI_TABLE_COUNT
    3.80 +};
    3.81 +
    3.82 +static char *acpi_table_signatures[ACPI_TABLE_COUNT] = {
    3.83 +	"APIC",
    3.84 +	"BOOT",
    3.85 +	"DBGP",
    3.86 +	"DSDT",
    3.87 +	"ECDT",
    3.88 +	"ETDT",
    3.89 +	"FACP",
    3.90 +	"FACS",
    3.91 +	"OEM",
    3.92 +	"PSDT",
    3.93 +	"SBST",
    3.94 +	"SLIT",
    3.95 +	"SPCR",
    3.96 +	"SRAT",
    3.97 +	"SSDT",
    3.98 +	"SPMI",
    3.99 +	"XSDT"
   3.100 +};
   3.101 +
   3.102 +struct acpi_table_madt {
   3.103 +	acpi_table_header header;
   3.104 +	u32 lapic_address;
   3.105 +	struct {
   3.106 +		u32 pcat_compat:1;
   3.107 +		u32 reserved:31;
   3.108 +	} flags __attribute__ ((packed));
   3.109 +} __attribute__ ((packed));;
   3.110 +
   3.111 +enum {
   3.112 +	ACPI_MADT_LAPIC = 0,
   3.113 +	ACPI_MADT_IOAPIC,
   3.114 +	ACPI_MADT_INT_SRC_OVR,
   3.115 +	ACPI_MADT_NMI_SRC,
   3.116 +	ACPI_MADT_LAPIC_NMI,
   3.117 +	ACPI_MADT_LAPIC_ADDR_OVR,
   3.118 +	ACPI_MADT_IOSAPIC,
   3.119 +	ACPI_MADT_LSAPIC,
   3.120 +	ACPI_MADT_PLAT_INT_SRC,
   3.121 +	ACPI_MADT_ENTRY_COUNT
   3.122 +};
   3.123 +
   3.124 +#define RSDP_SIG			"RSD PTR "
   3.125 +#define RSDT_SIG 			"RSDT"
   3.126 +
   3.127 +#define ACPI_DEBUG_PRINT(pl)
   3.128 +
   3.129 +#define ACPI_MEMORY_MODE                0x01
   3.130 +#define ACPI_LOGICAL_ADDRESSING         0x00
   3.131 +#define ACPI_PHYSICAL_ADDRESSING        0x01
   3.132 +
   3.133 +#define LO_RSDP_WINDOW_BASE         	0	/* Physical Address */
   3.134 +#define HI_RSDP_WINDOW_BASE         	0xE0000	/* Physical Address */
   3.135 +#define LO_RSDP_WINDOW_SIZE         	0x400
   3.136 +#define HI_RSDP_WINDOW_SIZE         	0x20000
   3.137 +#define RSDP_SCAN_STEP			16
   3.138 +#define RSDP_CHECKSUM_LENGTH		20
   3.139 +
   3.140 +typedef int (*acpi_table_handler) (acpi_table_header * header, unsigned long);
   3.141 +
   3.142 +struct acpi_table_rsdp {
   3.143 +	char signature[8];
   3.144 +	u8 checksum;
   3.145 +	char oem_id[6];
   3.146 +	u8 revision;
   3.147 +	u32 rsdt_address;
   3.148 +} __attribute__ ((packed));
   3.149 +
   3.150 +struct acpi_table_rsdt {
   3.151 +	acpi_table_header header;
   3.152 +	u32 entry[ACPI_TABLE_COUNT];
   3.153 +} __attribute__ ((packed));
   3.154 +
   3.155 +typedef struct {
   3.156 +	u8 type;
   3.157 +	u8 length;
   3.158 +} acpi_madt_entry_header __attribute__ ((packed));
   3.159 +
   3.160 +typedef struct {
   3.161 +	u16 polarity:2;
   3.162 +	u16 trigger:2;
   3.163 +	u16 reserved:12;
   3.164 +} acpi_madt_int_flags __attribute__ ((packed));
   3.165 +
   3.166 +struct acpi_table_lapic {
   3.167 +	acpi_madt_entry_header header;
   3.168 +	u8 acpi_id;
   3.169 +	u8 id;
   3.170 +	struct {
   3.171 +		u32 enabled:1;
   3.172 +		u32 reserved:31;
   3.173 +	} flags __attribute__ ((packed));
   3.174 +} __attribute__ ((packed));
   3.175 +
   3.176 +struct acpi_table_ioapic {
   3.177 +	acpi_madt_entry_header header;
   3.178 +	u8 id;
   3.179 +	u8 reserved;
   3.180 +	u32 address;
   3.181 +	u32 global_irq_base;
   3.182 +} __attribute__ ((packed));
   3.183 +
   3.184 +struct acpi_table_int_src_ovr {
   3.185 +	acpi_madt_entry_header header;
   3.186 +	u8 bus;
   3.187 +	u8 bus_irq;
   3.188 +	u32 global_irq;
   3.189 +	acpi_madt_int_flags flags;
   3.190 +} __attribute__ ((packed));
   3.191 +
   3.192 +struct acpi_table_nmi_src {
   3.193 +	acpi_madt_entry_header header;
   3.194 +	acpi_madt_int_flags flags;
   3.195 +	u32 global_irq;
   3.196 +} __attribute__ ((packed));
   3.197 +
   3.198 +struct acpi_table_lapic_nmi {
   3.199 +	acpi_madt_entry_header header;
   3.200 +	u8 acpi_id;
   3.201 +	acpi_madt_int_flags flags;
   3.202 +	u8 lint;
   3.203 +} __attribute__ ((packed));
   3.204 +
   3.205 +struct acpi_table_lapic_addr_ovr {
   3.206 +	acpi_madt_entry_header header;
   3.207 +	u8 reserved[2];
   3.208 +	u64 address;
   3.209 +} __attribute__ ((packed));
   3.210 +
   3.211 +struct acpi_table_iosapic {
   3.212 +	acpi_madt_entry_header header;
   3.213 +	u8 id;
   3.214 +	u8 reserved;
   3.215 +	u32 global_irq_base;
   3.216 +	u64 address;
   3.217 +} __attribute__ ((packed));
   3.218 +
   3.219 +struct acpi_table_lsapic {
   3.220 +	acpi_madt_entry_header header;
   3.221 +	u8 acpi_id;
   3.222 +	u8 id;
   3.223 +	u8 eid;
   3.224 +	u8 reserved[3];
   3.225 +	struct {
   3.226 +		u32 enabled:1;
   3.227 +		u32 reserved:31;
   3.228 +	} flags;
   3.229 +} __attribute__ ((packed));
   3.230 +
   3.231 +struct acpi_table_plat_int_src {
   3.232 +	acpi_madt_entry_header header;
   3.233 +	acpi_madt_int_flags flags;
   3.234 +	u8 type;
   3.235 +	u8 id;
   3.236 +	u8 eid;
   3.237 +	u8 iosapic_vector;
   3.238 +	u32 global_irq;
   3.239 +	u32 reserved;
   3.240 +} __attribute__ ((packed));
   3.241 +
   3.242 +/*
   3.243 + * ACPI Table Descriptor.  One per ACPI table
   3.244 + */
   3.245 +typedef struct acpi_table_desc {
   3.246 +	struct acpi_table_desc *prev;
   3.247 +	struct acpi_table_desc *next;
   3.248 +	struct acpi_table_desc *installed_desc;
   3.249 +	acpi_table_header *pointer;
   3.250 +	void *base_pointer;
   3.251 +	u8 *aml_pointer;
   3.252 +	u64 physical_address;
   3.253 +	u32 aml_length;
   3.254 +	u32 length;
   3.255 +	u32 count;
   3.256 +	u16 table_id;
   3.257 +	u8 type;
   3.258 +	u8 allocation;
   3.259 +	u8 loaded_into_namespace;
   3.260 +
   3.261 +} acpi_table_desc __attribute__ ((packed));;
   3.262 +
   3.263 +#endif