Example #1
0
/*
 * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
 * to map the target physical address. The problem is that set_fixmap()
 * provides a single page, and it is possible that the page is not
 * sufficient.
 * By using this area, we can map up to MAX_IO_APICS pages temporarily,
 * i.e. until the next __va_range() call.
 *
 * Important Safety Note:  The fixed I/O APIC page numbers are *subtracted*
 * from the fixed base.  That's why we start at FIX_IO_APIC_BASE_END and
 * count idx down while incrementing the phys address.
 */
char *__init __acpi_map_table(unsigned long phys, unsigned long size)
{
	unsigned long base, offset, mapped_size;
	int idx;

	if (!phys || !size)
		return NULL;

	if (phys+size <= (max_low_pfn_mapped << PAGE_SHIFT))
		return __va(phys);

	offset = phys & (PAGE_SIZE - 1);
	mapped_size = PAGE_SIZE - offset;
	clear_fixmap(FIX_ACPI_END);
	set_fixmap(FIX_ACPI_END, phys);
	base = fix_to_virt(FIX_ACPI_END);

	/*
	 * Most cases can be covered by the below.
	 */
	idx = FIX_ACPI_END;
	while (mapped_size < size) {
		if (--idx < FIX_ACPI_BEGIN)
			return NULL;	/* cannot handle this */
		phys += PAGE_SIZE;
		clear_fixmap(idx);
		set_fixmap(idx, phys);
		mapped_size += PAGE_SIZE;
	}

	return ((unsigned char *)base + offset);
}
Example #2
0
/*
 * paging_init() sets up the page tables - in fact we've already done this.
 */
