1 /*
2  * Dump memory map information
3  */
4 
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdlib.h>
8 #include <com32.h>
9 #include "sysdump.h"
10 
11 #define E820_CHUNK 128
12 struct e820_info {
13     uint32_t ebx;
14     uint32_t len;
15     uint8_t  data[24];
16 };
17 
dump_e820(struct upload_backend * be)18 static void dump_e820(struct upload_backend *be)
19 {
20     com32sys_t ireg, oreg;
21     struct e820_info *curr;
22     struct e820_info *buf, *p;
23     int nentry, nalloc;
24 
25     curr = lmalloc(sizeof *curr);
26 
27     buf = p = NULL;
28     nentry = nalloc = 0;
29     memset(&ireg, 0, sizeof ireg);
30     memset(&curr, 0, sizeof curr);
31 
32     ireg.eax.l = 0xe820;
33     ireg.edx.l = 0x534d4150;
34     ireg.ecx.l = sizeof curr->data;
35     ireg.es = SEG(curr->data);
36     ireg.edi.w[0] = OFFS(curr->data);
37 
38     do {
39 	__intcall(0x15, &ireg, &oreg);
40 	if ((oreg.eflags.l & EFLAGS_CF) ||
41 	    oreg.eax.l != 0x534d4150)
42 	    break;
43 
44 	if (nentry >= nalloc) {
45 	    nalloc += E820_CHUNK;
46 	    buf = realloc(buf, nalloc*sizeof *buf);
47 	    if (!buf)
48 		return;		/* FAILED */
49 	}
50 	memcpy(buf[nentry].data, curr->data, sizeof curr->data);
51 	buf[nentry].ebx = ireg.ebx.l;
52 	buf[nentry].len = oreg.ecx.l;
53 	nentry++;
54 
55 	ireg.ebx.l = oreg.ebx.l;
56     } while (ireg.ebx.l);
57 
58     if (nentry)
59 	cpio_writefile(be, "memmap/15e820", buf, nentry*sizeof *buf);
60 
61     free(buf);
62     lfree(curr);
63 }
64 
dump_memory_map(struct upload_backend * be)65 void dump_memory_map(struct upload_backend *be)
66 {
67     com32sys_t ireg, oreg;
68 
69     cpio_mkdir(be, "memmap");
70 
71     memset(&ireg, 0, sizeof ireg);
72     __intcall(0x12, &ireg, &oreg);
73     cpio_writefile(be, "memmap/12", &oreg, sizeof oreg);
74 
75     memset(&ireg, 0, sizeof ireg);
76     ireg.eax.b[1] = 0x88;
77     __intcall(0x15, &ireg, &oreg);
78     cpio_writefile(be, "memmap/1588", &oreg, sizeof oreg);
79 
80     memset(&ireg, 0, sizeof ireg);
81     ireg.eax.w[0] = 0xe801;
82     __intcall(0x15, &ireg, &oreg);
83     cpio_writefile(be, "memmap/15e801", &oreg, sizeof oreg);
84 
85     dump_e820(be);
86 }
87