All of lore.kernel.org
 help / color / mirror / Atom feed
* [BUG][PATCH] BIOS reserved regions block iomem registration
@ 2003-10-22 18:57 Thayne Harbaugh
  2003-10-22 19:56 ` Thayne Harbaugh
  2003-10-24  4:21 ` Rusty Russell
  0 siblings, 2 replies; 3+ messages in thread
From: Thayne Harbaugh @ 2003-10-22 18:57 UTC (permalink / raw)
  To: linux-kernel; +Cc: trivial, Eric Biederman


[-- Attachment #1.1: Type: text/plain, Size: 1370 bytes --]

arch/i386/kernel/setup.c:register_memory() marks e820 memory regions -
some of which are "reserved".  These "reserved" regions prevent FLASH
chip drivers from registering the memory range occupied by BIOS code:

bash-2.05# cat /proc/iomem
.
.
.
fec00000-fec003ff : reserved
fee00000-fee00fff : reserved
fff80000-ffffffff : reserved

The last range marked as "reserved" (fff80000-ffffffff) is occupied by
the FLASH chip containing the BIOS code.  I'd like the MTD drivers to
register the correct ranges like this:

fec00000-fec003ff : reserved
fee00000-fee00fff : reserved
ffb00000-ffffffff : amd76xrom
  fff80000-ffffffff : mtd0

That way the iomem resources will be correct and can be used to map
FLASH chip updates.

There are at least two ways to fix this problem:

1) Don't mark the BIOS reserved regions.  Some BIOSes don't mark these
and the kernel works fine.  This is a trivial patch of removing the
"reserved" line in setup.c:register_memory().  See
remove_reserved.patch.

2) Leave the "reserved" regions but mark them with a IORESOURCE_GUESS so
that they can be removed by a driver that knows better and is capable of
correctly using the memory range.  See resource_guess_flag.patch.

Both of these patches were made on 2.4.20, but will likely apply
trivially to any 2.4.x or 2.6.


-- 
Thayne Harbaugh
Linux Networx

[-- Attachment #1.2: remove_reserved.patch --]
[-- Type: text/plain, Size: 485 bytes --]

--- linux-2.4.20/arch/i386/kernel/setup.c	2002-11-28 16:53:09.000000000 -0700
+++ linux-2.4.20-bs/arch/i386/kernel/setup.c	2003-10-17 12:01:12.000000000 -0600
@@ -1047,7 +1047,6 @@
 		case E820_RAM:	res->name = "System RAM"; break;
 		case E820_ACPI:	res->name = "ACPI Tables"; break;
 		case E820_NVS:	res->name = "ACPI Non-volatile Storage"; break;
-		default:	res->name = "reserved";
 		}
 		res->start = e820.map[i].addr;
 		res->end = res->start + e820.map[i].size - 1;

[-- Attachment #1.3: resource_guess_flag.patch --]
[-- Type: text/plain, Size: 3858 bytes --]

--- linux-2.4.20/kernel/resource.c	2002-11-28 16:53:15.000000000 -0700
+++ linux-2.4.20-bs/kernel/resource.c	2003-10-16 16:17:15.000000000 -0600
@@ -70,6 +70,8 @@
 	unsigned long end = new->end;
 	struct resource *tmp, **p;
 
+	if (root->flags & IORESOURCE_GUESS)
+		return root;
 	if (end < start)
 		return root;
 	if (start < root->start)
@@ -121,6 +123,70 @@
 	return conflict ? -EBUSY : 0;
 }
 
