diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 1997-10-20 14:56:10 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 1997-10-20 14:56:10 +0000 |
commit | 19459ae0e96ad9a1a6428ad5783377d5ad017ec0 (patch) | |
tree | c75b823e4dd713db4c7914ad9efa6f241309035e /sys/arch/i386/stand | |
parent | 0107ab8ff90c44a590c939422a0ef954c0db5215 (diff) |
even better memprobe
Diffstat (limited to 'sys/arch/i386/stand')
-rw-r--r-- | sys/arch/i386/stand/libsa/cmd_i386.c | 26 | ||||
-rw-r--r-- | sys/arch/i386/stand/libsa/memprobe.c | 317 |
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; } - |