summaryrefslogtreecommitdiff
path: root/sys/arch/i386/stand
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>1997-10-20 14:56:10 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>1997-10-20 14:56:10 +0000
commit19459ae0e96ad9a1a6428ad5783377d5ad017ec0 (patch)
treec75b823e4dd713db4c7914ad9efa6f241309035e /sys/arch/i386/stand
parent0107ab8ff90c44a590c939422a0ef954c0db5215 (diff)
even better memprobe
Diffstat (limited to 'sys/arch/i386/stand')
-rw-r--r--sys/arch/i386/stand/libsa/cmd_i386.c26
-rw-r--r--sys/arch/i386/stand/libsa/memprobe.c317
2 files changed, 110 insertions, 233 deletions
diff --git a/sys/arch/i386/stand/libsa/cmd_i386.c b/sys/arch/i386/stand/libsa/cmd_i386.c
index 7568f0fd007..028852fa8f0 100644
--- a/sys/arch/i386/stand/libsa/cmd_i386.c
+++ b/sys/arch/i386/stand/libsa/cmd_i386.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd_i386.c,v 1.12 1997/10/20 14:47:42 mickey Exp $ */
+/* $OpenBSD: cmd_i386.c,v 1.13 1997/10/20 14:56:09 mickey Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff, Tobias Weingartner
@@ -67,12 +67,13 @@ Xdiskinfo()
{
int i;
- printf("Disk\tBIOS#\tCylinders\tHeads\tSectors\n");
+ printf("Disk\tBIOS#\t BSD#\tCylinders\tHeads\tSectors\n");
for(i = 0; bios_diskinfo[i].bios_number != -1 && i < 10; i++){
int d = bios_diskinfo[i].bios_number;
- printf("%cd%d\t 0x%x\t %s%d \t%d\t%d\n",
+ printf("%cd%d\t 0x%x\t0x%x\t %s%d \t%d\t%d\n",
(d & 0x80)?'h':'f', (d & 0x80)?d - 128:d, d,
+ bios_diskinfo[i].bsd_dev,
(bios_diskinfo[i].bios_cylinders < 100)?" ":" ",
bios_diskinfo[i].bios_cylinders,
bios_diskinfo[i].bios_heads,
@@ -119,7 +120,7 @@ Xboot()
printf("[%x,%d]\n", dev, part);
/* Read boot sector from device */
- st = biosd_rw(F_READ, dev, 0, 0, 1, 1, buf);
+ st = biosd_io(F_READ, dev, 0, 0, 1, 1, buf);
if(st) goto bad;
/* Frob boot flag in buffer from HD */
@@ -147,19 +148,16 @@ int
Xmemory()
{
bios_memmap_t *tm = memory_map;
- int count, total = 0;
+ int total = 0;
- for(count = 0; tm[count].type != BIOS_MAP_END; count++){
- printf("Region %d: type %u at 0x%lx for %luKB\n", count,
- tm[count].type, (long)tm[count].addr, (long)tm[count].size/1024);
-
- if(tm[count].type == BIOS_MAP_FREE)
- total += tm[count].size;
+ printf ("Map:");
+ for(; tm->type != BIOS_MAP_END; tm++){
+ printf(" [%luK]@0x%lx", (long)tm->size, (long)tm->addr);
+ if(tm->type == BIOS_MAP_FREE)
+ total += tm->size;
}
- printf("Low ram: %dKB High ram: %dKB\n", cnvmem, extmem);
- printf("Total free memory: %dKB\n", total/1024);
+ printf("\nTotal: %uK, Low: %uK, High: %uK\n", total, cnvmem, extmem);
return 0;
}
-
diff --git a/sys/arch/i386/stand/libsa/memprobe.c b/sys/arch/i386/stand/libsa/memprobe.c
index b0b96b080a9..7390d0f0c8b 100644
--- a/sys/arch/i386/stand/libsa/memprobe.c
+++ b/sys/arch/i386/stand/libsa/memprobe.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: memprobe.c,v 1.17 1997/10/20 14:47:42 mickey Exp $ */
+/* $OpenBSD: memprobe.c,v 1.18 1997/10/20 14:56:09 mickey Exp $ */
/*
- * Copyright (c) 1997 Tobias Weingartner
+ * Copyright (c) 1997 Tobias Weingartner, Michael Shalayeff
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,129 +37,71 @@
#include "libsa.h"
static int addrprobe __P((u_int));
-u_int cnvmem, extmem; /* XXX - remove */
-bios_memmap_t *memory_map;
-
-struct E820_desc_t {
- u_int32_t addr_lo;
- u_int32_t addr_hi;
- u_int32_t size_lo;
- u_int32_t size_hi;
- u_int32_t type;
-} __attribute__ ((packed));
-static struct E820_desc_t Desc;
-
-
-#define E820_MAX_MAPENT 10
+u_int cnvmem, extmem; /* XXX - compatibility */
+struct _bios_memmap *memory_map;
/* BIOS int 15, AX=E820
*
* This is the "prefered" method.
*/
-bios_memmap_t *
-bios_E820()
+static __inline struct _bios_memmap *
+bios_E820(mp)
+ register struct _bios_memmap *mp;
{
- static bios_memmap_t bm[E820_MAX_MAPENT]; /* This is easier */
- int E820Present = 0;
- int eax = 0, count = 0;
- volatile int ebx = 0;
+ int rc = 0, off = 0, sig;
do {
- BIOS_regs.biosr_es = ((unsigned)(&Desc) >> 4);
- __asm __volatile(
- "movl %2, %%ebx\n\t"
- "movl $0x534D4150, %%edx\n\t"
- DOINT(0x15) "\n\t"
- "movl %%eax, %%edx\n\t"
- "setc %b0\n\t"
- "movzbl %b0, %0\n\t"
- "cmpl $0x534D4150, %%edx\n\t"
- "je 1f\n\t"
- "incl %%eax\n\t"
- "1:\n\t"
- : "=a" (eax)
- : "0" (0xE820),
- "1" (ebx),
- "c" (sizeof(Desc)),
- "D" ((unsigned)(&Desc) & 0xF)
- : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "cc", "memory");
- ebx = BIOS_regs.biosr_bx;
-
- if(eax) break; /* Not present, or done */
-
- /* We are ignoring the upper 32 bits in the 64 bit
- * integer returned. If anyone has a PC where the
- * upper 32 bits are not zeros, *please* tell me! ;)
- *
- * NOTE: the BIOS_MAP_* numbers are the same, save for
- * the "zero" case, which we remap to reserved.
- */
- bm[count].addr = Desc.addr_lo;
- bm[count].size = Desc.size_lo;
- bm[count].type = (Desc.type)?Desc.type:BIOS_MAP_RES;
-
- E820Present = 1;
- } while((++count < E820_MAX_MAPENT) && (ebx != 0)); /* Do not re-oder! */
-
- if(E820Present){
- printf("int 0x15 [E820]\n");
- bm[count].type = BIOS_MAP_END;
- return(bm);
- }
-
- return(NULL);
+ BIOS_regs.biosr_es = ((unsigned)(mp) >> 4);
+ __asm __volatile(DOINT(0x15) "; setc %b1"
+ : "=a" (sig), "=d" (rc), "=b" (off)
+ : "0" (0xE820), "1" (0x534d4150), "b" (off),
+ "c" (sizeof(*mp)), "D" (((unsigned)mp) & 0xF)
+ : "cc", "memory");
+ off = BIOS_regs.biosr_bx;
+
+ if (rc & 0xff || sig != 0x534d4150)
+ return (NULL);
+ mp->size >>= 10; /* / 1024 */
+ mp++;
+ } while (off);
+
+ printf("0x15[E820]");
+
+ return (mp);
}
-
/* BIOS int 15, AX=E801
*
* Only used if int 15, AX=E820 does not work.
* This should work for more than 64MB.
*/
-bios_memmap_t *
-bios_E801()
+static __inline struct _bios_memmap *
+bios_E801(mp)
+ register struct _bios_memmap *mp;
{
- static bios_memmap_t bm[3];
- int eax, edx = 0;
+ int rc, m1, m2;
/* Test for 0xE801 */
- __asm __volatile(
- DOINT(0x15) "\n\t"
- "setc %b0\n\t"
- "movzbl %b0, %0\n\t"
- : "=a" (eax)
- : "a" (0xE801)
- );
+ __asm __volatile(DOINT(0x15) "; setc %b1"
+ : "=a" (m1), "=c" (rc), "=d" (m2) : "0" (0xE801));
/* Make a memory map from info */
- if(!eax){
- printf("int 0x15 [E801], ");
-
- __asm __volatile(
- DOINT(0x15) "\n\t"
- : "=a" (eax), "=d" (edx)
- : "a" (0xE801)
- );
-
- /* Make sure only valid bits */
- eax &= 0xFFFF;
- edx &= 0xFFFF;
+ if(rc & 0xff)
+ return (NULL);
- /* Fill out BIOS map */
- bm[0].addr = (1024 * 1024); /* 1MB */
- bm[0].size = eax * 1024;
- bm[0].type = BIOS_MAP_FREE;
+ printf("0x15[E801]");
- bm[1].addr = (1024 * 1024) * 16; /* 16MB */
- bm[1].size = (edx * 1024) * 64;
- bm[1].type = BIOS_MAP_FREE;
+ /* Fill out BIOS map */
+ mp->addr = (1024 * 1024); /* 1MB */
+ mp->size = (m1 & 0xffff);
+ mp->type = BIOS_MAP_FREE;
- bm[2].type = BIOS_MAP_END;
-
- return(bm);
- }
+ mp++;
+ mp->addr = (1024 * 1024) * 16; /* 16MB */
+ mp->size = (m2 & 0xffff) * 64;
+ mp->type = BIOS_MAP_FREE;
- return(NULL);
+ return ++mp;
}
@@ -168,60 +110,48 @@ bios_E801()
* Only used if int 15, AX=E801 does not work.
* Machines with this are restricted to 64MB.
*/
-bios_memmap_t *
-bios_8800()
+static __inline struct _bios_memmap *
+bios_8800(mp)
+ register struct _bios_memmap *mp;
{
- static bios_memmap_t bm[2];
- int eax, mem;
+ int rc, mem;
- __asm __volatile(
- DOINT(0x15) "\n\t"
- "movl %%eax, %%ecx\n\t"
- "setc %b0\n\t"
- "movzbl %b0, %0\n\t"
- : "=a" (eax), "=c" (mem)
- : "a" (0x8800)
- );
+ __asm __volatile(DOINT(0x15) "; setc %b0"
+ : "=c" (rc), "=a" (mem) : "a" (0x8800));
- if(eax) return(NULL);
+ if(rc & 0xff)
+ return (NULL);
- printf("int 0x15 [8800], ");
+ printf("0x15[8800]");
/* Fill out a BIOS_MAP */
- bm[0].addr = 1024*1024; /* 1MB */
- bm[0].size = (mem & 0xFFFF) * 1024;
- bm[0].type = BIOS_MAP_FREE;
+ mp->addr = 1024 * 1024; /* 1MB */
+ mp->size = mem & 0xffff;
+ mp->type = BIOS_MAP_FREE;
- bm[1].type = BIOS_MAP_END;
-
- return(bm);
+ return ++mp;
}
-
/* BIOS int 0x12 Get Conventional Memory
*
* Only used if int 15, AX=E820 does not work.
*/
-bios_memmap_t *
-bios_int12()
+static __inline struct _bios_memmap *
+bios_int12(mp)
+ struct _bios_memmap *mp;
{
- static bios_memmap_t bm[2];
int mem;
- printf("int 0x12\n");
+ printf(", 0x12\n");
- __asm __volatile(DOINT(0x12) : "=a" (mem)
- :: "%ecx", "%edx", "cc");
- mem &= 0xffff;
+ __asm __volatile(DOINT(0x12) : "=a" (mem) :: "%ecx", "%edx", "cc");
- /* Fill out a BIOS_MAP */
- bm[0].addr = 0;
- bm[0].size = mem * 1024;
- bm[0].type = BIOS_MAP_FREE;
+ /* Fill out a _bios_memmap */
+ mp->addr = 0;
+ mp->size = mem & 0xffff;
+ mp->type = BIOS_MAP_FREE;
- bm[1].type = BIOS_MAP_END;
-
- return(bm);
+ return ++mp;
}
@@ -281,7 +211,6 @@ addrprobe(kloc)
return ret;
}
-
/* Probe for all extended memory.
*
* This is only used as a last resort. If we resort to this
@@ -291,118 +220,68 @@ addrprobe(kloc)
* XXX - Does not detect aliases memory.
* XXX - Could be destructive, as it does write.
*/
-bios_memmap_t *
-badprobe()
+struct _bios_memmap *
+badprobe(mp)
+ register struct _bios_memmap *mp;
{
- static bios_memmap_t bm[2];
int ram;
- printf("Physical, ");
+ printf("Scan");
/* probe extended memory
*
* There is no need to do this in assembly language. This is
* much easier to debug in C anyways.
*/
- for(ram = 1024; ram < 512*1024; ram += 4)
+ for(ram = 1024; ram < 512 * 1024; ram += 4)
if(addrprobe(ram))
break;
- bm[0].addr = 1024 * 1024;
- bm[0].size = (ram - 1024) * 1024;
- bm[0].type = BIOS_MAP_FREE;
-
- bm[1].type = BIOS_MAP_END;
-
- return(bm);
-}
-
+ mp->addr = 1024 * 1024;
+ mp->size = ram - 1024;
+ mp->type = BIOS_MAP_FREE;
-int
-count(map)
- bios_memmap_t *map;
-{
- int i;
-
- for(i = 0; map[i].type != BIOS_MAP_END; i++) ;
-
- return(i);
+ return ++mp;
}
-
-bios_memmap_t *
-combine(a, b)
- bios_memmap_t *a, *b;
-{
- bios_memmap_t *res;
- int size, i;
-
- /* Sanity checks */
- if(!b) return(a);
- if(!a) return(b);
-
- size = (count(a) + count(b) + 1) * sizeof(bios_memmap_t);
- res = alloc(size);
-
- /* Again */
- if(!res) return(NULL); /* We are in deep doggie-doo */
-
- for(i = 0; a[i].type != BIOS_MAP_END; i++)
- res[i] = a[i];
- size = count(a);
- for(; b[i - size].type != BIOS_MAP_END; i++)
- res[i] = b[i - size];
-
- res[i].type = BIOS_MAP_END;
- return(res);
-}
-
-
void
memprobe()
{
- bios_memmap_t *tm, *em, *bm; /* total, extended, base */
- int count, total = 0;
+ static struct _bios_memmap bm[32]; /* This is easier */
+ struct _bios_memmap *pm = bm, *im;
+ int total = 0;
printf("Probing memory: ");
- tm = em = bm = NULL;
- tm = bios_E820();
- if(!tm){
- em = bios_E801();
- if(!em) em = bios_8800();
- if(!em) em = badprobe();
- bm = bios_int12();
-
- tm = combine(bm, em);
+ if(!(pm = bios_E820(bm))) {
+ pm = bios_E801(pm);
+ if(!pm)
+ pm = bios_8800(pm);
+ if(!pm)
+ pm = badprobe(pm);
+ pm = bios_int12(pm);
}
+ pm->type = BIOS_MAP_END;
/* Register in global var */
- memory_map = tm;
- printf("mem0:");
+ memory_map = bm;
+ printf("\nmem0:");
/* Get total free memory */
- for(count = 0; tm[count].type != BIOS_MAP_END; count++) {
- if(tm[count].type == BIOS_MAP_FREE) {
- total += tm[count].size;
-
- printf(" %luKB", (long)tm[count].size/1024);
+ for(im = bm; im->type != BIOS_MAP_END; im++) {
+ if (im->type == BIOS_MAP_FREE) {
+ total += im->size;
+ printf(" %luK", (long)im->size);
}
}
printf("\n");
/* XXX - Compatibility, remove later */
- cnvmem = extmem = 0;
- for(count = 0; tm[count].type != BIOS_MAP_END; count++) {
- if((tm[count].addr < 0xFFFFF) && (tm[count].type == BIOS_MAP_FREE)){
-
- cnvmem += tm[count].size;
+ for(im = bm; im->type != BIOS_MAP_END; im++)
+ if ((im->addr & 0xFFFFF) == im->addr &&
+ im->type == BIOS_MAP_FREE) {
+ cnvmem = im->size;
+ break; /* Take the first region */
}
- if((tm[count].addr > 0xFFFFF) && (tm[count].type == BIOS_MAP_FREE)){
- extmem += tm[count].size;
- }
- }
- cnvmem /= 1024;
- extmem /= 1024;
+ extmem = total - cnvmem;
}
-