+int request_resource_remove_guess(struct resource *root, struct resource *new)
+{
+	struct resource *conflict, *sibling, *conflict_head = NULL;
+	int rc = -EBUSY;
+
+	write_lock(&resource_lock);
+	for (;;) {
+		conflict = __request_resource(root, new);
+		if (! conflict) {
+			/* success - free any IORESOURCE_GUESS resources */
+#if 0
+/* this doesn't work because the resources are alloc_bootmem_low() */
+			while (conflict_head) {
+				sibling = conflict_head->sibling;
+				kfree(conflict_head);
+				conflict_head = sibling;
+			}
+#endif
+			rc = 0;
+			break;
+		}
+		/* something is in the way - check to see what it is */
+		if (conflict->flags & IORESOURCE_GUESS) {
+			/* It's a guess that can be removed */
+			if (__release_resource(conflict)) {
+				printk(KERN_ERR __FILE__
+				       " %s(): unable to remove conflict:"
+				       " %s %08lx-%08lx\n",
+				       __func__,
+				       conflict_head->name,
+				       conflict_head->start,
+				       conflict_head->end);
+				break;
+			}
+			conflict->sibling = conflict_head;
+			conflict_head = conflict;
+			continue;
+		}
+		/* Can't remove the conflict */
+		break;
+	}
+
+	/* If we have anything then put it back */
+	while (conflict_head) {
+		sibling = conflict_head->sibling;
+		if ((conflict = __request_resource(root, conflict_head))) {
+			/* We hold the lock so why can't the
+			   resource be replaced? */
+			printk(KERN_ERR __FILE__
+			       " %s(): failed to replace resource:"
+			       " %s %08lx-%08lx\n",
+			       __func__,
+			       conflict_head->name,
+			       conflict_head->start,
+			       conflict_head->end);
+			kfree(conflict);
+		}
+		conflict_head = sibling;
+	}
+
+	write_unlock(&resource_lock);
+	return rc;
+}
+
 int release_resource(struct resource *old)
 {
 	int retval;
--- linux-2.4.20/include/linux/ioport.h	2002-11-28 16:53:15.000000000 -0700
+++ linux-2.4.20-bs/include/linux/ioport.h	2003-10-16 10:15:53.000000000 -0600
@@ -42,6 +42,15 @@
 #define IORESOURCE_SHADOWABLE	0x00010000
 #define IORESOURCE_BUS_HAS_VGA	0x00080000
 
+#define IORESOURCE_GUESS	0x08000000	/* These regions are reserved
+						   but it's unknown if it's
+						   100% accurate.  Must not have
+						   children.  Can be removed by
+						   request_resource_remove_guess()
+						   which will also kfree() the
+						   resource - handles for these
+						   aren't tracked by anything. */
+
 #define IORESOURCE_UNSET	0x20000000
 #define IORESOURCE_AUTO		0x40000000
 #define IORESOURCE_BUSY		0x80000000	/* Driver has marked this resource busy */
@@ -87,6 +96,7 @@
 
 extern int check_resource(struct resource *root, unsigned long, unsigned long);
 extern int request_resource(struct resource *root, struct resource *new);
+extern int request_resource_remove_guess(struct resource *root, struct resource *new);
 extern int release_resource(struct resource *new);
 extern int allocate_resource(struct resource *root, struct resource *new,
 			     unsigned long size,
--- linux-2.4.20/kernel/ksyms.c	2003-06-18 17:04:08.000000000 -0600
+++ linux-2.4.20-bs/kernel/ksyms.c	2003-10-16 10:58:15.000000000 -0600
@@ -431,6 +431,7 @@
 
 /* resource handling */
 EXPORT_SYMBOL(request_resource);
+EXPORT_SYMBOL(request_resource_remove_guess);
 EXPORT_SYMBOL(release_resource);
 EXPORT_SYMBOL(allocate_resource);
 EXPORT_SYMBOL(check_resource);

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [BUG][PATCH] BIOS reserved regions block iomem registration
  2003-10-22 18:57 [BUG][PATCH] BIOS reserved regions block iomem registration Thayne Harbaugh
@ 2003-10-22 19:56 ` Thayne Harbaugh
  2003-10-24  4:21 ` Rusty Russell
  1 sibling, 0 replies; 3+ messages in thread
From: Thayne Harbaugh @ 2003-10-22 19:56 UTC (permalink / raw)
  To: linux-kernel; +Cc: trivial, Eric Biederman


[-- Attachment #1.1: Type: text/plain, Size: 354 bytes --]


> 1) Don't mark the BIOS reserved regions.  Some BIOSes don't mark these
> and the kernel works fine.  This is a trivial patch of removing the
> "reserved" line in setup.c:register_memory().  See
> remove_reserved.patch.

Er, the previous remove_reserved.patch wouldn't work.  This should be
more correct.

-- 
Thayne Harbaugh
Linux Networx

[-- Attachment #1.2: remove_reserved-2.patch --]
[-- Type: text/plain, Size: 770 bytes --]

--- linux-2.4.20/arch/i386/kernel/setup.c	2002-11-28 16:53:09.000000000 -0700
+++ linux-2.4.20-bs/arch/i386/kernel/setup.c	2003-10-22 14:25:48.000000000 -0600
@@ -1042,12 +1042,14 @@
 		struct resource *res;
 		if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
 			continue;
+		if (e820.map[i].type == E820_RESERVED)
+			continue;
 		res = alloc_bootmem_low(sizeof(struct resource));
 		switch (e820.map[i].type) {
 		case E820_RAM:	res->name = "System RAM"; break;
 		case E820_ACPI:	res->name = "ACPI Tables"; break;
 		case E820_NVS:	res->name = "ACPI Non-volatile Storage"; break;
-		default:	res->name = "reserved";
+		default:	res->name = "unknown";
 		}
 		res->start = e820.map[i].addr;
 		res->end = res->start + e820.map[i].size - 1;

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [BUG][PATCH] BIOS reserved regions block iomem registration
  2003-10-22 18:57 [BUG][PATCH] BIOS reserved regions block iomem registration Thayne Harbaugh
  2003-10-22 19:56 ` Thayne Harbaugh
@ 2003-10-24  4:21 ` Rusty Russell
  1 sibling, 0 replies; 3+ messages in thread
From: Rusty Russell @ 2003-10-24  4:21 UTC (permalink / raw)
  To: tharbaugh; +Cc: linux-kernel, Eric Biederman

In message <1066849062.6281.190.camel@tubarao> you write:
> arch/i386/kernel/setup.c:register_memory() marks e820 memory regions -
> some of which are "reserved".  These "reserved" regions prevent FLASH
> chip drivers from registering the memory range occupied by BIOS code:

Not trivial, sorry.

Rusty.
--
  Anyone who quotes me in their sig is an idiot. -- Rusty Russell.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2003-10-24  6:39 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-10-22 18:57 [BUG][PATCH] BIOS reserved regions block iomem registration Thayne Harbaugh
2003-10-22 19:56 ` Thayne Harbaugh
2003-10-24  4:21 ` Rusty Russell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.