cvs commit: src/sys/i386/i386 locore.s machdep.c

Bruce Evans bde at zeta.org.au
Sat Oct 4 23:29:13 PDT 2003


On Sat, 4 Oct 2003, Peter Wemm wrote:

> peter       2003/10/04 15:04:54 PDT
>
>   FreeBSD src repository
>
>   Modified files:
>     sys/i386/i386        locore.s machdep.c
>   Log:
>   Fix the apm problem for real.  We leave the first 4K page for the bios to
>   work in, but we had it mapped read-only.  While this has always been the
>   case, the PG_PS enable hack hid it and the apm bios code ended up taking
>   advantage of it.
>
>   Revision  Changes    Path
>   1.178     +0 -5      src/sys/i386/i386/locore.s
>   1.574     +6 -0      src/sys/i386/i386/machdep.c

This seems to be missing code for hasbrokenint12 case.  Untested fix
(with related and unrelated style changes):

%%%
Index: machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/machdep.c,v
retrieving revision 1.574
diff -u -2 -r1.574 machdep.c
--- machdep.c	4 Oct 2003 22:04:54 -0000	1.574
+++ machdep.c	5 Oct 2003 05:54:53 -0000
@@ -1505,7 +1530,14 @@
 	struct bios_smap *smap;

+	/*
+	 * Change the mapping of the page at address zero from r/o to r/w
+	 * so that vm86 can scribble on this page.  Note that this page is
+	 * not in the general free page pool.
+	 */
+	pmap_kenter(KERNBASE, 0);
+
 	hasbrokenint12 = 0;
 	TUNABLE_INT_FETCH("hw.hasbrokenint12", &hasbrokenint12);
-	bzero(&vmf, sizeof(struct vm86frame));
+	bzero(&vmf, sizeof(vmf));
 	bzero(physmap, sizeof(physmap));
 	basemem = 0;
@@ -1556,12 +1587,8 @@

 	/*
-	 * Map the page at address zero for the bios code to use.
-	 * Note that page zero is not in the general page pool.
-	 */
-	pmap_kenter(KERNBASE, 0);
-
-	/*
-	 * if basemem != 640, map pages r/w into vm86 page table so
-	 * that the bios can scribble on it.
+	 * Map pages between basemem and ISA_HOLE_START, if any, r/w into
+	 * the vm86 page table so that vm86 can scribble on them using
+	 * the vm86 map too.  XXX: why 2 ways for this and only 1 way for
+	 * page 0, at least as initialized here?
 	 */
 	pte = (pt_entry_t *)vm86paddr;
@@ -1646,18 +1674,25 @@
 		}

-		if (basemem == 0) {
-			basemem = 640;
-		}
+		/*
+		 * XXX this function is horribly organized and has to the same
+		 * things that it does above here.
+		 */

+		if (basemem == 0)
+			basemem = 640;
 		if (basemem > 640) {
-			printf("Preposterous BIOS basemem of %uK, truncating to 640K\n",
-				basemem);
+			printf(
+		    "Preposterous BIOS basemem of %uK; truncating to 640K\n",
+			    basemem);
 			basemem = 640;
 		}

+		/*
+		 * Let vm86 scribble on pages between basemem and
+		 * ISA_HOLE_START, as above.
+		 */
 		for (pa = trunc_page(basemem * 1024);
 		     pa < ISA_HOLE_START; pa += PAGE_SIZE)
 			pmap_kenter(KERNBASE + pa, pa);
-
 		pte = (pt_entry_t *)vm86paddr;
 		for (i = basemem / 4; i < 160; i++)
%%%

This mainly moves the r/w mapping for page 0 earlier and rewrites
related comments (but not the big one about the first part of remapping
biosbasemem through ISA_HOLE_START that most needs rewriting).  The
mapping of page 0 has nothing to do with basemem unless basemem == 0
in which case we probably crashed already.

Unfinished related details:
- Why do we make page 0 and the pages between biosmem and ISA_HOLE_START
  writeable in 2 maps?
- Which parts of vm86 and/or BIOSes need to write these pages?
- I think the non-FreeBSD part of vm86 needs to access (write?) page 0
  in the vm86 map, so we must be mapping it there somewhere else.  If
  so, why do we handle it different to the other BIOS pages.
- Page 0 will need to be writeable in cpu_reset_real(), so the comment
  which says that writeability is for vm86 will be incomplete.  However,
  r/w mapping could easily be delayed until it is needed in all cases.
- ISA_HOLE_START / PAGE_SIZE is sometimes hard-coded as 160.
- other points mentioned in comments.

Bruce


More information about the cvs-src mailing list