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