meminfo.c32: a program to dump out the system memory map
authorH. Peter Anvin <hpa@zytor.com>
Wed, 23 Jan 2008 07:16:32 +0000 (23:16 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Wed, 23 Jan 2008 07:16:32 +0000 (23:16 -0800)
Handy little utility for dumping out the system memory map.  Changes
no other code.

com32/modules/Makefile
com32/modules/meminfo.c [new file with mode: 0644]

index 9925d23..0347c17 100644 (file)
@@ -49,7 +49,7 @@ COM32DIR = $(AUXDIR)/com32
 
 MODULES          = chain.c32 menu.c32 vesamenu.c32 ethersel.c32 mboot.c32 \
            dmitest.c32 cpuidtest.c32 pcitest.c32 elf.c32 linux.c32 \
-           reboot.c32 pmload.c32
+           reboot.c32 pmload.c32 meminfo.c32
 TESTFILES =
 
 all: $(MODULES) $(TESTFILES)
diff --git a/com32/modules/meminfo.c b/com32/modules/meminfo.c
new file mode 100644 (file)
index 0000000..81678c5
--- /dev/null
@@ -0,0 +1,109 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * meminfo.c
+ *
+ * Dump the memory map of the system
+ */
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <console.h>
+#include <com32.h>
+
+struct e820_data {
+  uint64_t base;
+  uint64_t len;
+  uint32_t type;
+} __attribute__((packed));
+
+static const char * const e820_types[] = {
+  "usable",
+  "reserved",
+  "ACPI reclaim",
+  "ACPI NVS",
+};
+
+static void dump_e820(void)
+{
+  com32sys_t ireg, oreg;
+  struct e820_data ed;
+  uint32_t type;
+
+  memset(&ireg, 0, sizeof ireg);
+
+  ireg.eax.w[0] = 0xe820;
+  ireg.edx.l    = 0x534d4150;
+  ireg.ecx.l    = sizeof(struct e820_data);
+  ireg.edi.w[0] = OFFS(__com32.cs_bounce);
+  ireg.es       = SEG(__com32.cs_bounce);
+
+  do {
+    __intcall(0x15, &ireg, &oreg);
+    if (oreg.eflags.l & EFLAGS_CF ||
+       oreg.eax.l != 0x534d4150)
+      break;
+
+    memcpy(&ed, __com32.cs_bounce, sizeof ed);
+
+    /* ebx base length end type */
+    printf("%8x %016llx %016llx %016llx %x",
+          ireg.ebx.l, ed.base, ed.len, ed.base+ed.len, ed.type);
+
+    type = ed.type - 1;
+    if (type < sizeof(e820_types)/sizeof(e820_types[0]))
+      printf(" %s", e820_types[type]);
+
+    putchar('\n');
+
+    ireg.ebx.l = oreg.ebx.l;
+  } while (ireg.ebx.l);
+}
+
+static void dump_legacy(void)
+{
+  com32sys_t ireg, oreg;
+  uint16_t dosram = *(uint16_t *)0x413;
+  struct { uint16_t offs, seg; } * const ivt = (void *)0;
+
+  memset(&ireg, 0, sizeof ireg);
+
+  __intcall(0x12, &ireg, &oreg);
+
+  printf("INT 15h = %04x:%04x  DOS RAM: %dK (0x%05x)  INT 12h: %dK (0x%05x)\n",
+        ivt[0x15].seg, ivt[0x15].offs,
+        dosram, dosram << 10,
+        oreg.eax.w[0], oreg.eax.w[0] << 10);
+
+  ireg.eax.b[1] = 0x88;
+  __intcall(0x15, &ireg, &oreg);
+
+  printf("INT 15 88: 0x%04x (%uK)  ",
+        oreg.eax.w[0], oreg.eax.w[0]);
+
+  ireg.eax.w[0] = 0xe801;
+  __intcall(0x15, &ireg, &oreg);
+
+  printf("INT 15 E801: 0x%04x (%uK) 0x%04x (%uK)\n",
+        oreg.ecx.w[0], oreg.ecx.w[0], oreg.edx.w[0], oreg.edx.w[0] << 6);
+}
+
+int main(void)
+{
+  openconsole(&dev_null_r, &dev_stdcon_w);
+
+  dump_legacy();
+  dump_e820();
+
+  return 0;
+}