int __init
find_unisys_acpi_oem_table(unsigned long *oem_addr)
{
	struct acpi_table_rsdp		*rsdp = NULL;
	unsigned long			rsdp_phys = 0;
	struct acpi_table_header 	*header = NULL;
	int				i;
	struct acpi_table_sdt		sdt;

	rsdp_phys = acpi_find_rsdp();
	rsdp = __va(rsdp_phys);
	if (rsdp->rsdt_address) {
		struct acpi_table_rsdt	*mapped_rsdt = NULL;
		sdt.pa = rsdp->rsdt_address;

		header = (struct acpi_table_header *)
			__acpi_map_table(sdt.pa, sizeof(struct acpi_table_header));
		if (!header)
			return -ENODEV;

		sdt.count = (header->length - sizeof(struct acpi_table_header)) >> 3;
		mapped_rsdt = (struct acpi_table_rsdt *)
			__acpi_map_table(sdt.pa, header->length);
		if (!mapped_rsdt)
			return -ENODEV;

		header = &mapped_rsdt->header;

		for (i = 0; i < sdt.count; i++)
			sdt.entry[i].pa = (unsigned long) mapped_rsdt->entry[i];
	};
	for (i = 0; i < sdt.count; i++) {

		header = (struct acpi_table_header *)
			__acpi_map_table(sdt.entry[i].pa,
				sizeof(struct acpi_table_header));
		if (!header)
			continue;
		if (!strncmp((char *) &header->signature, "OEM1", 4)) {
			if (!strncmp((char *) &header->oem_id, "UNISYS", 6)) {
				void *addr;
				struct oem_table *t;
				acpi_table_print(header, sdt.entry[i].pa);
				t = (struct oem_table *) __acpi_map_table(sdt.entry[i].pa, header->length);
				addr = (void *) __acpi_map_table(t->OEMTableAddr, t->OEMTableSize);
				*oem_addr = (unsigned long) addr;
				return 0;
			}
		}
	}
	return -1;
}
Exemple #2
0
/*
 * 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)
{
	unsigned int i;
	enum acpi_table_id temp_id;

	/* DSDT is different from the rest */
	if (id == ACPI_DSDT)
		temp_id = ACPI_FADT;
	else
		temp_id = id;

	/* Locate the table. */

	for (i = 0; i < sdt_count; i++) {
		if (sdt_entry[i].id != temp_id)
			continue;
		*header = (void *)
			__acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
		if (!*header) {
			printk(KERN_WARNING PREFIX "Unable to map %s\n",
			       acpi_table_signatures[temp_id]);
			return -ENODEV;
		}
		break;
	}

	if (!*header) {
		printk(KERN_WARNING PREFIX "%s not present\n",
		       acpi_table_signatures[id]);
		return -ENODEV;
	}

	/* Map the DSDT header via the pointer in the FADT */
	if (id == ACPI_DSDT) {
		struct acpi_table_fadt *fadt = (struct acpi_table_fadt *) *header;

		*header = (void *) __acpi_map_table(fadt->dsdt_addr,
				sizeof(struct acpi_table_header));
		if (!*header) {
			printk(KERN_WARNING PREFIX "Unable to map DSDT\n");
			return -ENODEV;
		}
	}

	return 0;
}
Exemple #3
0
static int __init
acpi_parse_madt (
	unsigned long		phys_addr,
	unsigned long		size)
{
	struct acpi_table_madt	*madt = NULL;

	if (!phys_addr || !size)
		return -EINVAL;

	madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size);
	if (!madt) {
		printk(KERN_WARNING PREFIX "Unable to map MADT\n");
		return -ENODEV;
	}

	if (madt->lapic_address)
		acpi_lapic_addr = (u64) madt->lapic_address;

	printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n",
		madt->lapic_address);

	detect_clustered_apic(madt->header.oem_id, madt->header.oem_table_id);

	return 0;
}
static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr)
{
    struct acpi_table_header *header = NULL;
    struct es7000_oem_table *table;
    acpi_size tbl_size;
    acpi_status ret;
    int i = 0;

    for (;;) {
        ret = acpi_get_table_with_size("OEM1", i++, &header, &tbl_size);
        if (!ACPI_SUCCESS(ret))
            return -1;

        if (!memcmp((char *) &header->oem_id, "UNISYS", 6))
            break;

        early_acpi_os_unmap_memory(header, tbl_size);
    }

    table = (void *)header;

    oem_addrX	= table->OEMTableAddr;
    oem_size	= table->OEMTableSize;

    early_acpi_os_unmap_memory(header, tbl_size);

    *oem_addr	= (unsigned long)__acpi_map_table(oem_addrX, oem_size);

    return 0;
}
Exemple #5
0
/* Get pm1x_cnt and pm1x_evt information for ACPI sleep */
static void __init
acpi_fadt_parse_sleep_info(struct acpi_table_fadt *fadt)
{
	struct acpi_table_facs *facs = NULL;
	uint64_t facs_pa;

	acpi_fadt_copy_address(pm1a_cnt, pm1a_control, pm1_control);
	acpi_fadt_copy_address(pm1b_cnt, pm1b_control, pm1_control);
	acpi_fadt_copy_address(pm1a_evt, pm1a_event, pm1_event);
	acpi_fadt_copy_address(pm1b_evt, pm1b_event, pm1_event);

	printk(KERN_INFO PREFIX
	       "ACPI SLEEP INFO: pm1x_cnt[%"PRIx64",%"PRIx64"], "
	       "pm1x_evt[%"PRIx64",%"PRIx64"]\n",
	       acpi_sinfo.pm1a_cnt_blk.address,
	       acpi_sinfo.pm1b_cnt_blk.address,
	       acpi_sinfo.pm1a_evt_blk.address,
	       acpi_sinfo.pm1b_evt_blk.address);

	/* Now FACS... */
	if (fadt->header.revision >= FADT2_REVISION_ID)
		facs_pa = fadt->Xfacs;
	else
		facs_pa = (uint64_t)fadt->facs;

	facs = (struct acpi_table_facs *)
		__acpi_map_table(facs_pa, sizeof(struct acpi_table_facs));
	if (!facs)
		goto bad;

	if (strncmp(facs->signature, "FACS", 4)) {
		printk(KERN_ERR PREFIX "Invalid FACS signature %.4s\n",
			facs->signature);
		goto bad;
	}

	if (facs->length < 24) {
		printk(KERN_ERR PREFIX "Invalid FACS table length: 0x%x",
			facs->length);
		goto bad;
	}

	if (facs->length < 64)
		printk(KERN_WARNING PREFIX
			"FACS is shorter than ACPI spec allow: 0x%x",
			facs->length);

	acpi_sinfo.wakeup_vector = facs_pa + 
		offsetof(struct acpi_table_facs, firmware_waking_vector);
	acpi_sinfo.vector_width = 32;

	printk(KERN_INFO PREFIX
	       "                 wakeup_vec[%"PRIx64"], vec_size[%x]\n",
	       acpi_sinfo.wakeup_vector, acpi_sinfo.vector_width);
	return;
bad:
	memset(&acpi_sinfo, 0, sizeof(acpi_sinfo));
}
Exemple #6
0
int __init
acpi_table_parse_madt_family (
	enum acpi_table_id	id,
	unsigned long		madt_size,
	int			entry_id,
	acpi_madt_entry_handler	handler)
{
	void			*madt = NULL;
	acpi_table_entry_header	*entry = NULL;
	unsigned long		count = 0;
	unsigned long		madt_end = 0;
	unsigned int			i = 0;

	if (!handler)
		return -EINVAL;

	/* Locate the MADT (if exists). There should only be one. */

	for (i = 0; i < sdt_count; i++) {
		if (sdt_entry[i].id != id)
			continue;
		madt = (void *)
			__acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
		if (!madt) {
			printk(KERN_WARNING PREFIX "Unable to map %s\n",
			       acpi_table_signatures[id]);
			return -ENODEV;
		}
		break;
	}

	if (!madt) {
		printk(KERN_WARNING PREFIX "%s not present\n",
		       acpi_table_signatures[id]);
		return -ENODEV;
	}

	madt_end = (unsigned long) madt + sdt_entry[i].size;

	/* Parse all entries looking for a match. */

	entry = (acpi_table_entry_header *)
		((unsigned long) madt + madt_size);

	while (((unsigned long) entry) < madt_end) {
		if (entry->type == entry_id) {
			count++;
			handler(entry);
		}
		entry = (acpi_table_entry_header *)
			((unsigned long) entry + entry->length);
	}

	return count;
}
Exemple #7
0
void __iomem *__init_refok
acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
{
	struct acpi_ioremap *map;
	void __iomem *virt;
	acpi_physical_address pg_off;
	acpi_size pg_sz;

	if (phys > ULONG_MAX) {
		printk(KERN_ERR PREFIX "Cannot map memory that high\n");
		return NULL;
	}

	if (!acpi_gbl_permanent_mmap)
		return __acpi_map_table((unsigned long)phys, size);

	mutex_lock(&acpi_ioremap_lock);
	/* Check if there's a suitable mapping already. */
	map = acpi_map_lookup(phys, size);
	if (map) {
		map->refcount++;
		goto out;
	}

	map = kzalloc(sizeof(*map), GFP_KERNEL);
	if (!map) {
		mutex_unlock(&acpi_ioremap_lock);
		return NULL;
	}

	pg_off = round_down(phys, PAGE_SIZE);
	pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
	virt = acpi_map(pg_off, pg_sz);
	if (!virt) {
		mutex_unlock(&acpi_ioremap_lock);
		kfree(map);
		return NULL;
	}

	INIT_LIST_HEAD(&map->list);
	map->virt = virt;
	map->phys = pg_off;
	map->size = pg_sz;
	map->refcount = 1;

	list_add_tail_rcu(&map->list, &acpi_ioremaps);

 out:
	mutex_unlock(&acpi_ioremap_lock);
	return map->virt + (phys - map->phys);
}
Exemple #8
0
void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
{
	if (phys > ULONG_MAX) {
		printk(KERN_ERR PREFIX "Cannot map memory that high\n");
		return NULL;
	}
	if (acpi_gbl_permanent_mmap)
		/*
		* ioremap checks to ensure this is in reserved space
		*/
		return ioremap((unsigned long)phys, size);
	else
		return __acpi_map_table((unsigned long)phys, size);
}
int __init
find_unisys_acpi_oem_table(unsigned long *oem_addr)
{
	struct acpi_table_header *header = NULL;
	int i = 0;
	while (ACPI_SUCCESS(acpi_get_table("OEM1", i++, &header))) {
		if (!memcmp((char *) &header->oem_id, "UNISYS", 6)) {
			struct oem_table *t = (struct oem_table *)header;
			*oem_addr = (unsigned long)__acpi_map_table(t->OEMTableAddr,
								    t->OEMTableSize);
			return 0;
		}
	}
	return -1;
}
Exemple #10
0
static int __init
acpi_parse_fadt(unsigned long phys, unsigned long size)
{
        struct fadt_descriptor_rev2 *fadt =0;

        fadt = (struct fadt_descriptor_rev2*) __acpi_map_table(phys,size);
        if (!fadt) {
                printk(KERN_WARNING PREFIX "Unable to map FADT\n");
                return 0;
        }

#ifdef  CONFIG_ACPI_INTERPRETER
        /* initialize sci_int early for INT_SRC_OVR MADT parsing */
        acpi_fadt.sci_int = fadt->sci_int;
#endif

        return 0;
}
Exemple #11
0
static void acpi_sleep_prepare(u32 state)
{
    void *wakeup_vector_va;

    if ( state != ACPI_STATE_S3 )
        return;

    wakeup_vector_va = __acpi_map_table(
        acpi_sinfo.wakeup_vector, sizeof(uint64_t));

    /* TBoot will set resume vector itself (when it is safe to do so). */
    if ( tboot_in_measured_env() )
        return;

    if ( acpi_sinfo.vector_width == 32 )
        *(uint32_t *)wakeup_vector_va = bootsym_phys(wakeup_start);
    else
        *(uint64_t *)wakeup_vector_va = bootsym_phys(wakeup_start);
}
Exemple #12
0
static int __init 
acpi_parse_mcfg(unsigned long phys_addr,
		unsigned long size)
{
	struct acpi_table_mcfg *mcfg = NULL;

	if (!phys_addr || !size)
		return -EINVAL;

	mcfg = (struct acpi_table_mcfg *) __acpi_map_table(phys_addr, size);
	if (!mcfg) {
		printk(KERN_WARNING PREFIX "Unable to map MCFG\n");
		return -ENODEV;
	}

	if (mcfg->base_reserved) {
		printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n");
		return -ENODEV;
	}

	pci_mmcfg_base_addr = mcfg->base_address;

	return 0;
}
Exemple #13
0
/* Get pm1x_cnt and pm1x_evt information for ACPI sleep */
static void __init
acpi_fadt_parse_sleep_info(struct acpi_table_fadt *fadt)
{
	struct acpi_table_facs *facs = NULL;
	uint64_t facs_pa;

	if (fadt->header.revision >= 5 &&
	    fadt->header.length >= ACPI_FADT_V5_SIZE) {
		acpi_sinfo.sleep_control = fadt->sleep_control;
		acpi_sinfo.sleep_status = fadt->sleep_status;

		printk(KERN_INFO PREFIX
		       "v5 SLEEP INFO: control[%d:%"PRIx64"],"
		       " status[%d:%"PRIx64"]\n",
		       acpi_sinfo.sleep_control.space_id,
		       acpi_sinfo.sleep_control.address,
		       acpi_sinfo.sleep_status.space_id,
		       acpi_sinfo.sleep_status.address);

		if ((fadt->sleep_control.address &&
		     (fadt->sleep_control.bit_offset ||
		      fadt->sleep_control.bit_width !=
		      fadt->sleep_control.access_width * 8)) ||
		    (fadt->sleep_status.address &&
		     (fadt->sleep_status.bit_offset ||
		      fadt->sleep_status.bit_width !=
		      fadt->sleep_status.access_width * 8))) {
			printk(KERN_WARNING PREFIX
			       "Invalid sleep control/status register data:"
			       " %#x:%#x:%#x %#x:%#x:%#x\n",
			       fadt->sleep_control.bit_offset,
			       fadt->sleep_control.bit_width,
			       fadt->sleep_control.access_width,
			       fadt->sleep_status.bit_offset,
			       fadt->sleep_status.bit_width,
			       fadt->sleep_status.access_width);
			fadt->sleep_control.address = 0;
			fadt->sleep_status.address = 0;
		}
	}

	if (fadt->flags & ACPI_FADT_HW_REDUCED)
		goto bad;

	acpi_fadt_copy_address(pm1a_cnt, pm1a_control, pm1_control);
	acpi_fadt_copy_address(pm1b_cnt, pm1b_control, pm1_control);
	acpi_fadt_copy_address(pm1a_evt, pm1a_event, pm1_event);
	acpi_fadt_copy_address(pm1b_evt, pm1b_event, pm1_event);

	printk(KERN_INFO PREFIX
	       "SLEEP INFO: pm1x_cnt[%"PRIx64",%"PRIx64"], "
	       "pm1x_evt[%"PRIx64",%"PRIx64"]\n",
	       acpi_sinfo.pm1a_cnt_blk.address,
	       acpi_sinfo.pm1b_cnt_blk.address,
	       acpi_sinfo.pm1a_evt_blk.address,
	       acpi_sinfo.pm1b_evt_blk.address);

	/* Now FACS... */
	facs_pa = ((fadt->header.revision >= FADT2_REVISION_ID)
		   ? fadt->Xfacs : (uint64_t)fadt->facs);
	if (fadt->facs && ((uint64_t)fadt->facs != facs_pa)) {
		printk(KERN_WARNING PREFIX
		       "32/64X FACS address mismatch in FADT - "
		       "%08x/%016"PRIx64", using 32\n",
		       fadt->facs, facs_pa);
		facs_pa = (uint64_t)fadt->facs;
	}
	if (!facs_pa)
		goto bad;

	facs = (struct acpi_table_facs *)
		__acpi_map_table(facs_pa, sizeof(struct acpi_table_facs));
	if (!facs)
		goto bad;

	if (strncmp(facs->signature, "FACS", 4)) {
		printk(KERN_ERR PREFIX "Invalid FACS signature %.4s\n",
			facs->signature);
		goto bad;
	}

	if (facs->length < 24) {
		printk(KERN_ERR PREFIX "Invalid FACS table length: %#x",
			facs->length);
		goto bad;
	}

	if (facs->length < 64)
		printk(KERN_WARNING PREFIX
			"FACS is shorter than ACPI spec allow: %#x",
			facs->length);

	acpi_sinfo.wakeup_vector = facs_pa + 
		offsetof(struct acpi_table_facs, firmware_waking_vector);
	acpi_sinfo.vector_width = 32;

	printk(KERN_INFO PREFIX
	       "            wakeup_vec[%"PRIx64"], vec_size[%x]\n",
	       acpi_sinfo.wakeup_vector, acpi_sinfo.vector_width);
	return;
bad:
	memset(&acpi_sinfo, 0,
	       offsetof(struct acpi_sleep_info, sleep_control));
	memset(&acpi_sinfo.sleep_status + 1, 0,
	       (long)(&acpi_sinfo + 1) - (long)(&acpi_sinfo.sleep_status + 1));
}
Exemple #14
0
static int __init
acpi_table_get_sdt (
	struct acpi_table_rsdp	*rsdp)
{
	struct acpi_table_header *header = NULL;
	unsigned int		i, id = 0;

