176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Dump memory map information
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdio.h>
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <string.h>
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdlib.h>
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <com32.h>
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "sysdump.h"
1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define E820_CHUNK 128
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct e820_info {
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t ebx;
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t len;
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint8_t  data[24];
1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void dump_e820(struct upload_backend *be)
1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    com32sys_t ireg, oreg;
2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct e820_info *curr;
2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct e820_info *buf, *p;
2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    int nentry, nalloc;
2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    curr = lmalloc(sizeof *curr);
2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    buf = p = NULL;
2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    nentry = nalloc = 0;
2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    memset(&ireg, 0, sizeof ireg);
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    memset(&curr, 0, sizeof curr);
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    ireg.eax.l = 0xe820;
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    ireg.edx.l = 0x534d4150;
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    ireg.ecx.l = sizeof curr->data;
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    ireg.es = SEG(curr->data);
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    ireg.edi.w[0] = OFFS(curr->data);
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    do {
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	__intcall(0x15, &ireg, &oreg);
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ((oreg.eflags.l & EFLAGS_CF) ||
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    oreg.eax.l != 0x534d4150)
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    break;
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (nentry >= nalloc) {
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    nalloc += E820_CHUNK;
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    buf = realloc(buf, nalloc*sizeof *buf);
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (!buf)
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return;		/* FAILED */
4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	memcpy(buf[nentry].data, curr->data, sizeof curr->data);
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	buf[nentry].ebx = ireg.ebx.l;
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	buf[nentry].len = oreg.ecx.l;
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nentry++;
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ireg.ebx.l = oreg.ebx.l;
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    } while (ireg.ebx.l);
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (nentry)
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cpio_writefile(be, "memmap/15e820", buf, nentry*sizeof *buf);
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    free(buf);
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    lfree(curr);
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid dump_memory_map(struct upload_backend *be)
6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    com32sys_t ireg, oreg;
6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    cpio_mkdir(be, "memmap");
7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    memset(&ireg, 0, sizeof ireg);
7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    __intcall(0x12, &ireg, &oreg);
7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    cpio_writefile(be, "memmap/12", &oreg, sizeof oreg);
7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    memset(&ireg, 0, sizeof ireg);
7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    ireg.eax.b[1] = 0x88;
7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    __intcall(0x15, &ireg, &oreg);
7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    cpio_writefile(be, "memmap/1588", &oreg, sizeof oreg);
7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    memset(&ireg, 0, sizeof ireg);
8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    ireg.eax.w[0] = 0xe801;
8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    __intcall(0x15, &ireg, &oreg);
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    cpio_writefile(be, "memmap/15e801", &oreg, sizeof oreg);
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    dump_e820(be);
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
87