⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 acpi.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  acpi.c - Architecture-Specific Low-Level ACPI Support * *  Copyright (C) 1999 VA Linux Systems *  Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com> *  Copyright (C) 2000, 2002-2003 Hewlett-Packard Co. *	David Mosberger-Tang <davidm@hpl.hp.com> *  Copyright (C) 2000 Intel Corp. *  Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com> *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> *  Copyright (C) 2001 Jenna Hall <jenna.s.hall@intel.com> *  Copyright (C) 2001 Takayoshi Kochi <t-kochi@bq.jp.nec.com> *  Copyright (C) 2002 Erich Focht <efocht@ess.nec.de> *  Copyright (C) 2004 Ashok Raj <ashok.raj@intel.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 * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */#include <linux/module.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/smp.h>#include <linux/string.h>#include <linux/types.h>#include <linux/irq.h>#include <linux/acpi.h>#include <linux/efi.h>#include <linux/mmzone.h>#include <linux/nodemask.h>#include <asm/io.h>#include <asm/iosapic.h>#include <asm/machvec.h>#include <asm/page.h>#include <asm/system.h>#include <asm/numa.h>#include <asm/sal.h>#include <asm/cyclone.h>#include <asm/xen/hypervisor.h>#ifdef XEN#include <asm/hw_irq.h>extern u8 numa_slit[MAX_NUMNODES * MAX_NUMNODES];#endif#define BAD_MADT_ENTRY(entry, end) (                                        \		(!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \		((struct acpi_subtable_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 int acpi_cpei_override;unsigned int acpi_cpei_phys_cpuid;unsigned long acpi_wakeup_address = 0;#ifdef CONFIG_IA64_GENERIC#ifndef XENstatic unsigned long __init acpi_find_rsdp(void)#elseunsigned long __init acpi_find_rsdp(void)#endif{	unsigned long rsdp_phys = 0;	if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)		rsdp_phys = efi.acpi20;	else if (efi.acpi != EFI_INVALID_TABLE_ADDR)		printk(KERN_WARNING PREFIX		       "v1.0/r0.71 tables no longer supported\n");	return rsdp_phys;}#endifconst char __init *acpi_get_sysname(void){#ifdef CONFIG_IA64_GENERIC	unsigned long rsdp_phys;	struct acpi_table_rsdp *rsdp;	struct acpi_table_xsdt *xsdt;	struct acpi_table_header *hdr;	rsdp_phys = acpi_find_rsdp();	if (!rsdp_phys) {		printk(KERN_ERR		       "ACPI 2.0 RSDP not found, default to \"dig\"\n");		return "dig";	}	rsdp = (struct acpi_table_rsdp *)__va(rsdp_phys);	if (strncmp(rsdp->signature, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1)) {		printk(KERN_ERR		       "ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n");		return "dig";	}	xsdt = (struct acpi_table_xsdt *)__va(rsdp->xsdt_physical_address);	hdr = &xsdt->header;	if (strncmp(hdr->signature, ACPI_SIG_XSDT, sizeof(ACPI_SIG_XSDT) - 1)) {		printk(KERN_ERR		       "ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n");		return "dig";	}	if (!strcmp(hdr->oem_id, "HP")) {		return "hpzx1";	} else if (!strcmp(hdr->oem_id, "SGI")) {		if (!strcmp(hdr->oem_table_id + 4, "UV"))			return "uv";		else			return "sn2";#ifndef XEN	} else if (is_running_on_xen() && !strcmp(hdr->oem_id, "XEN")) {		return "xen";#endif	}	return "dig";#else# if defined (CONFIG_IA64_HP_SIM)	return "hpsim";# elif defined (CONFIG_IA64_HP_ZX1)	return "hpzx1";# elif defined (CONFIG_IA64_HP_ZX1_SWIOTLB)	return "hpzx1_swiotlb";# elif defined (CONFIG_IA64_SGI_SN2)	return "sn2";# elif defined (CONFIG_IA64_SGI_UV)	return "uv";# elif defined (CONFIG_IA64_DIG)	return "dig";# elif defined (CONFIG_IA64_XEN)	return "xen";# else#	error Unknown platform.  Fix acpi.c.# endif#endif}#ifdef CONFIG_ACPI#define ACPI_MAX_PLATFORM_INTERRUPTS	256/* Array to record platform interrupt vectors for generic interrupt routing. */int platform_intr_list[ACPI_MAX_PLATFORM_INTERRUPTS] = {	[0 ... ACPI_MAX_PLATFORM_INTERRUPTS - 1] = -1};enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC;/* * Interrupt routing API for device drivers.  Provides interrupt vector for * a generic platform event.  Currently only CPEI is implemented. */int acpi_request_vector(u32 int_type){	int vector = -1;	if (int_type < ACPI_MAX_PLATFORM_INTERRUPTS) {		/* corrected platform error interrupt */		vector = platform_intr_list[int_type];	} else		printk(KERN_ERR		       "acpi_request_vector(): invalid interrupt type\n");	return vector;}char *__init __acpi_map_table(unsigned long phys_addr, unsigned long size){	return __va(phys_addr);}/* --------------------------------------------------------------------------                            Boot-time Table Parsing   -------------------------------------------------------------------------- */static int total_cpus __initdata;static int available_cpus __initdata;struct acpi_table_madt *acpi_madt __initdata;static u8 has_8259;static int __initacpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header,			  const unsigned long end){	struct acpi_madt_local_apic_override *lapic;	lapic = (struct acpi_madt_local_apic_override *)header;	if (BAD_MADT_ENTRY(lapic, end))		return -EINVAL;	if (lapic->address) {		iounmap(ipi_base_addr);		ipi_base_addr = ioremap(lapic->address, 0);	}	return 0;}static int __initacpi_parse_lsapic(struct acpi_subtable_header * header, const unsigned long end){	struct acpi_madt_local_sapic *lsapic;	lsapic = (struct acpi_madt_local_sapic *)header;	/*Skip BAD_MADT_ENTRY check, as lsapic size could vary */	if (lsapic->lapic_flags & ACPI_MADT_ENABLED) {#ifdef CONFIG_SMP		smp_boot_data.cpu_phys_id[available_cpus] =		    (lsapic->id << 8) | lsapic->eid;#endif		++available_cpus;	}	total_cpus++;	return 0;}static int __initacpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end){	struct acpi_madt_local_apic_nmi *lacpi_nmi;	lacpi_nmi = (struct acpi_madt_local_apic_nmi *)header;	if (BAD_MADT_ENTRY(lacpi_nmi, end))		return -EINVAL;	/* TBD: Support lapic_nmi entries */	return 0;}static int __initacpi_parse_iosapic(struct acpi_subtable_header * header, const unsigned long end){	struct acpi_madt_io_sapic *iosapic;	iosapic = (struct acpi_madt_io_sapic *)header;	if (BAD_MADT_ENTRY(iosapic, end))		return -EINVAL;	return iosapic_init(iosapic->address, iosapic->global_irq_base);}static unsigned int __initdata acpi_madt_rev;static int __initacpi_parse_plat_int_src(struct acpi_subtable_header * header,			const unsigned long end){	struct acpi_madt_interrupt_source *plintsrc;	int vector;	plintsrc = (struct acpi_madt_interrupt_source *)header;	if (BAD_MADT_ENTRY(plintsrc, end))		return -EINVAL;	/*	 * Get vector assignment for this interrupt, set attributes,	 * and program the IOSAPIC routing table.	 */	vector = iosapic_register_platform_intr(plintsrc->type,						plintsrc->global_irq,						plintsrc->io_sapic_vector,						plintsrc->eid,						plintsrc->id,						((plintsrc->inti_flags & ACPI_MADT_POLARITY_MASK) ==						 ACPI_MADT_POLARITY_ACTIVE_HIGH) ?						IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,						((plintsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) ==						 ACPI_MADT_TRIGGER_EDGE) ?						IOSAPIC_EDGE : IOSAPIC_LEVEL);	platform_intr_list[plintsrc->type] = vector;	if (acpi_madt_rev > 1) {		acpi_cpei_override = plintsrc->flags & ACPI_MADT_CPEI_OVERRIDE;	}	/*	 * Save the physical id, so we can check when its being removed	 */	acpi_cpei_phys_cpuid = ((plintsrc->id << 8) | (plintsrc->eid)) & 0xffff;	return 0;}#ifdef CONFIG_HOTPLUG_CPU#ifdef XENunsigned int force_cpei_retarget = 0;#endifunsigned int can_cpei_retarget(void){	extern int cpe_vector;	extern unsigned int force_cpei_retarget;	/*	 * Only if CPEI is supported and the override flag	 * is present, otherwise return that its re-targettable	 * if we are in polling mode.	 */	if (cpe_vector > 0) {		if (acpi_cpei_override || force_cpei_retarget)			return 1;		else			return 0;	}	return 1;}unsigned int is_cpu_cpei_target(unsigned int cpu){	unsigned int logical_id;	logical_id = cpu_logical_id(acpi_cpei_phys_cpuid);	if (logical_id == cpu)		return 1;	else		return 0;}void set_cpei_target_cpu(unsigned int cpu){	acpi_cpei_phys_cpuid = cpu_physical_id(cpu);}#endifunsigned int get_cpei_target_cpu(void){	return acpi_cpei_phys_cpuid;}static int __initacpi_parse_int_src_ovr(struct acpi_subtable_header * header,		       const unsigned long end){	struct acpi_madt_interrupt_override *p;	p = (struct acpi_madt_interrupt_override *)header;	if (BAD_MADT_ENTRY(p, end))		return -EINVAL;	iosapic_override_isa_irq(p->source_irq, p->global_irq,				 ((p->inti_flags & ACPI_MADT_POLARITY_MASK) ==				  ACPI_MADT_POLARITY_ACTIVE_HIGH) ?				 IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,				 ((p->inti_flags & ACPI_MADT_TRIGGER_MASK) ==				 ACPI_MADT_TRIGGER_EDGE) ?				 IOSAPIC_EDGE : IOSAPIC_LEVEL);	return 0;}static int __initacpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end){	struct acpi_madt_nmi_source *nmi_src;	nmi_src = (struct acpi_madt_nmi_source *)header;	if (BAD_MADT_ENTRY(nmi_src, end))		return -EINVAL;	/* TBD: Support nimsrc entries */	return 0;}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))) {		/*		 * 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;#ifndef XEN		cyclone_setup();#endif	}}static int __init acpi_parse_madt(struct acpi_table_header *table){	if (!table)		return -EINVAL;	acpi_madt = (struct acpi_table_madt *)table;	acpi_madt_rev = acpi_madt->header.revision;	/* remember the value for reference after free_initmem() */#ifdef CONFIG_ITANIUM	has_8259 = 1;		/* Firmware on old Itanium systems is broken */#else	has_8259 = acpi_madt->flags & ACPI_MADT_PCAT_COMPAT;#endif	iosapic_system_init(has_8259);	/* Get base address of IPI Message Block */	if (acpi_madt->address)		ipi_base_addr = ioremap(acpi_madt->address, 0);	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);	return 0;}#ifdef CONFIG_ACPI_NUMA#undef SLIT_DEBUG#define PXM_FLAG_LEN ((MAX_PXM_DOMAINS + 1)/32)static int __initdata srat_num_cpus;	/* number of cpus */static u32 __devinitdata pxm_flag[PXM_FLAG_LEN];#define pxm_bit_set(bit)	(set_bit(bit,(void *)pxm_flag))#define pxm_bit_test(bit)	(test_bit(bit,(void *)pxm_flag))static struct acpi_table_slit __initdata *slit_table;cpumask_t early_cpu_possible_map = CPU_MASK_NONE;static int get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa){	int pxm;	pxm = pa->proximity_domain_lo;	if (ia64_platform_is("sn2"))		pxm += pa->proximity_domain_hi[0] << 8;	return pxm;}static int get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma){	int pxm;	pxm = ma->proximity_domain;	if (!ia64_platform_is("sn2"))		pxm &= 0xff;	return pxm;}/* * ACPI 2.0 SLIT (System Locality Information Table) * http://devresource.hp.com/devresource/Docs/TechPapers/IA64/slit.pdf */void __init acpi_numa_slit_init(struct acpi_table_slit *slit){	u32 len;	len = sizeof(struct acpi_table_header) + 8	    + slit->locality_count * slit->locality_count;	if (slit->header.length != len) {		printk(KERN_ERR		       "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n",		       len, slit->header.length);		memset(numa_slit, 10, sizeof(numa_slit));		return;	}	slit_table = slit;}#ifndef XENvoid __initacpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)#elsevoid __initacpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa__)#endif{#ifdef XEN	struct acpi_srat_cpu_affinity *pa = (struct acpi_srat_cpu_affinity *)pa__;#endif	int pxm;	if (!(pa->flags & ACPI_SRAT_CPU_ENABLED))		return;	pxm = get_processor_proximity_domain(pa);	/* record this node in proximity bitmap */	pxm_bit_set(pxm);	node_cpuid[srat_num_cpus].phys_id =	    (pa->apic_id << 8) | (pa->local_sapic_eid);	/* nid should be overridden as logical node id later */	node_cpuid[srat_num_cpus].nid = pxm;	cpu_set(srat_num_cpus, early_cpu_possible_map);	srat_num_cpus++;}#ifndef XENvoid __initacpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)#elsevoid __initacpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma__)#endif{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -