[PATCH] [30/66] x86_64: Implement early DMI scanning

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This required some cleanup in the i386 code.

Signed-off-by: Andi Kleen <ak@xxxxxxx>

---
 arch/i386/kernel/dmi_scan.c |    1 +
 arch/x86_64/kernel/setup.c  |   16 +++++++++-------
 arch/x86_64/mm/init.c       |   27 +++++++++++++++++++++++++++
 include/asm-i386/dmi.h      |   11 +++++++++++
 include/asm-x86_64/dmi.h    |   27 +++++++++++++++++++++++++++
 include/asm-x86_64/io.h     |    8 +++-----
 6 files changed, 78 insertions(+), 12 deletions(-)

Index: linux/arch/i386/kernel/dmi_scan.c
===================================================================
--- linux.orig/arch/i386/kernel/dmi_scan.c
+++ linux/arch/i386/kernel/dmi_scan.c
@@ -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)
 {
Index: linux/arch/x86_64/kernel/setup.c
===================================================================
--- linux.orig/arch/x86_64/kernel/setup.c
+++ linux/arch/x86_64/kernel/setup.c
@@ -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);
-
Index: linux/arch/x86_64/mm/init.c
===================================================================
--- linux.orig/arch/x86_64/mm/init.c
+++ linux/arch/x86_64/mm/init.c
@@ -225,6 +225,33 @@ static __meminit void unmap_low_page(int
 	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)
 {
Index: linux/include/asm-i386/dmi.h
===================================================================
--- /dev/null
+++ linux/include/asm-i386/dmi.h
@@ -0,0 +1,11 @@
+#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
Index: linux/include/asm-x86_64/dmi.h
===================================================================
--- /dev/null
+++ linux/include/asm-x86_64/dmi.h
@@ -0,0 +1,27 @@
+#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
Index: linux/include/asm-x86_64/io.h
===================================================================
--- linux.orig/include/asm-x86_64/io.h
+++ linux/include/asm-x86_64/io.h
@@ -135,6 +135,9 @@ static inline void __iomem * ioremap (un
 	return __ioremap(offset, size, 0);
 }
 
+extern void *early_ioremap(unsigned long addr, unsigned long size);
+extern void early_iounmap(void *addr, unsigned long size);
+
 /*
  * This one maps high address device memory and turns off caching for that area.
  * it's useful if some control registers are in such an area and write combining
@@ -143,11 +146,6 @@ static inline void __iomem * ioremap (un
 extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
 extern void iounmap(volatile void __iomem *addr);
 
-/* Use normal IO mappings for DMI */
-#define dmi_ioremap ioremap
-#define dmi_iounmap(x,l) iounmap(x)
-#define dmi_alloc(l) kmalloc(l, GFP_ATOMIC)
-
 /*
  * ISA I/O bus memory addresses are 1:1 with the physical address.
  */
-
: send the line "unsubscribe linux-x86_64" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux ia64]     [Linux Kernel]     [DCCP]     [Linux ARM]     [Yosemite News]     [Linux SCSI]     [Linux Hams]
  Powered by Linux