Exemple #1
0
/*
 * Search through the EBDA for the BIOS Memory Console, and
 * set the global variables to point to it.  Return true if found.
 */
static bool found_memconsole(void)
{
	unsigned int address;
	size_t length, cur;

	address = get_bios_ebda();
	if (!address) {
		printk(KERN_INFO "BIOS EBDA non-existent.\n");
		return false;
	}

	/* EBDA length is byte 0 of EBDA (in KB) */
	length = *(u8 *)phys_to_virt(address);
	length <<= 10; /* convert to bytes */

	/*
	 * Search through EBDA for BIOS memory console structure
	 * note: signature is not necessarily dword-aligned
	 */
	for (cur = 0; cur < length; cur++) {
		struct biosmemcon_ebda *hdr = phys_to_virt(address + cur);

		/* memconsole v1 */
		if (hdr->signature == BIOS_MEMCONSOLE_V1_MAGIC) {
			found_v1_header(hdr);
			return true;
		}

		/* memconsole v2 */
		if (hdr->signature == BIOS_MEMCONSOLE_V2_MAGIC) {
			found_v2_header(hdr);
			return true;
		}
	}

	printk(KERN_INFO "BIOS console EBDA structure not found!\n");
	return false;
}
void __init reserve_ebda_region(void)
{
	unsigned int lowmem, ebda_addr;

	/*                                               */
	/*                                                */
	/*                                                  */
	/*                                                */
	/*                                                */
	/*                              */
	if (paravirt_enabled())
		return;

	/*                                  */
	lowmem = *(unsigned short *)__va(BIOS_LOWMEM_KILOBYTES);
	lowmem <<= 10;

	/*                    */
	ebda_addr = get_bios_ebda();

	/*                                                 */
	/*                                                     */
	if ((lowmem - ebda_addr) <= 0x10000)
		lowmem = ebda_addr;

	/*                                             */
	/*                                                       */
	if ((ebda_addr == 0) && (lowmem >= 0x9f000))
		lowmem = 0x9f000;

	/*                                       */
	if ((lowmem == 0) || (lowmem >= 0x100000))
		lowmem = 0x9f000;

	/*                                                    */
	memblock_reserve(lowmem, 0x100000 - lowmem);
}
void __init reserve_ebda_region(void)
{
	unsigned int lowmem, ebda_addr;

	/* To determine the position of the EBDA and the */
	/* end of conventional memory, we need to look at */
	/* the BIOS data area. In a paravirtual environment */
	/* that area is absent. We'll just have to assume */
	/* that the paravirt case can handle memory setup */
	/* correctly, without our help. */
	if (paravirt_enabled())
		return;

	/* end of low (conventional) memory */
	lowmem = *(unsigned short *)__va(BIOS_LOWMEM_KILOBYTES);
	lowmem <<= 10;

	/* start of EBDA area */
	ebda_addr = get_bios_ebda();

	/* Fixup: bios puts an EBDA in the top 64K segment */
	/* of conventional memory, but does not adjust lowmem. */
	if ((lowmem - ebda_addr) <= 0x10000)
		lowmem = ebda_addr;

	/* Fixup: bios does not report an EBDA at all. */
	/* Some old Dells seem to need 4k anyhow (bugzilla 2990) */
	if ((ebda_addr == 0) && (lowmem >= 0x9f000))
		lowmem = 0x9f000;

	/* Paranoia: should never happen, but... */
	if ((lowmem == 0) || (lowmem >= 0x100000))
		lowmem = 0x9f000;

	/* reserve all memory between lowmem and the 1MB mark */
	reserve_early_overlap_ok(lowmem, 0x100000, "BIOS reserved");
}
Exemple #4
0
static int __init ibm_rtl_init(void) {
	unsigned long ebda_addr, ebda_size;
	unsigned int ebda_kb;
	int ret = -ENODEV, i;

	if (force)
		pr_warn("module loaded by force\n");
	/* first ensure that we are running on IBM HW */
	else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table))
		return -ENODEV;

	/* Get the address for the Extended BIOS Data Area */
	ebda_addr = get_bios_ebda();
	if (!ebda_addr) {
		RTL_DEBUG("no BIOS EBDA found\n");
		return -ENODEV;
	}

	ebda_map = ioremap(ebda_addr, 4);
	if (!ebda_map)
		return -ENOMEM;

	/* First word in the EDBA is the Size in KB */
	ebda_kb = ioread16(ebda_map);
	RTL_DEBUG("EBDA is %d kB\n", ebda_kb);

	if (ebda_kb == 0)
		goto out;

	iounmap(ebda_map);
	ebda_size = ebda_kb*1024;

	/* Remap the whole table */
	ebda_map = ioremap(ebda_addr, ebda_size);
	if (!ebda_map)
		return -ENOMEM;

	/* search for the _RTL_ signature at the start of the table */
	for (i = 0 ; i < ebda_size/sizeof(unsigned int); i++) {
		struct ibm_rtl_table __iomem * tmp;
		tmp = (struct ibm_rtl_table __iomem *) (ebda_map+i);
		if ((readq(&tmp->signature) & RTL_MASK) == RTL_SIGNATURE) {
			phys_addr_t addr;
			unsigned int plen;
			RTL_DEBUG("found RTL_SIGNATURE at %p\n", tmp);
			rtl_table = tmp;
			/* The address, value, width and offset are platform
			 * dependent and found in the ibm_rtl_table */
			rtl_cmd_width = ioread8(&rtl_table->cmd_granularity);
			rtl_cmd_type = ioread8(&rtl_table->cmd_address_type);
			RTL_DEBUG("rtl_cmd_width = %u, rtl_cmd_type = %u\n",
				  rtl_cmd_width, rtl_cmd_type);
			addr = ioread32(&rtl_table->cmd_port_address);
			RTL_DEBUG("addr = %#llx\n", (unsigned long long)addr);
			plen = rtl_cmd_width/sizeof(char);
			rtl_cmd_addr = rtl_port_map(addr, plen);
			RTL_DEBUG("rtl_cmd_addr = %p\n", rtl_cmd_addr);
			if (!rtl_cmd_addr) {
				ret = -ENOMEM;
				break;
			}
			ret = rtl_setup_sysfs();
			break;
		}
	}

