Home | History | Annotate | Download | only in modules
      1 /* ----------------------------------------------------------------------- *
      2  *
      3  *   Copyright 2008 H. Peter Anvin - All Rights Reserved
      4  *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
      5  *
      6  *   This program is free software; you can redistribute it and/or modify
      7  *   it under the terms of the GNU General Public License as published by
      8  *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
      9  *   Boston MA 02110-1301, USA; either version 2 of the License, or
     10  *   (at your option) any later version; incorporated herein by reference.
     11  *
     12  * ----------------------------------------------------------------------- */
     13 
     14 /*
     15  * meminfo.c
     16  *
     17  * Dump the memory map of the system
     18  */
     19 #include <inttypes.h>
     20 #include <stdio.h>
     21 #include <string.h>
     22 #include <console.h>
     23 #include <com32.h>
     24 
     25 struct e820_data {
     26     uint64_t base;
     27     uint64_t len;
     28     uint32_t type;
     29     uint32_t extattr;
     30 } __attribute__ ((packed));
     31 
     32 static const char *const e820_types[] = {
     33     "usable",
     34     "reserved",
     35     "ACPI reclaim",
     36     "ACPI NVS",
     37     "unusable",
     38 };
     39 
     40 static void dump_e820(void)
     41 {
     42     com32sys_t ireg, oreg;
     43     struct e820_data ed;
     44     uint32_t type;
     45     void *low_ed;
     46 
     47     low_ed = lmalloc(sizeof ed);
     48     if (!low_ed)
     49 	return;
     50 
     51     memset(&ireg, 0, sizeof ireg);
     52 
     53     ireg.eax.w[0] = 0xe820;
     54     ireg.edx.l = 0x534d4150;
     55     ireg.ecx.l = sizeof(struct e820_data);
     56     ireg.edi.w[0] = OFFS(low_ed);
     57     ireg.es = SEG(low_ed);
     58 
     59     memset(&ed, 0, sizeof ed);
     60     ed.extattr = 1;
     61 
     62     do {
     63 	memcpy(low_ed, &ed, sizeof ed);
     64 
     65 	__intcall(0x15, &ireg, &oreg);
     66 	if (oreg.eflags.l & EFLAGS_CF ||
     67 	    oreg.eax.l != 0x534d4150 || oreg.ecx.l < 20)
     68 	    break;
     69 
     70 	memcpy(&ed, low_ed, sizeof ed);
     71 
     72 	if (oreg.ecx.l >= 24) {
     73 	    /* ebx base length end type */
     74 	    printf("%8x %016llx %016llx %016llx %d [%x]",
     75 		   ireg.ebx.l, ed.base, ed.len, ed.base + ed.len, ed.type,
     76 		   ed.extattr);
     77 	} else {
     78 	    /* ebx base length end */
     79 	    printf("%8x %016llx %016llx %016llx %d [-]",
     80 		   ireg.ebx.l, ed.base, ed.len, ed.base + ed.len, ed.type);
     81 	    ed.extattr = 1;
     82 	}
     83 
     84 	type = ed.type - 1;
     85 	if (type < sizeof(e820_types) / sizeof(e820_types[0]))
     86 	    printf(" %s", e820_types[type]);
     87 
     88 	putchar('\n');
     89 
     90 	ireg.ebx.l = oreg.ebx.l;
     91     } while (ireg.ebx.l);
     92 
     93     lfree(low_ed);
     94 }
     95 
     96 static void dump_legacy(void)
     97 {
     98     com32sys_t ireg, oreg;
     99     uint16_t dosram = *(uint16_t *) 0x413;
    100     struct {
    101 	uint16_t offs, seg;
    102     } *const ivt = (void *)0;
    103 
    104     memset(&ireg, 0, sizeof ireg);
    105 
    106     __intcall(0x12, &ireg, &oreg);
    107 
    108     printf
    109 	("INT 15h = %04x:%04x  DOS RAM: %dK (0x%05x)  INT 12h: %dK (0x%05x)\n",
    110 	 ivt[0x15].seg, ivt[0x15].offs, dosram, dosram << 10, oreg.eax.w[0],
    111 	 oreg.eax.w[0] << 10);
    112 
    113     memset(&ireg, 0, sizeof ireg);
    114     ireg.eax.b[1] = 0x88;
    115     __intcall(0x15, &ireg, &oreg);
    116 
    117     printf("INT 15 88: 0x%04x (%uK)  ", oreg.eax.w[0], oreg.eax.w[0]);
    118 
    119     memset(&ireg, 0, sizeof ireg);
    120     ireg.eax.w[0] = 0xe801;
    121     __intcall(0x15, &ireg, &oreg);
    122 
    123     printf("INT 15 E801: 0x%04x (%uK) 0x%04x (%uK)\n",
    124 	   oreg.ecx.w[0], oreg.ecx.w[0], oreg.edx.w[0], oreg.edx.w[0] << 6);
    125 }
    126 
    127 int main(int argc __unused, char **argv __unused)
    128 {
    129     dump_legacy();
    130     dump_e820();
    131     return 0;
    132 }
    133