Re: machdep.c problem

2002-11-15 Thread Bruce Evans
On Sun, 10 Nov 2002, David Schultz wrote:

 Thus spake Mitsuru IWASAKI [EMAIL PROTECTED]:
   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.

Note that the int 0x12 call was removed from boot2, so the bi_basemem == 0
case can;t be trusted.

   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

Since 1995, but not in boot2 since 2002/10/01.  The bi_memsizes_valid
flag unfortunately covers both bi_basemem and bi_extmem, so it is still
set although bi_basemem is bogus.  Also, boot2 and most (all?) other
places never checked for errors from int 0x12, so bi_basemem may be
pure garbage.

   kernel should be removed entirely to avoid redundancy, or moved
   from loader and boot2 to locore.s.)
 
  Yes, this idea was in my first patch actually, and this was not
  good solution as Bruce explained.  Please see the archive at:
  
http://docs.freebsd.org/cgi/getmsg.cgi?fetch=94412+0+archive/2002/freebsd-current/20021006.freebsd-current

 It sounds like the basic objection is, ``We came up with this
 feature in 1995 and never used it, so we shouldn't start using it
 now.''

We did use it, at least in the non-VM86 case, until VM86 became standard
in 1999.  I didn't like making VM86 the default but got used to it.  I
now see that I was wrong :-).

IIRC, the main reason for making VM86 standard was to use it here.
vm86_intcall() still doesn't seem to be used much.  It is used mainly for
the memsize calls and setting vesa modes.  int 0x12 can be done just as
easily in the boot code.  Setting vesa modes can be optional.  Only the
memory map subcall of the int 0x15 is much easier to do like it is done
now (the maps are too large for the boot code to pass easily).

 Fine, but I still maintain that determining the memory
 size in real mode like everyone else is the right thing to do.

I agree.

 Are there any objections to the following?

   - Remove the redundant and unused memory detection code
 from boot2, loader, and libi386.

I think this is currently the least bad place for it (except there
is not enough room to do int 0x15:0xe820 in boot2).

   - Mark the bootinfo fields bi_basemem and bi_extmem as
 deprecated.

Doesn't go with leaving it in boot2, etc.

   - Determine basemem in locore.s using 15h:e820h, with a
 fallback to int 12h.

I think this is the worst place to do it.

   - Remove the basemem calculation from machdep.c.

machdep.c could probably do the real mode switch without much more
difficulty than boot2, etc.

I would prefer to fix int 0x12 (if BIOSes are so broken as to trap
even when it is set up correctly, then handle the trap and make int
0x12 return 0; also return 0 if it fails.  So basemem is 0 in broken
cases -- waste a whole 640K as a reward for being broken.  Note that
the subsequent int 0x15 call(s) in machdep.c will still work, just as
if the BIOS ate the 640K -- we map it all r/w for the BIOS).

Bruce


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: machdep.c problem

2002-11-15 Thread David Schultz
Thus spake Bruce Evans [EMAIL PROTECTED]:
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
 
 Since 1995, but not in boot2 since 2002/10/01.  The bi_memsizes_valid
 flag unfortunately covers both bi_basemem and bi_extmem, so it is still
 set although bi_basemem is bogus.  Also, boot2 and most (all?) other
 places never checked for errors from int 0x12, so bi_basemem may be
 pure garbage.

That's easy enough to fix.  Add fields bi_newbasemem and
bi_newextmem, implement them correctly, and fall back to the
present behavior if neither are present.  This approach couldn't
make things any worse than they already are.

 IIRC, the main reason for making VM86 standard was to use it here.
 vm86_intcall() still doesn't seem to be used much.  It is used mainly for
 the memsize calls and setting vesa modes.  int 0x12 can be done just as
 easily in the boot code.  Setting vesa modes can be optional.  Only the
 memory map subcall of the int 0x15 is much easier to do like it is done
 now (the maps are too large for the boot code to pass easily).

Linux manages this by reserving a page for the int 15h:e820h map,
I think.  It doesn't look unreasonably difficult to pass the map
to the kernel.  Even if we have to resort to VM86 for this, we can
at least deal with basemem in real mode.

  Are there any objections to the following?
[...]
  - Remove the basemem calculation from machdep.c.
 
 machdep.c could probably do the real mode switch without much more
 difficulty than boot2, etc.

You think so?  I would imagine that after paging is enabled,
switching to real mode from a loaded kernel would be nontrivial.

 I would prefer to fix int 0x12 (if BIOSes are so broken as to trap
 even when it is set up correctly, then handle the trap and make int
 0x12 return 0; also return 0 if it fails.  So basemem is 0 in broken
 cases -- waste a whole 640K as a reward for being broken.  Note that
 the subsequent int 0x15 call(s) in machdep.c will still work, just as
 if the BIOS ate the 640K -- we map it all r/w for the BIOS).

Your idea sounds reasonable, although I would still prefer to fix
the boot loader to reliably report the base memory size.

To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: machdep.c problem

2002-11-10 Thread David Schultz
Thus spake Mitsuru IWASAKI [EMAIL PROTECTED]:
 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 -   1.547
+++ machdep.c   10 Nov 2002 12:09:19 -
@@ -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 = 0x) {
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] == 0x) {
-   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 

Re: machdep.c problem

2002-11-10 Thread Mitsuru IWASAKI
Hi,

 Thus spake Mitsuru IWASAKI [EMAIL PROTECTED]:
  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.)

Yes, this idea was in my first patch actually, and this was not
good solution as Bruce explained.  Please see the archive at:
http://docs.freebsd.org/cgi/getmsg.cgi?fetch=94412+0+archive/2002/freebsd-current/20021006.freebsd-current

I think that this is not so easy problem, we need to re-design memory
size detection code carefully considering PAE support in future.  This
will take time, so the patch I committed into CURRENT last night is
reasonable for the time being, I think.

Thanks

To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: machdep.c problem

2002-11-10 Thread David Schultz
Thus spake Mitsuru IWASAKI [EMAIL PROTECTED]:
  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.)
 
 Yes, this idea was in my first patch actually, and this was not
 good solution as Bruce explained.  Please see the archive at:
 
http://docs.freebsd.org/cgi/getmsg.cgi?fetch=94412+0+archive/2002/freebsd-current/20021006.freebsd-current

It sounds like the basic objection is, ``We came up with this
feature in 1995 and never used it, so we shouldn't start using it
now.''  Fine, but I still maintain that determining the memory
size in real mode like everyone else is the right thing to do.
Are there any objections to the following?

- Remove the redundant and unused memory detection code
  from boot2, loader, and libi386.

- Mark the bootinfo fields bi_basemem and bi_extmem as
  deprecated.

- Determine basemem in locore.s using 15h:e820h, with a
  fallback to int 12h.

- Remove the basemem calculation from machdep.c.

To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message