syslinux/com32/modules/meminfo.c
<<
>>
Prefs
   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
  25struct e820_data {
  26    uint64_t base;
  27    uint64_t len;
  28    uint32_t type;
  29    uint32_t extattr;
  30} __attribute__ ((packed));
  31
  32static const char *const e820_types[] = {
  33    "usable",
  34    "reserved",
  35    "ACPI reclaim",
  36    "ACPI NVS",
  37    "unusable",
  38};
  39
  40static void dump_e820(void)
  41{
  42    com32sys_t ireg, oreg;
  43    struct e820_data ed;
  44    uint32_t type;
  45
  46    memset(&ireg, 0, sizeof ireg);
  47
  48    ireg.eax.w[0] = 0xe820;
  49    ireg.edx.l = 0x534d4150;
  50    ireg.ecx.l = sizeof(struct e820_data);
  51    ireg.edi.w[0] = OFFS(__com32.cs_bounce);
  52    ireg.es = SEG(__com32.cs_bounce);
  53
  54    memset(&ed, 0, sizeof ed);
  55    ed.extattr = 1;
  56
  57    do {
  58        memcpy(__com32.cs_bounce, &ed, sizeof ed);
  59
  60        __intcall(0x15, &ireg, &oreg);
  61        if (oreg.eflags.l & EFLAGS_CF ||
  62            oreg.eax.l != 0x534d4150 || oreg.ecx.l < 20)
  63            break;
  64
  65        memcpy(&ed, __com32.cs_bounce, sizeof ed);
  66
  67        if (oreg.ecx.l >= 24) {
  68            /* ebx base length end type */
  69            printf("%8x %016llx %016llx %016llx %d [%x]",
  70                   ireg.ebx.l, ed.base, ed.len, ed.base + ed.len, ed.type,
  71                   ed.extattr);
  72        } else {
  73            /* ebx base length end */
  74            printf("%8x %016llx %016llx %016llx %d [-]",
  75                   ireg.ebx.l, ed.base, ed.len, ed.base + ed.len, ed.type);
  76            ed.extattr = 1;
  77        }
  78
  79        type = ed.type - 1;
  80        if (type < sizeof(e820_types) / sizeof(e820_types[0]))
  81            printf(" %s", e820_types[type]);
  82
  83        putchar('\n');
  84
  85        ireg.ebx.l = oreg.ebx.l;
  86    } while (ireg.ebx.l);
  87}
  88
  89static void dump_legacy(void)
  90{
  91    com32sys_t ireg, oreg;
  92    uint16_t dosram = *(uint16_t *) 0x413;
  93    struct {
  94        uint16_t offs, seg;
  95    } *const ivt = (void *)0;
  96
  97    memset(&ireg, 0, sizeof ireg);
  98
  99    __intcall(0x12, &ireg, &oreg);
 100
 101    printf
 102        ("INT 15h = %04x:%04x  DOS RAM: %dK (0x%05x)  INT 12h: %dK (0x%05x)\n",
 103         ivt[0x15].seg, ivt[0x15].offs, dosram, dosram << 10, oreg.eax.w[0],
 104         oreg.eax.w[0] << 10);
 105
 106    ireg.eax.b[1] = 0x88;
 107    __intcall(0x15, &ireg, &oreg);
 108
 109    printf("INT 15 88: 0x%04x (%uK)  ", oreg.eax.w[0], oreg.eax.w[0]);
 110
 111    ireg.eax.w[0] = 0xe801;
 112    __intcall(0x15, &ireg, &oreg);
 113
 114    printf("INT 15 E801: 0x%04x (%uK) 0x%04x (%uK)\n",
 115           oreg.ecx.w[0], oreg.ecx.w[0], oreg.edx.w[0], oreg.edx.w[0] << 6);
 116}
 117
 118int main(void)
 119{
 120    openconsole(&dev_null_r, &dev_stdcon_w);
 121
 122    dump_legacy();
 123    dump_e820();
 124
 125    return 0;
 126}
 127
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.