예제 #1
0
/*
 *	cru_detect
 *
 *	Routine Description:
 *	This function uses the 32-bit BIOS Service Directory record to
 *	search for a $CRU record.
 *
 *	Return Value:
 *	0        :  SUCCESS
 *	<0       :  FAILURE
 */
static int __devinit cru_detect(unsigned long map_entry,
	unsigned long map_offset)
{
	void *bios32_map;
	unsigned long *bios32_entrypoint;
	unsigned long cru_physical_address;
	unsigned long cru_length;
	unsigned long physical_bios_base = 0;
	unsigned long physical_bios_offset = 0;
	int retval = -ENODEV;

	bios32_map = ioremap(map_entry, (2 * PAGE_SIZE));

	if (bios32_map == NULL)
		return -ENODEV;

	bios32_entrypoint = bios32_map + map_offset;

	cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE;

	set_memory_x((unsigned long)bios32_entrypoint, (2 * PAGE_SIZE));
	asminline_call(&cmn_regs, bios32_entrypoint);

	if (cmn_regs.u1.ral != 0) {
		printk(KERN_WARNING
			"hpwdt: Call succeeded but with an error: 0x%x\n",
			cmn_regs.u1.ral);
	} else {
		physical_bios_base = cmn_regs.u2.rebx;
		physical_bios_offset = cmn_regs.u4.redx;
		cru_length = cmn_regs.u3.recx;
		cru_physical_address =
			physical_bios_base + physical_bios_offset;

		/* If the values look OK, then map it in. */
		if ((physical_bios_base + physical_bios_offset)) {
			cru_rom_addr =
				ioremap(cru_physical_address, cru_length);
			if (cru_rom_addr) {
				set_memory_x((unsigned long)cru_rom_addr, cru_length);
				retval = 0;
			}
		}

		printk(KERN_DEBUG "hpwdt: CRU Base Address:   0x%lx\n",
			physical_bios_base);
		printk(KERN_DEBUG "hpwdt: CRU Offset Address: 0x%lx\n",
			physical_bios_offset);
		printk(KERN_DEBUG "hpwdt: CRU Length:         0x%lx\n",
			cru_length);
		printk(KERN_DEBUG "hpwdt: CRU Mapped Address: 0x%x\n",
			(unsigned int)&cru_rom_addr);
	}
	iounmap(bios32_map);
	return retval;
}
예제 #2
0
파일: hpwdt.c 프로젝트: Chong-Li/cse522
/*
 *	cru_detect
 *
 *	Routine Description:
 *	This function uses the 32-bit BIOS Service Directory record to
 *	search for a $CRU record.
 *
 *	Return Value:
 *	0        :  SUCCESS
 *	<0       :  FAILURE
 */
static int cru_detect(unsigned long map_entry,
	unsigned long map_offset)
{
	void *bios32_map;
	unsigned long *bios32_entrypoint;
	unsigned long cru_physical_address;
	unsigned long cru_length;
	unsigned long physical_bios_base = 0;
	unsigned long physical_bios_offset = 0;
	int retval = -ENODEV;

	bios32_map = ioremap(map_entry, (2 * PAGE_SIZE));

	if (bios32_map == NULL)
		return -ENODEV;

	bios32_entrypoint = bios32_map + map_offset;

	cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE;

	set_memory_x((unsigned long)bios32_map, 2);
	asminline_call(&cmn_regs, bios32_entrypoint);

	if (cmn_regs.u1.ral != 0) {
		pr_warn("Call succeeded but with an error: 0x%x\n",
			cmn_regs.u1.ral);
	} else {
		physical_bios_base = cmn_regs.u2.rebx;
		physical_bios_offset = cmn_regs.u4.redx;
		cru_length = cmn_regs.u3.recx;
		cru_physical_address =
			physical_bios_base + physical_bios_offset;

		/* If the values look OK, then map it in. */
		if ((physical_bios_base + physical_bios_offset)) {
			cru_rom_addr =
				ioremap(cru_physical_address, cru_length);
			if (cru_rom_addr) {
				set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK,
					(cru_length + PAGE_SIZE - 1) >> PAGE_SHIFT);
				retval = 0;
			}
		}

		pr_debug("CRU Base Address:   0x%lx\n", physical_bios_base);
		pr_debug("CRU Offset Address: 0x%lx\n", physical_bios_offset);
		pr_debug("CRU Length:         0x%lx\n", cru_length);
		pr_debug("CRU Mapped Address: %p\n", &cru_rom_addr);
	}