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

📄 acpi.c

📁 一个2.4.21版本的嵌入式linux内核
💻 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 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> * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * *  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/config.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 <asm/io.h>#include <asm/iosapic.h>#include <asm/machvec.h>#include <asm/page.h>#include <asm/system.h>#define PREFIX			"ACPI: "asm (".weak iosapic_register_intr");asm (".weak iosapic_override_isa_irq");asm (".weak iosapic_register_platform_intr");asm (".weak iosapic_init");asm (".weak iosapic_version");void (*pm_idle) (void);void (*pm_power_off) (void);unsigned char acpi_kbd_controller_present = 1;const char *acpi_get_sysname (void){#ifdef CONFIG_IA64_GENERIC	unsigned long rsdp_phys;	struct acpi20_table_rsdp *rsdp;	struct acpi_table_xsdt *xsdt;	struct acpi_table_header *hdr;	rsdp_phys = acpi_find_rsdp();	if (!rsdp_phys) {		printk("ACPI 2.0 RSDP not found, default to \"dig\"\n");		return "dig";	}	rsdp = (struct acpi20_table_rsdp *) __va(rsdp_phys);	if (strncmp(rsdp->signature, RSDP_SIG, sizeof(RSDP_SIG) - 1)) {		printk("ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n");		return "dig";	}	xsdt = (struct acpi_table_xsdt *) __va(rsdp->xsdt_address);	hdr = &xsdt->header;	if (strncmp(hdr->signature, XSDT_SIG, sizeof(XSDT_SIG) - 1)) {		printk("ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n");		return "dig";	}	if (!strcmp(hdr->oem_id, "HP")) {		return "hpzx1";	}	return "dig";#else# if defined (CONFIG_IA64_HP_SIM)	return "hpsim";# elif defined (CONFIG_IA64_HP_ZX1)	return "hpzx1";# elif defined (CONFIG_IA64_SGI_SN1)	return "sn1";# elif defined (CONFIG_IA64_SGI_SN2)	return "sn2";# elif defined (CONFIG_IA64_DIG)	return "dig";# else#	error Unknown platform.  Fix acpi.c.# endif#endif}#ifdef CONFIG_ACPIstatic acpi_resource *acpi_get_crs_next (acpi_buffer *buf, int *offset){	acpi_resource *res;	if (*offset >= buf->length)		return NULL;	res = (acpi_resource *)((char *) buf->pointer + *offset);	*offset += res->length;	return res;}static acpi_resource_data *acpi_get_crs_type (acpi_buffer *buf, int *offset, int type){	for (;;) {		acpi_resource *res = acpi_get_crs_next(buf, offset);		if (!res)			return NULL;		if (res->id == type)			return &res->data;	}}static voidacpi_get_crs_addr (acpi_buffer *buf, int type, u64 *base, u64 *length, u64 *tra){	int offset = 0;	acpi_resource_address16 *addr16;	acpi_resource_address32 *addr32;	acpi_resource_address64 *addr64;	for (;;) {		acpi_resource *res = acpi_get_crs_next(buf, &offset);		if (!res)			return;		switch (res->id) {			case ACPI_RSTYPE_ADDRESS16:				addr16 = (acpi_resource_address16 *) &res->data;				if (type == addr16->resource_type) {					*base = addr16->min_address_range;					*length = addr16->address_length;					*tra = addr16->address_translation_offset;					return;				}				break;			case ACPI_RSTYPE_ADDRESS32:				addr32 = (acpi_resource_address32 *) &res->data;				if (type == addr32->resource_type) {					*base = addr32->min_address_range;					*length = addr32->address_length;					*tra = addr32->address_translation_offset;					return;				}				break;			case ACPI_RSTYPE_ADDRESS64:				addr64 = (acpi_resource_address64 *) &res->data;				if (type == addr64->resource_type) {					*base = addr64->min_address_range;					*length = addr64->address_length;					*tra = addr64->address_translation_offset;					return;				}				break;			case ACPI_RSTYPE_END_TAG:				return;				break;		}	}}acpi_statusacpi_get_addr_space(acpi_handle obj, u8 type, u64 *base, u64 *length, u64 *tra){	acpi_status status;	acpi_buffer buf = { .length  = ACPI_ALLOCATE_BUFFER,			    .pointer = NULL };	*base = 0;	*length = 0;	*tra = 0;	status = acpi_get_current_resources(obj, &buf);	if (ACPI_FAILURE(status)) {		printk(KERN_ERR PREFIX "Unable to get _CRS data on object\n");		return status;	}	acpi_get_crs_addr(&buf, type, base, length, tra);	acpi_os_free(buf.pointer);	return AE_OK;}typedef struct {	u8	guid_id;	u8	guid[16];	u8	csr_base[8];	u8	csr_length[8];} acpi_hp_vendor_long;#define HP_CCSR_LENGTH 0x21#define HP_CCSR_TYPE 0x2#define HP_CCSR_GUID EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, \			      0xf6, 0x4a, 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad)acpi_statusacpi_hp_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length){	int i, offset = 0;	acpi_status status;	acpi_buffer buf = { .length  = ACPI_ALLOCATE_BUFFER,			    .pointer = NULL };	acpi_resource_vendor *res;	acpi_hp_vendor_long *hp_res;	efi_guid_t vendor_guid;	*csr_base = 0;	*csr_length = 0;	status = acpi_get_current_resources(obj, &buf);	if (ACPI_FAILURE(status)) {		printk(KERN_ERR PREFIX "Unable to get _CRS data on object\n");		return status;	}	status = AE_NOT_FOUND;	res = (acpi_resource_vendor *)acpi_get_crs_type(&buf, &offset, ACPI_RSTYPE_VENDOR);	if (!res) {		printk(KERN_ERR PREFIX "Failed to find config space for device\n");		goto out;	}	status = AE_TYPE; /* Revisit error? */	hp_res = (acpi_hp_vendor_long *)(res->reserved);	if (res->length != HP_CCSR_LENGTH || hp_res->guid_id != HP_CCSR_TYPE) {		printk(KERN_ERR PREFIX "Unknown Vendor data\n");		goto out;	}	memcpy(&vendor_guid, hp_res->guid, sizeof(efi_guid_t));	if (efi_guidcmp(vendor_guid, HP_CCSR_GUID) != 0) {		printk(KERN_ERR PREFIX "Vendor GUID does not match\n");		goto out;	}	/* It's probably unaligned, so use memcpy */	memcpy(csr_base, hp_res->csr_base, 8);	memcpy(csr_length, hp_res->csr_length, 8);	status = AE_OK; out:	acpi_os_free(buf.pointer);	return status;}#endif /* CONFIG_ACPI */#ifdef CONFIG_ACPI_BOOT#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. */intacpi_request_vector (u32 int_type){	int vector = -1;	if (int_type < ACPI_MAX_PLATFORM_INTERRUPTS) {		/* correctable platform error interrupt */		vector = platform_intr_list[int_type];	} else		printk("acpi_request_vector(): invalid interrupt type\n");	return vector;}char *__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 (acpi_table_entry_header *header){	struct acpi_table_lapic_addr_ovr *lapic;	lapic = (struct acpi_table_lapic_addr_ovr *) header;	if (!lapic)		return -EINVAL;	acpi_table_print_madt_entry(header);	if (lapic->address) {		iounmap((void *) ipi_base_addr);		ipi_base_addr = (unsigned long) ioremap(lapic->address, 0);	}	return 0;}static int __initacpi_parse_lsapic (acpi_table_entry_header *header){	struct acpi_table_lsapic *lsapic;	int phys_id;	lsapic = (struct acpi_table_lsapic *) header;	if (!lsapic)		return -EINVAL;	acpi_table_print_madt_entry(header);	phys_id = (lsapic->id << 8) | lsapic->eid;	if (total_cpus == NR_CPUS) {		printk(KERN_ERR PREFIX "Ignoring CPU (0x%04x) (NR_CPUS == %d)\n",			phys_id, NR_CPUS);		return 0;	}	printk("CPU %d (0x%04x)", total_cpus, phys_id);	if (lsapic->flags.enabled) {		available_cpus++;		printk(" enabled");#ifdef CONFIG_SMP		smp_boot_data.cpu_phys_id[total_cpus] = phys_id;		if (hard_smp_processor_id() == smp_boot_data.cpu_phys_id[total_cpus])			printk(" (BSP)");#endif	}	else {		printk(" disabled");#ifdef CONFIG_SMP		smp_boot_data.cpu_phys_id[total_cpus] = -1;#endif	}	printk("\n");	total_cpus++;	return 0;}

⌨️ 快捷键说明

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