out:
	if (ret) {
		iounmap(ebda_map);
		rtl_port_unmap(rtl_cmd_addr);
	}

	return ret;
}
static int __init ibm_rtl_init(void) {
    unsigned long ebda_addr, ebda_size;
    unsigned int ebda_kb;
    int ret = -ENODEV, i;

    if (force)
        pr_warn("module loaded by force\n");

    else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table))
        return -ENODEV;


    ebda_addr = get_bios_ebda();
    if (!ebda_addr) {
        RTL_DEBUG("no BIOS EBDA found\n");
        return -ENODEV;
    }

    ebda_map = ioremap(ebda_addr, 4);
    if (!ebda_map)
        return -ENOMEM;


    ebda_kb = ioread16(ebda_map);
    RTL_DEBUG("EBDA is %d kB\n", ebda_kb);

    if (ebda_kb == 0)
        goto out;

    iounmap(ebda_map);
    ebda_size = ebda_kb*1024;


    ebda_map = ioremap(ebda_addr, ebda_size);
    if (!ebda_map)
        return -ENOMEM;


    for (i = 0 ; i < ebda_size/sizeof(unsigned int); i++) {
        struct ibm_rtl_table __iomem * tmp;
        tmp = (struct ibm_rtl_table __iomem *) (ebda_map+i);
        if ((readq(&tmp->signature) & RTL_MASK) == RTL_SIGNATURE) {
            phys_addr_t addr;
            unsigned int plen;
            RTL_DEBUG("found RTL_SIGNATURE at %p\n", tmp);
            rtl_table = tmp;
            rtl_cmd_width = ioread8(&rtl_table->cmd_granularity);
            rtl_cmd_type = ioread8(&rtl_table->cmd_address_type);
            RTL_DEBUG("rtl_cmd_width = %u, rtl_cmd_type = %u\n",
                      rtl_cmd_width, rtl_cmd_type);
            addr = ioread32(&rtl_table->cmd_port_address);
            RTL_DEBUG("addr = %#llx\n", (unsigned long long)addr);
            plen = rtl_cmd_width/sizeof(char);
            rtl_cmd_addr = rtl_port_map(addr, plen);
            RTL_DEBUG("rtl_cmd_addr = %p\n", rtl_cmd_addr);
            if (!rtl_cmd_addr) {
                ret = -ENOMEM;
                break;
            }
            ret = rtl_setup_sysfs();
            break;
        }
    }

out:
    if (ret) {
        iounmap(ebda_map);
        rtl_port_unmap(rtl_cmd_addr);
    }

    return ret;
}