static void __init paging_init(void)
{
	unsigned long zones_size[MAX_NR_ZONES];
#ifdef CONFIG_MMU
	int idx;

	/* Setup fixmaps */
	for (idx = 0; idx < __end_of_fixed_addresses; idx++)
		clear_fixmap(idx);
#endif

	/* Clean every zones */
	memset(zones_size, 0, sizeof(zones_size));

#ifdef CONFIG_HIGHMEM
	highmem_init();

	zones_size[ZONE_DMA] = max_low_pfn;
	zones_size[ZONE_HIGHMEM] = max_pfn;
#else
	zones_size[ZONE_DMA] = max_pfn;
#endif

	/* We don't have holes in memory map */
	free_area_init_nodes(zones_size);
}
Example #3
0
static void pre_suspend(void)
{
	HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
	clear_fixmap(FIX_SHARED_INFO);

	xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn);
	xen_start_info->console_mfn =
		mfn_to_pfn(xen_start_info->console_mfn);
}
Example #4
0
void __init tboot_probe(void)
{
    tboot_shared_t *tboot_shared;

    /* Look for valid page-aligned address for shared page. */
    if ( !opt_tboot_pa || (opt_tboot_pa & ~PAGE_MASK) )
        return;

    /* Map and check for tboot UUID. */
    set_fixmap(FIX_TBOOT_SHARED_BASE, opt_tboot_pa);
    tboot_shared = (tboot_shared_t *)fix_to_virt(FIX_TBOOT_SHARED_BASE);
    if ( tboot_shared == NULL )
        return;
    if ( memcmp(&tboot_shared_uuid, (uuid_t *)tboot_shared, sizeof(uuid_t)) )
        return;

    /* new tboot_shared (w/ GAS support, integrity, etc.) is not backwards
       compatible */
    if ( tboot_shared->version < 4 )
    {
        printk("unsupported version of tboot (%u)\n", tboot_shared->version);
        return;
    }

    g_tboot_shared = tboot_shared;
    printk("TBOOT: found shared page at phys addr %#lx:\n", opt_tboot_pa);
    printk("  version: %d\n", tboot_shared->version);
    printk("  log_addr: %#x\n", tboot_shared->log_addr);
    printk("  shutdown_entry: %#x\n", tboot_shared->shutdown_entry);
    printk("  tboot_base: %#x\n", tboot_shared->tboot_base);
    printk("  tboot_size: %#x\n", tboot_shared->tboot_size);
    if ( tboot_shared->version >= 6 )
        printk("  flags: %#x\n", tboot_shared->flags);

    /* these will be needed by tboot_protect_mem_regions() and/or
       tboot_parse_dmar_table(), so get them now */

    txt_heap_base = txt_heap_size = sinit_base = sinit_size = 0;
    /* TXT Heap */
    tboot_copy_memory((unsigned char *)&txt_heap_base, sizeof(txt_heap_base),
                      TXT_PUB_CONFIG_REGS_BASE + TXTCR_HEAP_BASE);
    tboot_copy_memory((unsigned char *)&txt_heap_size, sizeof(txt_heap_size),
                      TXT_PUB_CONFIG_REGS_BASE + TXTCR_HEAP_SIZE);
    /* SINIT */
    tboot_copy_memory((unsigned char *)&sinit_base, sizeof(sinit_base),
                      TXT_PUB_CONFIG_REGS_BASE + TXTCR_SINIT_BASE);
    tboot_copy_memory((unsigned char *)&sinit_size, sizeof(sinit_size),
                      TXT_PUB_CONFIG_REGS_BASE + TXTCR_SINIT_SIZE);
    clear_fixmap(FIX_TBOOT_MAP_ADDRESS);
}
Example #5
0
static int __init remap_vsyscall(void)
{
	unsigned long physaddr_page0 = (unsigned long) &__vsyscall_0 - PAGE_OFFSET;

	if (!vsyscall_mapped)
		return 0;

	/* Remap the VSYSCALL page w/ PAGE_KERNEL_VSYSCALL permissions
	 * after the alternate_instruction code has run
	 */
	clear_fixmap(FIX_VSYSCALL_GTOD_FIRST_PAGE);
	__set_fixmap(FIX_VSYSCALL_GTOD_FIRST_PAGE, physaddr_page0, PAGE_KERNEL_VSYSCALL);

	return 0;
}
Example #6
0
static void __init test_wp_bit(void)
{
	printk("Checking if this processor honours the WP bit even in supervisor mode... ");

	/* Any page-aligned address will do, the test is non-destructive */
	__set_fixmap(FIX_WP_TEST, __pa(&swapper_pg_dir), PAGE_READONLY);
	boot_cpu_data.wp_works_ok = do_test_wp_bit();
	clear_fixmap(FIX_WP_TEST);

	if (!boot_cpu_data.wp_works_ok) {
		printk("No.\n");
#ifdef CONFIG_X86_WP_WORKS_OK
		panic("This kernel doesn't support CPU's with broken WP. Recompile it for a 386!");
#endif
	} else {
		printk("Ok.\n");
	}
}
Example #7
0
void __init video_init(void)
{
    int node, depth;
    u32 address_cells, size_cells;
    struct lfb_prop lfbp;
    unsigned char *lfb;
    paddr_t hdlcd_start, hdlcd_size;
    paddr_t framebuffer_start, framebuffer_size;
    const struct fdt_property *prop;
    const u32 *cell;
    const char *mode_string;
    char _mode_string[16];
    int bytes_per_pixel = 4;
    struct color_masks *c = NULL;
    struct modeline *videomode = NULL;
    int i;

    if ( find_compatible_node("arm,hdlcd", &node, &depth,
                &address_cells, &size_cells) <= 0 )
        return;

    prop = fdt_get_property(device_tree_flattened, node, "reg", NULL);
    if ( !prop )
        return;

    cell = (const u32 *)prop->data;
    device_tree_get_reg(&cell, address_cells, size_cells,
            &hdlcd_start, &hdlcd_size);

    prop = fdt_get_property(device_tree_flattened, node, "framebuffer", NULL);
    if ( !prop )
        return;

    cell = (const u32 *)prop->data;
    device_tree_get_reg(&cell, address_cells, size_cells,
            &framebuffer_start, &framebuffer_size);

    if ( !hdlcd_start )
    {
        printk(KERN_ERR "HDLCD address missing from device tree, disabling driver\n");
        return;
    }

    if ( !hdlcd_start || !framebuffer_start )
    {
        printk(KERN_ERR "HDLCD: framebuffer address missing from device tree, disabling driver\n");
        return;
    }

    mode_string = fdt_getprop(device_tree_flattened, node, "mode", NULL);
    if ( !mode_string )
    {
        get_color_masks("32", &c);
        memcpy(_mode_string, "1280x1024@60", strlen("1280x1024@60") + 1);
        bytes_per_pixel = 4;
    }
    else if ( strlen(mode_string) < strlen("800x600@60") ||
            strlen(mode_string) > sizeof(_mode_string) - 1 )
    {
        printk(KERN_ERR "HDLCD: invalid modeline=%s\n", mode_string);
        return;
    } else {
        char *s = strchr(mode_string, '-');
        if ( !s )
        {
            printk(KERN_INFO "HDLCD: bpp not found in modeline %s, assume 32 bpp\n",
                    mode_string);
            get_color_masks("32", &c);
            memcpy(_mode_string, mode_string, strlen(mode_string) + 1);
            bytes_per_pixel = 4;
        } else {
            if ( strlen(s) < 6 )
            {
                printk(KERN_ERR "HDLCD: invalid mode %s\n", mode_string);
                return;
            }
            s++;
            if ( get_color_masks(s, &c) < 0 )
            {
                printk(KERN_WARNING "HDLCD: unsupported bpp %s\n", s);
                return;
            }
            bytes_per_pixel = simple_strtoll(s, NULL, 10) / 8;
        }
        i = s - mode_string - 1;
        memcpy(_mode_string, mode_string, i);
        memcpy(_mode_string + i, mode_string + i + 3, 4);
    }

    for ( i = 0; i < ARRAY_SIZE(videomodes); i++ ) {
        if ( !strcmp(_mode_string, videomodes[i].mode) )
        {
            videomode = &videomodes[i];
            break;
        }
    }
    if ( !videomode )
    {
        printk(KERN_WARNING "HDLCD: unsupported videomode %s\n", _mode_string);
        return;
    }

    if ( framebuffer_size < bytes_per_pixel * videomode->xres * videomode->yres )
    {
        printk(KERN_ERR "HDLCD: the framebuffer is too small, disabling the HDLCD driver\n");
        return;
    }

    printk(KERN_INFO "Initializing HDLCD driver\n");

    lfb = ioremap_wc(framebuffer_start, framebuffer_size);
    if ( !lfb )
    {
        printk(KERN_ERR "Couldn't map the framebuffer\n");
        return;
    }
    memset(lfb, 0x00, bytes_per_pixel * videomode->xres * videomode->yres);

    /* uses FIXMAP_MISC */
    set_pixclock(videomode->pixclock);

    set_fixmap(FIXMAP_MISC, hdlcd_start >> PAGE_SHIFT, DEV_SHARED);
    HDLCD[HDLCD_COMMAND] = 0;

    HDLCD[HDLCD_LINELENGTH] = videomode->xres * bytes_per_pixel;
    HDLCD[HDLCD_LINECOUNT] = videomode->yres - 1;
    HDLCD[HDLCD_LINEPITCH] = videomode->xres * bytes_per_pixel;
    HDLCD[HDLCD_PF] = ((bytes_per_pixel - 1) << 3);
    HDLCD[HDLCD_INTMASK] = 0;
    HDLCD[HDLCD_FBBASE] = framebuffer_start;
    HDLCD[HDLCD_BUS] = 0xf00 | (1 << 4);
    HDLCD[HDLCD_VBACK] = videomode->vback - 1;
    HDLCD[HDLCD_VSYNC] = videomode->vsync - 1;
    HDLCD[HDLCD_VDATA] = videomode->yres - 1;
    HDLCD[HDLCD_VFRONT] = videomode->vfront - 1;
    HDLCD[HDLCD_HBACK] = videomode->hback - 1;
    HDLCD[HDLCD_HSYNC] = videomode->hsync - 1;
    HDLCD[HDLCD_HDATA] = videomode->xres - 1;
    HDLCD[HDLCD_HFRONT] = videomode->hfront - 1;
    HDLCD[HDLCD_POLARITIES] = (1 << 2) | (1 << 3);
    HDLCD[HDLCD_RED] = (c->red_size << 8) | c->red_shift;
    HDLCD[HDLCD_GREEN] = (c->green_size << 8) | c->green_shift;
    HDLCD[HDLCD_BLUE] = (c->blue_size << 8) | c->blue_shift;
    HDLCD[HDLCD_COMMAND] = 1;
    clear_fixmap(FIXMAP_MISC);

    lfbp.pixel_on = (((1 << c->red_size) - 1) << c->red_shift) |
        (((1 << c->green_size) - 1) << c->green_shift) |
        (((1 << c->blue_size) - 1) << c->blue_shift);
    lfbp.lfb = lfb;
    lfbp.font = &font_vga_8x16;
    lfbp.bits_per_pixel = bytes_per_pixel*8;
    lfbp.bytes_per_line = bytes_per_pixel*videomode->xres;
    lfbp.width = videomode->xres;
    lfbp.height = videomode->yres;
    lfbp.flush = hdlcd_flush;
    lfbp.text_columns = videomode->xres / 8;
    lfbp.text_rows = videomode->yres / 16;
    if ( lfb_init(&lfbp) < 0 )
            return;
    video_puts = lfb_scroll_puts;
}
Example #8
0
static int __do_suspend(void *ignore)
{
	int i, j, k, fpp, err;

	extern unsigned long max_pfn;
	extern unsigned long *pfn_to_mfn_frame_list_list;
	extern unsigned long *pfn_to_mfn_frame_list[];

	extern void time_resume(void);

	BUG_ON(smp_processor_id() != 0);
	BUG_ON(in_interrupt());

	if (xen_feature(XENFEAT_auto_translated_physmap)) {
		printk(KERN_WARNING "Cannot suspend in "
		       "auto_translated_physmap mode.\n");
		return -EOPNOTSUPP;
	}

	err = smp_suspend();
	if (err)
		return err;

	xenbus_suspend();

	preempt_disable();

#ifdef __i386__
	kmem_cache_shrink(pgd_cache);
#endif
	mm_pin_all();

	__cli();
	preempt_enable();

	gnttab_suspend();

	HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
	clear_fixmap(FIX_SHARED_INFO);

	xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn);
	xen_start_info->console_mfn = mfn_to_pfn(xen_start_info->console_mfn);

	/*
	 * We'll stop somewhere inside this hypercall. When it returns,
	 * we'll start resuming after the restore.
	 */
	HYPERVISOR_suspend(virt_to_mfn(xen_start_info));

	shutting_down = SHUTDOWN_INVALID;

	set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);

	HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);

	memset(empty_zero_page, 0, PAGE_SIZE);

	HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
		virt_to_mfn(pfn_to_mfn_frame_list_list);

	fpp = PAGE_SIZE/sizeof(unsigned long);
	for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) {
		if ((j % fpp) == 0) {
			k++;
			pfn_to_mfn_frame_list_list[k] =
				virt_to_mfn(pfn_to_mfn_frame_list[k]);
			j = 0;
		}
		pfn_to_mfn_frame_list[k][j] =
			virt_to_mfn(&phys_to_machine_mapping[i]);
	}
	HYPERVISOR_shared_info->arch.max_pfn = max_pfn;

	gnttab_resume();

	irq_resume();

	time_resume();

	switch_idle_mm();

	__sti();

	xencons_resume();

	xenbus_resume();

	smp_resume();

	return err;
}