Re: machdep.c problem
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
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
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
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
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