summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Weingartner <weingart@cvs.openbsd.org>2002-06-20 20:22:59 +0000
committerTobias Weingartner <weingart@cvs.openbsd.org>2002-06-20 20:22:59 +0000
commite1ff28eeda5ba208f890eee363ea02698428e9f4 (patch)
treea96b3d1c80001d36fa55d7759e3436a923ed07df
parentee8982b34af448814c8d6cb1ffd156515693c3f2 (diff)
Fix 4GB memory probing and other memory probing issues.
Outstanding issue is with Compaq 16MB detection problem. ok deraadt@, and various people from the 'net.
-rw-r--r--sys/arch/i386/stand/libsa/Makefile6
-rw-r--r--sys/arch/i386/stand/libsa/apmprobe.c11
-rw-r--r--sys/arch/i386/stand/libsa/biosprobe.c83
-rw-r--r--sys/arch/i386/stand/libsa/libsa.h7
-rw-r--r--sys/arch/i386/stand/libsa/memprobe.c61
5 files changed, 140 insertions, 28 deletions
diff --git a/sys/arch/i386/stand/libsa/Makefile b/sys/arch/i386/stand/libsa/Makefile
index 0d568eeaa67..9072d80f629 100644
--- a/sys/arch/i386/stand/libsa/Makefile
+++ b/sys/arch/i386/stand/libsa/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.38 2000/10/25 17:12:07 mickey Exp $
+# $OpenBSD: Makefile,v 1.39 2002/06/20 20:22:58 weingart Exp $
.include "${.CURDIR}/../Makefile.inc"
@@ -17,12 +17,12 @@ SRCS+= unixdev.c unixsys.S nullfs.c memprobe.c
CLEANFILES+= gidt.o debug_i386.o alloca.o \
biosdev.o bioscons.o gateA20.o apmprobe.o \
memprobe.o diskprobe.o smpprobe.o \
- time.o
+ time.o biosprobe.o
.else
SRCS+= gidt.S debug_i386.S alloca.S \
biosdev.c bioscons.c gateA20.c apmprobe.c \
memprobe.c diskprobe.c pciprobe.c smpprobe.c \
- time.c
+ time.c biosprobe.c
CLEANFILES+= unixdev.o unixsys.o nullfs.o
.endif
diff --git a/sys/arch/i386/stand/libsa/apmprobe.c b/sys/arch/i386/stand/libsa/apmprobe.c
index cdc9d600d4d..16b0abf3634 100644
--- a/sys/arch/i386/stand/libsa/apmprobe.c
+++ b/sys/arch/i386/stand/libsa/apmprobe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: apmprobe.c,v 1.8 2000/01/29 21:49:36 mickey Exp $ */
+/* $OpenBSD: apmprobe.c,v 1.9 2002/06/20 20:22:58 weingart Exp $ */
/*
* Copyright (c) 1997-2000 Michael Shalayeff
@@ -186,12 +186,13 @@ apmprobe()
}
void
-apmcheck()
+apmfixmem(void)
{
#ifdef DEBUG
- printf("apm");
+ printf("apmremove (%d)", ai.apm_detail);
#endif
- mem_delete(i386_trunc_page(ai.apm_data_base),
- i386_round_page(ai.apm_data_base + ai.apm_data_len));
+ if (ai.apm_detail)
+ mem_delete(i386_trunc_page(ai.apm_data_base),
+ i386_round_page(ai.apm_data_base + ai.apm_data_len));
}
diff --git a/sys/arch/i386/stand/libsa/biosprobe.c b/sys/arch/i386/stand/libsa/biosprobe.c
new file mode 100644
index 00000000000..fddf1b2ed57
--- /dev/null
+++ b/sys/arch/i386/stand/libsa/biosprobe.c
@@ -0,0 +1,83 @@
+/* $OpenBSD: biosprobe.c,v 1.1 2002/06/20 20:22:58 weingart Exp $ */
+
+/*
+ * Copyright (c) 2002 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <machine/biosvar.h>
+#include <machine/pio.h>
+#include <dev/cons.h>
+#include <lib/libsa/stand.h>
+#include "debug.h"
+
+
+void *
+getSYSCONFaddr()
+{
+ u_int32_t status;
+ u_int8_t *vers;
+
+ __asm __volatile(DOINT(0x15) "\n\t"
+ "setc %%al\n\t"
+ : "=a" (status)
+ : "0" (0xC000)
+ : "%ebx", "%ecx", "%edx", "%esi", "%edi", "cc");
+
+ /* On failure we go for a NULL */
+ if(status)
+ return(NULL);
+
+ /* Calculate where the version bytes are */
+ vers = (void*)((BIOS_regs.biosr_es << 4) | BIOS_regs.biosr_bx);
+ return(vers);
+}
+
+void *
+getEBDAaddr()
+{
+ u_int32_t status;
+ u_int8_t *info;
+
+ info = getSYSCONFaddr();
+ if(!info) return(NULL);
+
+ __asm __volatile(DOINT(0x15) "\n\t"
+ "setc %%al"
+ : "=a" (status)
+ : "0" (0xC100)
+ : "%ebx", "%ecx", "%edx", "%esi", "%edi", "cc");
+
+ if(status) return(NULL);
+
+ info = (void *)(BIOS_regs.biosr_es << 4);
+
+ return(info);
+}
+
diff --git a/sys/arch/i386/stand/libsa/libsa.h b/sys/arch/i386/stand/libsa/libsa.h
index 298aba48ab6..3e8499f4255 100644
--- a/sys/arch/i386/stand/libsa/libsa.h
+++ b/sys/arch/i386/stand/libsa/libsa.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: libsa.h,v 1.34 2002/03/14 01:26:34 millert Exp $ */
+/* $OpenBSD: libsa.h,v 1.35 2002/06/20 20:22:58 weingart Exp $ */
/*
* Copyright (c) 1996-1999 Michael Shalayeff
@@ -45,7 +45,7 @@ void pciprobe(void);
void memprobe(void);
void diskprobe(void);
void apmprobe(void);
-void apmcheck(void);
+void apmfixmem(void);
void dump_biosmem(bios_memmap_t *);
int mem_add(long, long);
int mem_delete(long, long);
@@ -54,6 +54,9 @@ void mem_pass(void);
void devboot(dev_t, char *);
void machdep(void);
+void *getSYSCONFaddr(void);
+void *getEBDAaddr(void);
+
extern const char bdevs[][4];
extern const int nbdevs;
extern u_int cnvmem, extmem; /* XXX global pass memprobe()->machdep_start() */
diff --git a/sys/arch/i386/stand/libsa/memprobe.c b/sys/arch/i386/stand/libsa/memprobe.c
index e987c284262..29853aaf4f2 100644
--- a/sys/arch/i386/stand/libsa/memprobe.c
+++ b/sys/arch/i386/stand/libsa/memprobe.c
@@ -1,8 +1,8 @@
-/* $OpenBSD: memprobe.c,v 1.36 2002/05/03 13:58:11 espie Exp $ */
+/* $OpenBSD: memprobe.c,v 1.37 2002/06/20 20:22:58 weingart Exp $ */
/*
* Copyright (c) 1997-1999 Michael Shalayeff
- * Copyright (c) 1997 Tobias Weingartner
+ * Copyright (c) 1997-1999 Tobias Weingartner
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -73,7 +73,9 @@ static __inline bios_memmap_t *
bios_E820(mp)
register bios_memmap_t *mp;
{
+ void *info;
int rc, off = 0, sig, gotcha = 0;
+ info = getEBDAaddr();
do {
BIOS_regs.biosr_es = ((u_int)(mp) >> 4);
@@ -100,29 +102,46 @@ bios_E820(mp)
return (mp);
}
-/* XXX Disabled until it is shown it is needed, and a version that does not
- * confuse the AT&T Globalyst 580 comes up. Ask niklas@openbsd.org if you
- * want to know details.
- */
#if 0
/* BIOS int 15, AX=E801
*
* Only used if int 15, AX=E820 does not work.
- * This should work for more than 64MB.
+ * This should work for more than 64MB on most
+ * modern machines. However, there is always
+ * an exception, the older IBM machine do not
+ * like this call.
*/
static __inline bios_memmap_t *
bios_E801(mp)
register bios_memmap_t *mp;
{
- int rc, m1, m2;
+ int rc, m1, m2, m3, m4;
+ u_int8_t *info;
+
+ /* Test for possibility of 0xE801 */
+ info = getSYSCONFaddr();
+ if(!info) return(NULL);
+ /* XXX - Should test model/submodel/rev here */
+ printf("model(%d,%d,%d)", info[2], info[3], info[4]);
- /* Test for 0xE801 */
- __asm __volatile(DOINT(0x15) "; setc %b1"
- : "=a" (m1), "=b" (m2), "=c" (rc) : "0" (0xE801));
+ /* Check for 94 or later bios */
+ info = (void *)0xFFFFB;
+ if(info[0] == '9' && info[1] <= '3') return(NULL);
- /* Make a memory map from info */
+ /* We might have this call */
+ __asm __volatile(DOINT(0x15) "; mov %%ax, %%si; setc %b0"
+ : "=a" (rc), "=S" (m1), "=b" (m2), "=c" (m3), "=d" (m4)
+ : "0" (0xE801));
+
+ /* Test for failure */
if(rc & 0xff)
return (NULL);
+
+ /* Fixup for screwed up machines */
+ if(m1 == 0){
+ m1 = m3;
+ m2 = m4;
+ }
#ifdef DEBUG
printf("0x15[E801] ");
#endif
@@ -306,11 +325,12 @@ memprobe()
pm = im;
}
}
-
pm->type = BIOS_MAP_END;
- /* gotta peephole optimize the list */
- apmcheck();
+ /* XXX - gotta peephole optimize the list */
+
+ /* Remove APM needed RAM */
+ apmfixmem();
#ifdef DEBUG
printf(")[");
@@ -359,9 +379,14 @@ dump_biosmem(tm)
if (!tm)
tm = bios_memmap;
+ /* libsa printf does not handle quad args, so we use long
+ * instead. Note, since we're unlikely to support more than
+ * 4G of RAM on a x86 box, this not likely to cause a problem.
+ * If/when we do, libsa may need to be updated some...
+ */
for(p = tm; p->type != BIOS_MAP_END; p++) {
printf("Region %ld: type %u at 0x%x for %uKB\n",
- (long)(p - tm), p->type, (u_int)p->addr,
+ (long)(p - tm), p->type, (u_int)p->addr,
(u_int)(p->size / 1024));
if(p->type == BIOS_MAP_FREE)
@@ -380,7 +405,7 @@ mem_delete(sa, ea)
for (p = bios_memmap; p->type != BIOS_MAP_END; p++) {
if (p->type == BIOS_MAP_FREE) {
- register int32_t sp = p->addr, ep = p->addr + p->size;
+ register int64_t sp = p->addr, ep = p->addr + p->size;
/* can we eat it as a whole? */
if ((sa - sp) <= NBPG && (ep - ea) <= NBPG) {
@@ -418,7 +443,7 @@ mem_add(sa, ea)
for (p = bios_memmap; p->type != BIOS_MAP_END; p++) {
if (p->type == BIOS_MAP_FREE) {
- register int32_t sp = p->addr, ep = p->addr + p->size;
+ register int64_t sp = p->addr, ep = p->addr + p->size;
/* is it already there? */
if (sp <= sa && ea <= ep) {