From owner-freebsd-current Mon Oct 21 20:14:20 2002 Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4B91537B401 for ; Mon, 21 Oct 2002 20:14:16 -0700 (PDT) Received: from tasogare.imasy.or.jp (tasogare.imasy.or.jp [202.227.24.5]) by mx1.FreeBSD.org (Postfix) with ESMTP id D87CF43E6A for ; Mon, 21 Oct 2002 20:14:13 -0700 (PDT) (envelope-from iwasaki@jp.FreeBSD.org) Received: from localhost (iwa@tasogare.imasy.or.jp [202.227.24.5]) by tasogare.imasy.or.jp (8.11.6+3.4W/8.11.6/tasogare) with ESMTP/inet id g9M3E1Y00710; Tue, 22 Oct 2002 12:14:01 +0900 (JST) (envelope-from iwasaki@jp.FreeBSD.org) Date: Tue, 22 Oct 2002 12:13:55 +0900 (JST) Message-Id: <20021022.121355.78702461.iwasaki@jp.FreeBSD.org> To: bde@zeta.org.au Cc: current@FreeBSD.ORG Subject: Re: [PATCH] Workaround for bogus INT 12H BIOS service implementation From: Mitsuru IWASAKI In-Reply-To: <20021022103609.V12732-100000@gamplex.bde.org> References: <20021022.003512.15273101.iwasaki@jp.FreeBSD.org> <20021022103609.V12732-100000@gamplex.bde.org> X-Mailer: Mew version 2.2 on Emacs 20.7 / Mule 4.0 (HANANOEN) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG > > - 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. OK, RELENG_3 GENERIC kernel might have problems with base memory, RTC was used there... How about this? It's my original idea. Thanks Index: machdep.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/machdep.c,v retrieving revision 1.542 diff -u -r1.542 machdep.c --- machdep.c 12 Oct 2002 05:32:23 -0000 1.542 +++ machdep.c 22 Oct 2002 03:04:15 -0000 @@ -1281,49 +1281,7 @@ bzero(&vmf, sizeof(struct vm86frame)); bzero(physmap, sizeof(physmap)); - - /* - * Perform "base memory" related probes & setup - */ - vm86_intcall(0x12, &vmf); - basemem = vmf.vmf_ax; - if (basemem > 640) { - printf("Preposterous BIOS basemem of %uK, truncating to 640K\n", - basemem); - basemem = 640; - } - - /* - * 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; + basemem = 0; /* * map page 1 R/W into the kernel page table so we can use it @@ -1391,6 +1349,60 @@ physmap[physmap_idx + 1] = smap->base + smap->length; 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; + } + } + + /* Fall back to the old compatibility function for base memory */ + 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); + basemem = 640; + } + + /* + * 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; To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message