Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f2d3efed authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds
Browse files

[PATCH] x86_64: Implement early DMI scanning



There are more and more cases where we need to know DMI information
early to work around bugs.  i386 already had early DMI scanning, but
x86-64 didn't.  Implement this now.

This required some cleanup in the i386 code.

Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f083a329
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include <linux/dmi.h>
#include <linux/bootmem.h>
#include <linux/slab.h>
#include <asm/dmi.h>

static char * __init dmi_string(struct dmi_header *dm, u8 s)
{
+9 −7
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@
#include <asm/swiotlb.h>
#include <asm/sections.h>
#include <asm/gart-mapping.h>
#include <asm/dmi.h>

/*
 * Machine setup..
@@ -92,6 +93,12 @@ int bootloader_type;

unsigned long saved_video_mode;

/* 
 * Early DMI memory
 */
int dmi_alloc_index;
char dmi_alloc_data[DMI_MAX_DATA];

/*
 * Setup options
 */
@@ -620,6 +627,8 @@ void __init setup_arch(char **cmdline_p)

	init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));

	dmi_scan_machine();

	zap_low_mappings(0);

#ifdef CONFIG_ACPI
@@ -1412,10 +1421,3 @@ struct seq_operations cpuinfo_op = {
	.show =	show_cpuinfo,
};
static int __init run_dmi_scan(void)
{
	dmi_scan_machine();
	return 0;
}
core_initcall(run_dmi_scan);
+27 −0
Original line number Diff line number Diff line
@@ -225,6 +225,33 @@ static __meminit void unmap_low_page(int i)
	ti->allocated = 0; 
} 

/* Must run before zap_low_mappings */
__init void *early_ioremap(unsigned long addr, unsigned long size)
{
	unsigned long map = round_down(addr, LARGE_PAGE_SIZE); 

	/* actually usually some more */
	if (size >= LARGE_PAGE_SIZE) { 
		printk("SMBIOS area too long %lu\n", size);
		return NULL;
	}
	set_pmd(temp_mappings[0].pmd,  __pmd(map | _KERNPG_TABLE | _PAGE_PSE));
	map += LARGE_PAGE_SIZE;
	set_pmd(temp_mappings[1].pmd,  __pmd(map | _KERNPG_TABLE | _PAGE_PSE));
	__flush_tlb();
	return temp_mappings[0].address + (addr & (LARGE_PAGE_SIZE-1));
}

/* To avoid virtual aliases later */
__init void early_iounmap(void *addr, unsigned long size)
{
	if ((void *)round_down((unsigned long)addr, LARGE_PAGE_SIZE) != temp_mappings[0].address)
		printk("early_iounmap: bad address %p\n", addr);
	set_pmd(temp_mappings[0].pmd, __pmd(0));
	set_pmd(temp_mappings[1].pmd, __pmd(0));
	__flush_tlb();
}

static void __meminit
phys_pmd_init(pmd_t *pmd, unsigned long address, unsigned long end)
{

include/asm-i386/dmi.h

0 → 100644
+11 −0
Original line number Diff line number Diff line
#ifndef _ASM_DMI_H
#define _ASM_DMI_H 1

#include <asm/io.h>

/* Use early IO mappings for DMI because it's initialized early */
#define dmi_ioremap bt_ioremap
#define dmi_iounmap bt_iounmap
#define dmi_alloc alloc_bootmem

#endif
+27 −0
Original line number Diff line number Diff line
#ifndef _ASM_DMI_H
#define _ASM_DMI_H 1

#include <asm/io.h>

extern void *dmi_ioremap(unsigned long addr, unsigned long size);
extern void dmi_iounmap(void *addr, unsigned long size);

#define DMI_MAX_DATA 2048

extern int dmi_alloc_index;
extern char dmi_alloc_data[DMI_MAX_DATA];

/* This is so early that there is no good way to allocate dynamic memory. 
   Allocate data in an BSS array. */
static inline void *dmi_alloc(unsigned len)
{
	int idx = dmi_alloc_index;
	if ((dmi_alloc_index += len) > DMI_MAX_DATA)
		return NULL;
	return dmi_alloc_data + idx;
}

#define dmi_ioremap early_ioremap
#define dmi_iounmap early_iounmap

#endif
Loading