Esempio n. 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;
}
static void __init early_mapping_set_exec(unsigned long start,
					  unsigned long end,
					  int executable)
{
	unsigned long num_pages;

	start &= PMD_MASK;
	end = (end + PMD_SIZE - 1) & PMD_MASK;
	num_pages = (end - start) >> PAGE_SHIFT;
	if (executable)
		set_memory_x((unsigned long)__va(start), num_pages);
	else
		set_memory_nx((unsigned long)__va(start), num_pages);
}
Esempio n. 3
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 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);
	}
/**
 * Initialize module.
 *
 * @returns appropriate status code.
 */
static int __init VBoxDrvLinuxInit(void)
{
    int       rc;

    /*
     * Check for synchronous/asynchronous TSC mode.
     */
    printk(KERN_DEBUG "vboxdrv: Found %u processor cores\n", (unsigned)RTMpGetOnlineCount());
#ifdef CONFIG_VBOXDRV_AS_MISC
    rc = misc_register(&gMiscDeviceSys);
    if (rc)
    {
        printk(KERN_ERR "vboxdrv: Can't register system misc device! rc=%d\n", rc);
        return rc;
    }
    rc = misc_register(&gMiscDeviceUsr);
    if (rc)
    {
        printk(KERN_ERR "vboxdrv: Can't register user misc device! rc=%d\n", rc);
        misc_deregister(&gMiscDeviceSys);
        return rc;
    }
#else  /* !CONFIG_VBOXDRV_AS_MISC */
    /*
     * Register character devices and save the returned major numbers.
     */
    /* /dev/vboxdrv */
    g_iModuleMajorSys = DEVICE_MAJOR_SYS;
    rc = register_chrdev((dev_t)g_iModuleMajorSys, DEVICE_NAME_SYS, &gFileOpsVBoxDrvSys);
    if (rc < 0)
    {
        Log(("register_chrdev() failed with rc=%#x for vboxdrv!\n", rc));
        return rc;
    }
    if (DEVICE_MAJOR_SYS != 0)
        g_iModuleMajorSys = DEVICE_MAJOR_SYS;
    else
        g_iModuleMajorSys = rc;

    /* /dev/vboxdrvu */
    /** @todo Use a minor number of this bugger (not sure if this code is used
     *        though, so not bothering right now.) */
    g_iModuleMajorUsr = DEVICE_MAJOR_USR;
    rc = register_chrdev((dev_t)g_iModuleMajorUsr, DEVICE_NAME_USR, &gFileOpsVBoxDrvUsr);
    if (rc < 0)
    {
        Log(("register_chrdev() failed with rc=%#x for vboxdrv!\n", rc));
        return rc;
    }
    if (DEVICE_MAJOR_USR != 0)
        g_iModuleMajorUsr = DEVICE_MAJOR_USR;
    else
        g_iModuleMajorUsr = rc;
    rc = 0;

# ifdef CONFIG_DEVFS_FS
    /*
     * Register a device entry
     */
    if (   devfs_mk_cdev(MKDEV(DEVICE_MAJOR_SYS, 0), S_IFCHR | VBOX_DEV_FMASK, DEVICE_NAME_SYS) != 0
        || devfs_mk_cdev(MKDEV(DEVICE_MAJOR_USR, 0), S_IFCHR | VBOX_DEV_FMASK, DEVICE_NAME_USR) != 0)
    {
        Log(("devfs_register failed!\n"));
        rc = -EINVAL;
    }
# endif
#endif /* !CONFIG_VBOXDRV_AS_MISC */
    if (!rc)
    {
        /*
         * Initialize the runtime.
         * On AMD64 we'll have to donate the high rwx memory block to the exec allocator.
         */
        rc = RTR0Init(0);
        if (RT_SUCCESS(rc))
        {
#if (defined(RT_ARCH_AMD64) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)) || defined(VBOX_WITH_TEXT_MODMEM_HACK)
# ifdef VBOX_WITH_TEXT_MODMEM_HACK
            set_memory_x(&g_abExecMemory[0], sizeof(g_abExecMemory) / PAGE_SIZE);
            set_memory_rw(&g_abExecMemory[0], sizeof(g_abExecMemory) / PAGE_SIZE);
# endif
            rc = RTR0MemExecDonate(&g_abExecMemory[0], sizeof(g_abExecMemory));
            printk(KERN_DEBUG "VBoxDrv: dbg - g_abExecMemory=%p\n", (void *)&g_abExecMemory[0]);
#endif
            Log(("VBoxDrv::ModuleInit\n"));

            /*
             * Initialize the device extension.
             */
            if (RT_SUCCESS(rc))
                rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
            if (RT_SUCCESS(rc))
            {
#ifdef VBOX_WITH_SUSPEND_NOTIFICATION
                rc = platform_driver_register(&gPlatformDriver);
                if (rc == 0)
                {
                    rc = platform_device_register(&gPlatformDevice);
                    if (rc == 0)
#endif
                    {
                        printk(KERN_INFO "vboxdrv: TSC mode is %s, tentative frequency %llu Hz\n",
                               SUPGetGIPModeName(g_DevExt.pGip), g_DevExt.pGip->u64CpuHz);
                        LogFlow(("VBoxDrv::ModuleInit returning %#x\n", rc));
                        printk(KERN_DEBUG "vboxdrv: Successfully loaded version "
                                VBOX_VERSION_STRING " (interface " RT_XSTR(SUPDRV_IOC_VERSION) ")\n");
                        return rc;
                    }
#ifdef VBOX_WITH_SUSPEND_NOTIFICATION
                    else
                        platform_driver_unregister(&gPlatformDriver);
                }
#endif
            }

            rc = -EINVAL;
            RTR0TermForced();
        }
        else
            rc = -EINVAL;

        /*
         * Failed, cleanup and return the error code.
         */
#if defined(CONFIG_DEVFS_FS) && !defined(CONFIG_VBOXDRV_AS_MISC)
        devfs_remove(DEVICE_NAME_SYS);
        devfs_remove(DEVICE_NAME_USR);
#endif
    }
#ifdef CONFIG_VBOXDRV_AS_MISC
    misc_deregister(&gMiscDeviceSys);
    misc_deregister(&gMiscDeviceUsr);
    Log(("VBoxDrv::ModuleInit returning %#x (minor:%d & %d)\n", rc, gMiscDeviceSys.minor, gMiscDeviceUsr.minor));
#else
    unregister_chrdev(g_iModuleMajorUsr, DEVICE_NAME_USR);
    unregister_chrdev(g_iModuleMajorSys, DEVICE_NAME_SYS);
    Log(("VBoxDrv::ModuleInit returning %#x (major:%d & %d)\n", rc, g_iModuleMajorSys, g_iModuleMajorUsr));
#endif
    return rc;
}