Re: [PATCH] Workaround for bogus INT 12H BIOS service implementation

2002-10-21 Thread Bruce Evans
On Tue, 22 Oct 2002, Mitsuru IWASAKI wrote:

Hmmm, actually no.  I know that some machines get panic with fatal trap
12 if we do 0x12 call.  The worst case is getting panic, not losing
640K memory.
   ...
  ...
 FYI: On RELENG_4, this problem is critical too because this panic
 isn't recoverable.  This means that it's impossible to install onto
 some newer machines.
 ...
 I've recalled that FreeBSD used RTC to determine base memory size in
 old days.  I've tested this method on my machines and confirmed it's
 working well.

 I'll commit this coming weekend if no objections.

 Index: machdep.c
 ===
 RCS file: /home/ncvs/src/sys/i386/i386/machdep.c,v
 retrieving revision 1.541
 diff -u -r1.541 machdep.c
 --- machdep.c 5 Oct 2002 14:36:14 -   1.541
 +++ machdep.c 21 Oct 2002 15:27:02 -
 @@ -1284,8 +1284,14 @@
   /*
* Perform base memory related probes  setup
*/
 - vm86_intcall(0x12, vmf);
 - basemem = vmf.vmf_ax;
 + if ((basemem = rtcin(RTC_BASELO) + (rtcin(RTC_BASEHI)8))  640)
 + basemem = 640;
 +
 + if (basemem == 0) {
 + vm86_intcall(0x12, vmf);
 + basemem = vmf.vmf_ax;
 + }
 +
   if (basemem  640) {
   printf(Preposterous BIOS basemem of %uK, truncating to 640K\n,
   basemem);


This would reintroduce a large bug.  The RTC gives the hardware memory
size, but the interrupt gives the software memory size.  These differ
for one of two machines under my desk (both have Award BIOSes).  The
BIOS often steals some of the base memory.  It's hard to tell whether
this memory will be used after FreeBSD determines the memory size.  It
might be used for VM86 or (much more magically) for SMM.

Reading the memory size from BIOS RAM (offset 0x413) would be safer.
I'm not sure how standard this is.  I thought that it is less standard
than INT 0x12.

Bruce


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



Re: [PATCH] Workaround for bogus INT 12H BIOS service implementation

2002-10-02 Thread Bruce Evans

On Mon, 30 Sep 2002, Mitsuru IWASAKI wrote:

   Index: sys/i386/i386/machdep.c
   ===
   RCS file: /home/ncvs/src/sys/i386/i386/machdep.c,v
   retrieving revision 1.532
   diff -u -r1.532 machdep.c
   --- sys/i386/i386/machdep.c   7 Sep 2002 19:12:42 -   1.532
   +++ sys/i386/i386/machdep.c   29 Sep 2002 21:15:26 -
   @@ -1269,8 +1269,12 @@
 /*
  * Perform base memory related probes  setup
  */
   - vm86_intcall(0x12, vmf);
   - basemem = vmf.vmf_ax;
   + if (bootinfo.bi_basemem != 0) {
   + basemem = bootinfo.bi_basemem;
   + } else {
   + vm86_intcall(0x12, vmf);
   + basemem = vmf.vmf_ax;
   + }
 if (basemem  640) {
 printf(Preposterous BIOS basemem of %uK, truncating to 640K\n,
 basemem);
 
  The kernel hasn't used bootinfo.bi_basemem for a long time and shouldn't
  start using it again now.  It already uses the 0x15/0xe820 call for
  everything except basemem (except when the this call fails, it falls
  back to 0x15/0xe801).  Maybe the bug has something to do with the
  kernel using the 0x12 call without checking whether the call succeeded.

I checked that a kernel boots fine when int 0x12 returns 0.   But there
would probably be problems if it returned a garbage value.

  When both the 0x15/0xe820 and the 0x15/0xe801 calls fail, the kernel
  falls back to an 0x15/0x88 call for determining extmem ... except this
  is ifdefed out and replaced by looking at the rtc values.  Maybe the
  unreliability of the 0x15/0x88 call has something to do with not
  checking if the call succeeded.

 Yes, I think the best way to determine base mem size in getmemsize()
 is to try 0x15/0xe820 call first, then fall back to 0x12 call.  But
 I'm not sure whether it's OK to call vm86_datacall(0x15) before
 determining base mem size...

  The patch makes no difference for booting directly from boot2 ... except
  memsize() in boot2 also fails to check for errors, so it returns garbage
  values.

 Yes I know that :-)
 But booting kernel directly from boot2 is not working at all for
 several years, so my understanding is that /boot/loader is necessary
 to boot kernel.

It mostly works.  I submitted patches in a PR many years ago and still use
them.

  I think the basemem == 0 case should just work, so the systems with a
  broken INT 0x12 should at worst lose 640K of memory, no matter whether
  basemem is set to 0 because INT 0x12 fails or because it actually
  returns 0.

 Hmmm, actually no.  I know that some machines get panic with fatal trap
 12 if we do 0x12 call.  The worst case is getting panic, not losing
 640K memory.

Where does the panic occur?  I checked that there is no problem here if
the result of INT 0x12 is ignored and basemem is set to 0.

 And it seems that today's Linux don't have 0x12 calling any more,
 so I didn't see any problem on the machines.

 Now I have some ideas on this issue;
  - 0x15/0xe820 call in getmemsize() to determine base mem size. (But how?)
  - 0x15/0xe820 call in locore.s before calling init386().
  - specify the size by loader tunable (e.g. hw.basememsize).

I would first fix all the broken code that doesn't check for errors
and see if the problem goes away.  Then recover any low memory not
reported by int 0x12 in the int 0x15/0xe820 code in i386/machdep.c,
like libi386/biosmem.c does it (I think machdep.c intentionally skips
the low memory, while biosmem.c tries to find it).

Bruce


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



Re: [PATCH] Workaround for bogus INT 12H BIOS service implementation

2002-09-29 Thread Bruce Evans

On Mon, 30 Sep 2002, Mitsuru IWASAKI wrote:

 Hi, I've found that some recent machine's BIOS doesn't support INT 12H
 (Get base memory size) BIOS service, instead they seems to support
 SMAP (system memory map: INT 15H function e820H) for this purpose.
 I already checked that there is no problems on Linux or Windows or
 others, but FreeBSD won't boot at all.

 I'll report bogus INT 12H BIOS service implementation to BIOS vendors
 if I get chances.  On the other hand, I think we need to have a
 workaround in a safety way for this problem for newer machines.

 Here is the patches.  I'll commit them in a few days if no objection.
 ...
 Index: sys/i386/i386/machdep.c
 ===
 RCS file: /home/ncvs/src/sys/i386/i386/machdep.c,v
 retrieving revision 1.532
 diff -u -r1.532 machdep.c
 --- sys/i386/i386/machdep.c   7 Sep 2002 19:12:42 -   1.532
 +++ sys/i386/i386/machdep.c   29 Sep 2002 21:15:26 -
 @@ -1269,8 +1269,12 @@
   /*
* Perform base memory related probes  setup
*/
 - vm86_intcall(0x12, vmf);
 - basemem = vmf.vmf_ax;
 + if (bootinfo.bi_basemem != 0) {
 + basemem = bootinfo.bi_basemem;
 + } else {
 + vm86_intcall(0x12, vmf);
 + basemem = vmf.vmf_ax;
 + }
   if (basemem  640) {
   printf(Preposterous BIOS basemem of %uK, truncating to 640K\n,
   basemem);

The kernel hasn't used bootinfo.bi_basemem for a long time and shouldn't
start using it again now.  It already uses the 0x15/0xe820 call for
everything except basemem (except when the this call fails, it falls
back to 0x15/0xe801).  Maybe the bug has something to do with the
kernel using the 0x12 call without checking whether the call succeeded.

When both the 0x15/0xe820 and the 0x15/0xe801 calls fail, the kernel
falls back to an 0x15/0x88 call for determining extmem ... except this
is ifdefed out and replaced by looking at the rtc values.  Maybe the
unreliability of the 0x15/0x88 call has something to do with not
checking if the call succeeded.

The patch makes no difference for booting directly from boot2 ... except
memsize() in boot2 also fails to check for errors, so it returns garbage
values.

I think the basemem == 0 case should just work, so the systems with a
broken INT 0x12 should at worst lose 640K of memory, no matter whether
basemem is set to 0 because INT 0x12 fails or because it actually
returns 0.

Bruce


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