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

📄 acpi.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
		return -ENODEV;	p = (char *) (acpi_madt + 1);	end = p + (acpi_madt->header.length - sizeof(struct acpi_table_madt));	while (p < end) {		if (*p == ACPI_MADT_IOSAPIC) {			iosapic = (struct acpi_table_iosapic *) p;			*gsi_base = iosapic->global_irq_base;			*iosapic_address = ioremap(iosapic->address, 0);			ver = iosapic_version(*iosapic_address);			max_pin = (ver >> 16) & 0xff;			if ((gsi - *gsi_base) <= max_pin)				return 0;	/* Found it! */		}		p += p[1];	}	return -ENODEV;}static int __initacpi_parse_iosapic (acpi_table_entry_header *header){	struct acpi_table_iosapic *iosapic;	iosapic = (struct acpi_table_iosapic *) header;	if (!iosapic)		return -EINVAL;	acpi_table_print_madt_entry(header);	if (iosapic_init) {#ifndef CONFIG_ITANIUM		/* PCAT_COMPAT flag indicates dual-8259 setup */		iosapic_init(iosapic->address, iosapic->global_irq_base,			     acpi_madt->flags.pcat_compat);#else		/* Firmware on old Itanium systems is broken */		iosapic_init(iosapic->address, iosapic->global_irq_base, 1);#endif	}	return 0;}static int __initacpi_parse_plat_int_src (acpi_table_entry_header *header){	struct acpi_table_plat_int_src *plintsrc;	int vector;	u32 gsi_base;	char *iosapic_address;	plintsrc = (struct acpi_table_plat_int_src *) header;	if (!plintsrc)		return -EINVAL;	acpi_table_print_madt_entry(header);	if (!iosapic_register_platform_intr) {		printk(KERN_WARNING PREFIX "No ACPI platform interrupt support\n");		return -ENODEV;	}	if (acpi_find_iosapic(plintsrc->global_irq, &gsi_base, &iosapic_address)) {		printk(KERN_WARNING PREFIX "IOSAPIC not found\n");		return -ENODEV;	}	/*	 * 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->iosapic_vector,						plintsrc->eid,						plintsrc->id,						(plintsrc->flags.polarity == 1) ? 1 : 0,						(plintsrc->flags.trigger == 1) ? 1 : 0,						gsi_base,						iosapic_address);	platform_intr_list[plintsrc->type] = vector;	return 0;}static int __initacpi_parse_int_src_ovr (acpi_table_entry_header *header){	struct acpi_table_int_src_ovr *p;	p = (struct acpi_table_int_src_ovr *) header;	if (!p)		return -EINVAL;	acpi_table_print_madt_entry(header);	/* Ignore if the platform doesn't support overrides */	if (!iosapic_override_isa_irq)		return 0;	iosapic_override_isa_irq(p->bus_irq, p->global_irq,				 (p->flags.polarity == 1) ? 1 : 0,				 (p->flags.trigger == 1) ? 1 : 0);	return 0;}static int __initacpi_parse_nmi_src (acpi_table_entry_header *header){	struct acpi_table_nmi_src *nmi_src;	nmi_src = (struct acpi_table_nmi_src*) header;	if (!nmi_src)		return -EINVAL;	acpi_table_print_madt_entry(header);	/* TBD: Support nimsrc entries */	return 0;}static int __initacpi_parse_madt (unsigned long phys_addr, unsigned long size){	if (!phys_addr || !size)		return -EINVAL;	acpi_madt = (struct acpi_table_madt *) __va(phys_addr);	/* remember the value for reference after free_initmem() */	has_8259 = acpi_madt->flags.pcat_compat;	/* Get base address of IPI Message Block */	if (acpi_madt->lapic_address)		ipi_base_addr = (unsigned long) ioremap(acpi_madt->lapic_address, 0);	printk(KERN_INFO PREFIX "Local APIC address 0x%lx\n", ipi_base_addr);	return 0;}static int __initacpi_parse_fadt (unsigned long phys_addr, unsigned long size){	struct acpi_table_header *fadt_header;	fadt_descriptor_rev2 *fadt;	u32 sci_irq, gsi_base;	char *iosapic_address;	if (!phys_addr || !size)		return -EINVAL;	fadt_header = (struct acpi_table_header *) __va(phys_addr);	if (fadt_header->revision != 3)		return -ENODEV;		/* Only deal with ACPI 2.0 FADT */	fadt = (fadt_descriptor_rev2 *) fadt_header;	if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER))		acpi_kbd_controller_present = 0;	sci_irq = fadt->sci_int;	if (has_8259 && sci_irq < 16)		return 0;	/* legacy, no setup required */	if (!iosapic_register_intr)		return -ENODEV;	if (!acpi_find_iosapic(sci_irq, &gsi_base, &iosapic_address))		iosapic_register_intr(sci_irq, 0, 0, gsi_base, iosapic_address);	return 0;}#ifdef CONFIG_SERIAL_ACPI#include <linux/acpi_serial.h>static int __initacpi_parse_spcr (unsigned long phys_addr, unsigned long size){	acpi_ser_t *spcr;	u32 gsi, gsi_base;	char *iosapic_address;	if (!phys_addr || !size)		return -EINVAL;	if (!iosapic_register_intr)		return -ENODEV;	/*	 * ACPI is able to describe serial ports that live at non-standard	 * memory addresses and use non-standard interrupts, either via	 * direct SAPIC mappings or via PCI interrupts.  We handle interrupt	 * routing for SAPIC-based (non-PCI) devices here.  Interrupt routing	 * for PCI devices will be handled when processing the PCI Interrupt	 * Routing Table (PRT).	 */	spcr = (acpi_ser_t *) __va(phys_addr);	setup_serial_acpi(spcr);	if (spcr->length < sizeof(acpi_ser_t))		/* Table not long enough for full info, thus no interrupt */		return -ENODEV;	if ((spcr->base_addr.space_id != ACPI_SERIAL_PCICONF_SPACE) &&	    (spcr->int_type == ACPI_SERIAL_INT_SAPIC)) {		/* We have a UART in memory space with an SAPIC interrupt */		gsi = (spcr->global_int[3] << 24) |		      (spcr->global_int[2] << 16) |		      (spcr->global_int[1] << 8)  |		      (spcr->global_int[0]);		if (!acpi_find_iosapic(gsi, &gsi_base, &iosapic_address))			iosapic_register_intr(gsi, 1, 1,					      gsi_base, iosapic_address);	}	return 0;}#endif /*CONFIG_SERIAL_ACPI*/unsigned long __initacpi_find_rsdp (void){	unsigned long rsdp_phys = 0;	if (efi.acpi20)		rsdp_phys = __pa(efi.acpi20);	else if (efi.acpi)		printk(KERN_WARNING PREFIX "v1.0/r0.71 tables no longer supported\n");	return rsdp_phys;}int __initacpi_boot_init (char *cmdline){	int result;	/* Initialize the ACPI boot-time table parser */	result = acpi_table_init(cmdline);	if (result)		return result;	/*	 * MADT	 * ----	 * Parse the Multiple APIC Description Table (MADT), if exists.	 * Note that this table provides platform SMP configuration	 * information -- the successor to MPS tables.	 */	if (acpi_table_parse(ACPI_APIC, acpi_parse_madt) < 1) {		printk(KERN_ERR PREFIX "Can't find MADT\n");		goto skip_madt;	}	/* Local APIC */	if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR,				  acpi_parse_lapic_addr_ovr) < 0)		printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");	if (acpi_table_parse_madt(ACPI_MADT_LSAPIC,				  acpi_parse_lsapic) < 1)		printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n");	if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI,				  acpi_parse_lapic_nmi) < 0)		printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");	/* I/O APIC */	if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC,				  acpi_parse_iosapic) < 1)		printk(KERN_ERR PREFIX "Error parsing MADT - no IOAPIC entries\n");	/* System-Level Interrupt Routing */	if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC,				  acpi_parse_plat_int_src) < 0)		printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n");	if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR,				  acpi_parse_int_src_ovr) < 0)		printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");	if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC,				  acpi_parse_nmi_src) < 0)		printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");skip_madt:	/*	 * The FADT table contains an SCI_INT line, by which the system	 * gets interrupts such as power and sleep buttons.  If it's not	 * on a Legacy interrupt, it needs to be setup.	 */	if (acpi_table_parse(ACPI_FACP, acpi_parse_fadt) < 1)		printk(KERN_ERR PREFIX "Can't find FADT\n");#ifdef CONFIG_SERIAL_ACPI	acpi_table_parse(ACPI_SPCR, acpi_parse_spcr);#endif#ifdef CONFIG_SMP	if (available_cpus == 0) {		printk("ACPI: Found 0 CPUS; assuming 1\n");		available_cpus = 1; /* We've got at least one of these, no? */	}	smp_boot_data.cpu_count = total_cpus;#endif	/* Make boot-up look pretty */	printk("%d CPUs available, %d CPUs total\n", available_cpus, total_cpus);	return 0;}/* --------------------------------------------------------------------------                             PCI Interrupt Routing   -------------------------------------------------------------------------- */int __initacpi_get_prt (struct pci_vector_struct **vectors, int *count){	struct pci_vector_struct *vector;	struct list_head *node;	struct acpi_prt_entry *entry;	int i = 0;	if (!vectors || !count)		return -EINVAL;	*vectors = NULL;	*count = 0;	if (acpi_prt.count < 0) {		printk(KERN_ERR PREFIX "No PCI interrupt routing entries\n");		return -ENODEV;	}	/* Allocate vectors */	*vectors = kmalloc(sizeof(struct pci_vector_struct) * acpi_prt.count, GFP_KERNEL);	if (!(*vectors))		return -ENOMEM;	/* Convert PRT entries to IOSAPIC PCI vectors */	vector = *vectors;	list_for_each(node, &acpi_prt.entries) {		entry = (struct acpi_prt_entry *)node;		vector[i].segment = entry->id.segment;		vector[i].bus    = entry->id.bus;		vector[i].pci_id = ((u32) entry->id.device << 16) | 0xffff;		vector[i].pin    = entry->pin;		vector[i].irq    = entry->link.index;		i++;	}	*count = acpi_prt.count;	return 0;}/* Assume IA64 always use I/O SAPIC */int __initacpi_get_interrupt_model (int *type){        if (!type)                return -EINVAL;	*type = ACPI_IRQ_MODEL_IOSAPIC;        return 0;}intacpi_irq_to_vector (u32 irq){	if (has_8259 && irq < 16)		return isa_irq_to_vector(irq);	return gsi_to_vector(irq);}#endif /* CONFIG_ACPI_BOOT */

⌨️ 快捷键说明

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