	if (!rsdp)
		return -EINVAL;

	/* First check XSDT (but only on ACPI 2.0-compatible systems) */

	if ((rsdp->revision >= 2) &&
		(((struct acpi20_table_rsdp*)rsdp)->xsdt_address)) {
			
		struct acpi_table_xsdt	*mapped_xsdt = NULL;

		sdt_pa = ((struct acpi20_table_rsdp*)rsdp)->xsdt_address;

		/* map in just the header */
		header = (struct acpi_table_header *)
			__acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));

		if (!header) {
			printk(KERN_WARNING PREFIX "Unable to map XSDT header\n");
			return -ENODEV;
		}

		/* remap in the entire table before processing */
		mapped_xsdt = (struct acpi_table_xsdt *)
			__acpi_map_table(sdt_pa, header->length);
		if (!mapped_xsdt) {
			printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
			return -ENODEV;
		}
		header = &mapped_xsdt->header;

		if (strncmp(header->signature, "XSDT", 4)) {
			printk(KERN_WARNING PREFIX "XSDT signature incorrect\n");
			return -ENODEV;
		}

		if (acpi_table_compute_checksum(header, header->length)) {
			printk(KERN_WARNING PREFIX "Invalid XSDT checksum\n");
			return -ENODEV;
		}

		sdt_count = (header->length - sizeof(struct acpi_table_header)) >> 3;
		if (sdt_count > ACPI_MAX_TABLES) {
			printk(KERN_WARNING PREFIX "Truncated %lu XSDT entries\n",
				(sdt_count - ACPI_MAX_TABLES));
			sdt_count = ACPI_MAX_TABLES;
		}

		for (i = 0; i < sdt_count; i++)
			sdt_entry[i].pa = (unsigned long) mapped_xsdt->entry[i];
	}

	/* Then check RSDT */

	else if (rsdp->rsdt_address) {
Exemple #15
0
		for (i = 0; i < sdt_count; i++)
			sdt_entry[i].pa = (unsigned long) mapped_xsdt->entry[i];
	}

	/* Then check RSDT */

	else if (rsdp->rsdt_address) {

		struct acpi_table_rsdt	*mapped_rsdt = NULL;

		sdt_pa = rsdp->rsdt_address;

		/* map in just the header */
		header = (struct acpi_table_header *)
			__acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
		if (!header) {
			printk(KERN_WARNING PREFIX "Unable to map RSDT header\n");
			return -ENODEV;
		}

		/* remap in the entire table before processing */
		mapped_rsdt = (struct acpi_table_rsdt *)
			__acpi_map_table(sdt_pa, header->length);
		if (!mapped_rsdt) {
			printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
			return -ENODEV;
		}
		header = &mapped_rsdt->header;

		if (strncmp(header->signature, "RSDT", 4)) {
Exemple #16
0
void __iomem *
acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
{
	return __acpi_map_table((unsigned long)phys, size);
}