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