Date: Sun, 10 Nov 2002 04:43:54 -0800 From: David Schultz <dschultz@uclink.Berkeley.EDU> To: Mitsuru IWASAKI <iwasaki@jp.FreeBSD.org> Cc: arg-bsd@arg1.demon.co.uk, stable@FreeBSD.ORG, current@FreeBSD.ORG, David Rhodu <david@uky.edu>, Sidcarter <sidcarter@symonds.net> Subject: Re: machdep.c problem Message-ID: <20021110124354.GA2292@HAL9000.homeunix.com> In-Reply-To: <20021110.050300.98560281.iwasaki@jp.FreeBSD.org> References: <20021109.041802.45867347.iwasaki@jp.FreeBSD.org> <20021108234404.L22249-100000@server.arg.sj.co.uk> <20021110.050300.98560281.iwasaki@jp.FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Thus spake Mitsuru IWASAKI <iwasaki@jp.FreeBSD.org>:
> OK, it seems to be difficult to determine the region for any BIOSes.
> I've decided to introduce a new loader tunable to indicate that BIOS
> has broken int 12H. Attached patch back out 1.385.2.26 changes to
> support older BIOSes, and add support for broken int 12 BIOSes by
> new loader tunable.
> I don't think this is the best solution, but it is probably good for
> all people for now.
> I'll make the equivalent patches for CURRENT and commit them,
> then MFC soon.
> Sorry for inconvenience, folks.
This approach is okay with me in the sense that it doesn't break
anything that wasn't already broken, but as you say, I think we
can do better. Below is a patch that merely extracts the basemem
size from the bootinfo structure for the purposes of mapping the
EBDA. I retained the int 12h fallback just to be safe, but I
think the bootinfo structure is initialized with a valid basemem
for all loaders since at least 1998. (Maybe the fallbacks in the
kernel should be removed entirely to avoid redundancy, or moved
from loader and boot2 to locore.s.)
I also converted basemem from kilobytes to bytes in order to
simplify the math in the common case. Patches are against
-CURRENT; I can provide patches against -STABLE as well, barring
any complaints.
Index: machdep.c
===================================================================
RCS file: /cvs/src/sys/i386/i386/machdep.c,v
retrieving revision 1.547
diff -u -r1.547 machdep.c
--- machdep.c 7 Nov 2002 23:57:16 -0000 1.547
+++ machdep.c 10 Nov 2002 12:09:19 -0000
@@ -1477,7 +1477,25 @@
bzero(&vmf, sizeof(struct vm86frame));
bzero(physmap, sizeof(physmap));
- basemem = 0;
+
+ /*
+ * If basemem is < 640, the gap contains an extended BIOS
+ * data area and must be mapped read/write before any
+ * BIOS calls are made. Note that we can't use int 0x12
+ * to determine the base memory at this point because
+ * some modern machines do not support that interface.
+ * Instead, we rely on the loader to supply the value.
+ */
+ basemem = bootinfo.bi_basemem;
+ if (basemem) {
+ for (pa = trunc_page(basemem);
+ pa < ISA_HOLE_START; pa += PAGE_SIZE)
+ pmap_kenter(KERNBASE + pa, pa);
+
+ pte = (pt_entry_t *)vm86paddr;
+ for (i = basemem >> PAGE_SHIFT; i < 160; i++)
+ pte[i] = (i << PAGE_SHIFT) | PG_V | PG_RW | PG_U;
+ }
/*
* map page 1 R/W into the kernel page table so we can use it
@@ -1515,6 +1533,11 @@
if (smap->length == 0)
goto next_run;
+ if (smap->base == 00 && smap->length >= (512 * 1024)) {
+ basemem = smap->length;
+ goto next_run;
+ }
+
if (smap->base >= 0xffffffff) {
printf("%uK of memory above 4GB ignored\n",
(u_int)(smap->length / 1024));
@@ -1546,64 +1569,21 @@
next_run: ;
} while (vmf.vmf_ebx != 0);
- /*
- * Perform "base memory" related probes & setup
- */
- for (i = 0; i <= physmap_idx; i += 2) {
- if (physmap[i] == 0x00000000) {
- basemem = physmap[i + 1] / 1024;
- break;
- }
- }
+ if (physmap[1] != 0)
+ goto physmap_done;
- /* Fall back to the old compatibility function for base memory */
if (basemem == 0) {
vm86_intcall(0x12, &vmf);
- basemem = vmf.vmf_ax;
+ basemem = vmf.vmf_ax * 1024;
}
- if (basemem > 640) {
+ if (basemem > 640 * 1024) {
printf("Preposterous BIOS basemem of %uK, truncating to 640K\n",
- basemem);
- basemem = 640;
+ basemem / 1024);
+ basemem = 640 * 1024;
}
/*
- * XXX if biosbasemem is now < 640, there is a `hole'
- * between the end of base memory and the start of
- * ISA memory. The hole may be empty or it may
- * contain BIOS code or data. Map it read/write so
- * that the BIOS can write to it. (Memory from 0 to
- * the physical end of the kernel is mapped read-only
- * to begin with and then parts of it are remapped.
- * The parts that aren't remapped form holes that
- * remain read-only and are unused by the kernel.
- * The base memory area is below the physical end of
- * the kernel and right now forms a read-only hole.
- * The part of it from PAGE_SIZE to
- * (trunc_page(biosbasemem * 1024) - 1) will be
- * remapped and used by the kernel later.)
- *
- * This code is similar to the code used in
- * pmap_mapdev, but since no memory needs to be
- * allocated we simply change the mapping.
- */
- for (pa = trunc_page(basemem * 1024);
- pa < ISA_HOLE_START; pa += PAGE_SIZE)
- pmap_kenter(KERNBASE + pa, pa);
-
- /*
- * if basemem != 640, map pages r/w into vm86 page table so
- * that the bios can scribble on it.
- */
- pte = (pt_entry_t *)vm86paddr;
- for (i = basemem / 4; i < 160; i++)
- pte[i] = (i << PAGE_SHIFT) | PG_V | PG_RW | PG_U;
-
- if (physmap[1] != 0)
- goto physmap_done;
-
- /*
* If we failed above, try memory map with INT 15:E801
*/
vmf.vmf_ax = 0xE801;
@@ -1636,7 +1616,7 @@
extmem = 15 * 1024;
physmap[0] = 0;
- physmap[1] = basemem * 1024;
+ physmap[1] = basemem;
physmap_idx = 2;
physmap[physmap_idx] = 0x100000;
physmap[physmap_idx + 1] = physmap[physmap_idx] + extmem * 1024;
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20021110124354.GA2292>
