[patch] fix EFI memory map parsing for x86

2005-07-15 Thread Matt Tolentino
The memory descriptors that comprise the EFI memory map are
not fixed in stone such that the size could change in the 
future.  This uses the memory descriptor size obtained from
EFI to iterate over the memory map entries during boot. 
This enables the removal of an x86 specific pad (and ifdef) in
the EFI header.  I also couldn't stomach the broken up nature
of the function to put EFI runtime calls into virtual mode any 
longer so I fixed that up a bit as well.

For reference, this patch only impacts x86.

 arch/i386/kernel/efi.c   |  101 +++
 arch/i386/kernel/setup.c |   14 --
 arch/i386/mm/init.c  |5 +-
 include/asm-i386/setup.h |2 
 include/linux/efi.h  |   14 +-
 5 files changed, 67 insertions(+), 69 deletions(-)

Signed-off-by: Matt Tolentino <[EMAIL PROTECTED]>
---

diff -urNp linux-2.6.13-rc3/arch/i386/kernel/efi.c 
linux-2.6.13-rc3-efi/arch/i386/kernel/efi.c
--- linux-2.6.13-rc3/arch/i386/kernel/efi.c 2005-07-15 11:30:30.0 
-0400
+++ linux-2.6.13-rc3-efi/arch/i386/kernel/efi.c 2005-07-15 12:08:55.0 
-0400
@@ -233,22 +233,23 @@ void __init efi_map_memmap(void)
 {
memmap.map = NULL;
 
-   memmap.map = (efi_memory_desc_t *)
-   bt_ioremap((unsigned long) memmap.phys_map,
-   (memmap.nr_map * sizeof(efi_memory_desc_t)));
-
+   memmap.map = bt_ioremap((unsigned long) memmap.phys_map,
+   (memmap.nr_map * memmap.desc_size));
if (memmap.map == NULL)
printk(KERN_ERR PFX "Could not remap the EFI memmap!\n");
+
+   memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
 }
 
 #if EFI_DEBUG
 static void __init print_efi_memmap(void)
 {
efi_memory_desc_t *md;
+   void *p;
int i;
 
-   for (i = 0; i < memmap.nr_map; i++) {
-   md = &memmap.map[i];
+   for (p = memmap.map, i = 0; p < memmap.map_end; p += memmap.desc_size, 
i++) {
+   md = p;
printk(KERN_INFO "mem%02u: type=%u, attr=0x%llx, "
"range=[0x%016llx-0x%016llx) (%lluMB)\n",
i, md->type, md->attribute, md->phys_addr,
@@ -271,10 +272,10 @@ void efi_memmap_walk(efi_freemem_callbac
} prev, curr;
efi_memory_desc_t *md;
unsigned long start, end;
-   int i;
+   void *p;
 
-   for (i = 0; i < memmap.nr_map; i++) {
-   md = &memmap.map[i];
+   for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
+   md = p;
 
if ((md->num_pages == 0) || (!is_available_memory(md)))
continue;
@@ -325,6 +326,7 @@ void __init efi_init(void)
memmap.phys_map = EFI_MEMMAP;
memmap.nr_map = EFI_MEMMAP_SIZE/EFI_MEMDESC_SIZE;
memmap.desc_version = EFI_MEMDESC_VERSION;
+   memmap.desc_size = EFI_MEMDESC_SIZE;
 
efi.systab = (efi_system_table_t *)
boot_ioremap((unsigned long) efi_phys.systab,
@@ -431,22 +433,30 @@ void __init efi_init(void)
printk(KERN_ERR PFX "Could not map the runtime service 
table!\n");
 
/* Map the EFI memory map for use until paging_init() */
-
-   memmap.map = (efi_memory_desc_t *)
-   boot_ioremap((unsigned long) EFI_MEMMAP, EFI_MEMMAP_SIZE);
-
+   memmap.map = boot_ioremap((unsigned long) EFI_MEMMAP, EFI_MEMMAP_SIZE);
if (memmap.map == NULL)
printk(KERN_ERR PFX "Could not map the EFI memory map!\n");
 
-   if (EFI_MEMDESC_SIZE != sizeof(efi_memory_desc_t)) {
-   printk(KERN_WARNING PFX "Warning! Kernel-defined memdesc 
doesn't "
-  "match the one from EFI!\n");
-   }
+   memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
+
 #if EFI_DEBUG
print_efi_memmap();
 #endif
 }
 
+static inline void __init check_range_for_systab(efi_memory_desc_t *md)
+{
+   if (((unsigned long)md->phys_addr <= (unsigned long)efi_phys.systab) &&
+   ((unsigned long)efi_phys.systab < md->phys_addr +
+   ((unsigned long)md->num_pages << EFI_PAGE_SHIFT))) {
+   unsigned long addr;
+
+   addr = md->virt_addr - md->phys_addr + 
+   (unsigned long)efi_phys.systab;
+   efi.systab = (efi_system_table_t *)addr;
+   }
+}
+
 /*
  * This function will switch the EFI runtime services to virtual mode.
  * Essentially, look through the EFI memmap and map every region that
@@ -460,43 +470,32 @@ void __init efi_enter_virtual_mode(void)
 {
efi_memory_desc_t *md;
efi_status_t status;
-   int i;
+   void *p;
 
efi.systab = NULL;
 
-   for (i = 0; i < memmap.nr_map; i++) {
-   md = &memmap.ma

[patch] fix ACPI table discovery from EFI for x86

2005-07-13 Thread Matt Tolentino

This patch addresses a problem on x86 EFI systems with larger memory
configurations.  Up until now, we've relied on the fact that the 
ACPI RSDT would reside somewhere in low memory that could be permanently 
mapped in kernel address space - so __va() has been sufficient.  However,
on EFI systems, the RSDT is often anywhere in the lower 4GB of physical
address space.  So, we may need to remap it on x86 systems.  

Second, this fixes some miscalculations in one of the EFI memmap 
callback functions.  

Lastly, this also removes all of the va->pa->va contortions and 
stores the physical location in the efi struct while preserving the 
validity checks.  This change is the only reason this impacts 
ia64. 

Tested on x86 EFI machines and boot tested on one ia64 machine
thanks to Tony.  Additional testing on ia64 machines would be 
appreciated!  

Problem reported and original patch proposed by Ping Wei.

Signed-off-by: Matt Tolentino <[EMAIL PROTECTED]>
---
diff -urNp linux-2.6.13-rc3/arch/i386/kernel/acpi/boot.c 
linux-2.6.13-rc3-efi/arch/i386/kernel/acpi/boot.c
--- linux-2.6.13-rc3/arch/i386/kernel/acpi/boot.c   2005-07-13 
00:46:46.0 -0400
+++ linux-2.6.13-rc3-efi/arch/i386/kernel/acpi/boot.c   2005-07-13 
10:32:54.073297792 -0400
@@ -682,10 +682,10 @@ acpi_find_rsdp (void)
unsigned long   rsdp_phys = 0;
 
if (efi_enabled) {
-   if (efi.acpi20)
-   return __pa(efi.acpi20);
-   else if (efi.acpi)
-   return __pa(efi.acpi);
+   if (efi.phys_acpi20 != EFI_INVALID_ACPI_TABLE_ADDR)
+   return efi.phys_acpi20;
+   else if (efi.phys_acpi != EFI_INVALID_ACPI_TABLE_ADDR)
+   return efi.phys_acpi;
}
/*
 * Scan memory looking for the RSDP signature. First search EBDA (low
diff -urNp linux-2.6.13-rc3/arch/i386/kernel/efi.c 
linux-2.6.13-rc3-efi/arch/i386/kernel/efi.c
--- linux-2.6.13-rc3/arch/i386/kernel/efi.c 2005-07-13 00:46:46.0 
-0400
+++ linux-2.6.13-rc3-efi/arch/i386/kernel/efi.c 2005-07-13 10:32:04.731798840 
-0400
@@ -376,17 +376,20 @@ void __init efi_init(void)
if (config_tables == NULL)
printk(KERN_ERR PFX "Could not map EFI Configuration Table!\n");
 
+   efi.phys_acpi20 = EFI_INVALID_ACPI_TABLE_ADDR;
+   efi.phys_acpi = EFI_INVALID_ACPI_TABLE_ADDR;
+
for (i = 0; i < num_config_tables; i++) {
if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) {
efi.mps = (void *)config_tables[i].table;
printk(KERN_INFO " MPS=0x%lx ", config_tables[i].table);
} else
if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) 
== 0) {
-   efi.acpi20 = __va(config_tables[i].table);
+   efi.phys_acpi20 = config_tables[i].table;
printk(KERN_INFO " ACPI 2.0=0x%lx ", 
config_tables[i].table);
} else
if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 
0) {
-   efi.acpi = __va(config_tables[i].table);
+   efi.phys_acpi = config_tables[i].table;
printk(KERN_INFO " ACPI=0x%lx ", 
config_tables[i].table);
} else
if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) 
== 0) {
diff -urNp linux-2.6.13-rc3/arch/i386/kernel/setup.c 
linux-2.6.13-rc3-efi/arch/i386/kernel/setup.c
--- linux-2.6.13-rc3/arch/i386/kernel/setup.c   2005-07-13 00:46:46.0 
-0400
+++ linux-2.6.13-rc3-efi/arch/i386/kernel/setup.c   2005-07-13 
10:24:25.149665944 -0400
@@ -1034,10 +1034,10 @@ static int __init
 free_available_memory(unsigned long start, unsigned long end, void *arg)
 {
/* check max_low_pfn */
-   if (start >= ((max_low_pfn + 1) << PAGE_SHIFT))
+   if (start >= (max_low_pfn << PAGE_SHIFT))
return 0;
-   if (end >= ((max_low_pfn + 1) << PAGE_SHIFT))
-   end = (max_low_pfn + 1) << PAGE_SHIFT;
+   if (end >= (max_low_pfn << PAGE_SHIFT))
+   end = max_low_pfn << PAGE_SHIFT;
if (start < end)
free_bootmem(start, end - start);
 
diff -urNp linux-2.6.13-rc3/arch/ia64/kernel/acpi.c 
linux-2.6.13-rc3-efi/arch/ia64/kernel/acpi.c
--- linux-2.6.13-rc3/arch/ia64/kernel/acpi.c2005-07-13 00:46:46.0 
-0400
+++ linux-2.6.13-rc3-efi/arch/ia64/kernel/acpi.c2005-07-13 
10:33:51.614550192 -0400
@@ -615,9 +615,9 @@ acpi_find_rsdp (void)
 {
unsigned long rsdp_phys = 0;
 
-   if (efi.acpi20)
-   rsdp_phys = __pa(efi.acpi20);
-   else if (efi.acpi)
+   if (efi.phys_acpi20 != EFI_INVALID_ACPI_TABLE_ADDR)
+   rsdp_phys = efi.phys_acpi20;
+   else if (efi.ph

[patch] minor syctl fix in vsyscall_init

2005-04-13 Thread Matt Tolentino

Andi,

If CONFIG_SYCTL is not enabled then the x86-64 tree
fails to build due to use of a symbol that is not 
compiled in.  Don't bother compiling in the sysctl
register call if not building with sysctl.  

matt

Signed-off-by: Matt Tolentino <[EMAIL PROTECTED]>


diff -urNp linux-2.6.12-rc2/arch/x86_64/kernel/vsyscall.c 
linux-2.6.12-rc2-m/arch/x86_64/kernel/vsyscall.c
--- linux-2.6.12-rc2/arch/x86_64/kernel/vsyscall.c  2005-04-04 
12:39:06.0 -0400
+++ linux-2.6.12-rc2-m/arch/x86_64/kernel/vsyscall.c2005-04-13 
09:28:47.0 -0400
@@ -218,7 +218,9 @@ static int __init vsyscall_init(void)
BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE)));
map_vsyscall();
sysctl_vsyscall = 1;
+#ifdef CONFIG_SYSCTL
register_sysctl_table(kernel_root_table2, 0);
+#endif
return 0;
 }
 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/