micetools/src/micetools/util/micedump.c

272 lines
8.1 KiB
C

#include <Windows.h>
#include <setupapi.h>
#include <shellapi.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "Setupapi.lib")
#include "../lib/am/amEeprom.h"
#define OpenDriver(x) \
CreateFileA("\\\\.\\" x, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)
#define RULE "-----------------------------------------"
#define SECTION_HEAD(x) \
puts(""); \
puts(RULE); \
puts(x); \
puts(RULE); \
puts("");
typedef struct {
uint64_t physAddr;
DWORD dType;
DWORD size;
} columba_request_t;
void scan_for_dmi(HANDLE columba, DWORD *stable_addr) {
DWORD bytesOut;
// short *stable_len;
columba_request_t request;
unsigned char readBuf[0x8010];
uint64_t search_addr = 0xf0000;
while (1) {
request.physAddr = search_addr;
request.dType = 1;
request.size = sizeof readBuf;
BOOL succ = DeviceIoControl(columba, (DWORD)IOCTL_COLUMBA_READ, &request,
sizeof request, &readBuf, sizeof readBuf, &bytesOut, NULL);
if (succ && bytesOut == sizeof readBuf) {
for (unsigned int offset = 0; offset < 0x8008; offset++) {
if (readBuf[offset] == '_' && readBuf[offset + 1] == 'D' &&
readBuf[offset + 2] == 'M' && readBuf[offset + 3] == 'I' &&
readBuf[offset + 4] == '_') {
*stable_addr = *(DWORD *)&readBuf[offset + 8];
return;
}
}
}
search_addr += 0x7ff0;
if (search_addr > 0xfffdf) return;
}
}
BOOL dump_columba() {
SECTION_HEAD("columba");
HANDLE columba = OpenDriver("columba");
if (columba == INVALID_HANDLE_VALUE) return FALSE;
DWORD stable_addr = 0;
scan_for_dmi(columba, &stable_addr);
if (stable_addr == 0) {
CloseHandle(columba);
return FALSE;
}
columba_request_t request;
unsigned char readBuf[0x10000];
printf("Found DMI at: %d\n", stable_addr);
request.physAddr = stable_addr;
request.dType = 1;
if (stable_addr + 0x10000 < 0x100001) {
request.size = 0x10000;
} else {
request.size = 0x100000 - stable_addr;
}
DWORD bytesReturned;
BOOL s = DeviceIoControl(columba, (DWORD)IOCTL_COLUMBA_READ, &request, sizeof request,
readBuf, sizeof readBuf, &bytesReturned, NULL);
if (!s || bytesReturned != sizeof readBuf) {
CloseHandle(columba);
return FALSE;
}
puts("DMI read sucessful.");
FILE *dmi;
fopen_s(&dmi, "dmi.bin", "wb");
fwrite(readBuf, 1, sizeof readBuf, dmi);
fclose(dmi);
puts(" -> Written to dmi.bin");
CloseHandle(columba);
return TRUE;
}
BOOL dump_eeprom() {
SECTION_HEAD("mxSMBus");
HANDLE mxsmbus = amEepromCreateDeviceFile(&MXSMBUS_GUID, NULL, 0);
if (mxsmbus == INVALID_HANDLE_VALUE) return FALSE;
DWORD _dummy;
DWORD version;
DeviceIoControl(mxsmbus, (DWORD)IOCTL_MXSMBUS_GET_VERSION, NULL, 0, &version, sizeof version,
&_dummy, NULL);
printf("mxSMBus version: %08x\n", version);
BYTE data[0x20];
for (WORD reg = 0; reg < 256; reg++) {
if (!amEepromReadBlock(mxsmbus, reg & 0xFF, 0x20, data)) continue;
printf("%02x: ", reg);
for (int i = 0; i < 0x20; i++) printf("%02x ", data[i]);
puts("");
}
CloseHandle(mxsmbus);
return TRUE;
}
unsigned char sram_buf[1024 * 2048];
BOOL dump_sram() {
SECTION_HEAD("mxSRAM");
HANDLE mxsram = OpenDriver("mxsram");
if (mxsram == INVALID_HANDLE_VALUE) return FALSE;
DWORD _dummy;
BOOL s;
DWORD version;
s = DeviceIoControl(mxsram, (DWORD)IOCTL_MXSRAM_PING, NULL, 0, &version, sizeof version,
&_dummy, NULL);
if (!s) {
CloseHandle(mxsram);
return FALSE;
}
printf("mxSRAM version: %04x\n", version);
DISK_GEOMETRY geom;
s = DeviceIoControl(mxsram, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geom, sizeof geom, &_dummy,
NULL);
if (!s) {
CloseHandle(mxsram);
return FALSE;
}
puts("mxSRAM geometry:");
printf(":: Cylinders: %lld\n", geom.Cylinders.QuadPart);
printf(":: MediaType: %d\n", geom.MediaType);
printf(":: TracksPerCylinder: %d\n", geom.TracksPerCylinder);
printf(":: SectorsPerTrack: %d\n", geom.SectorsPerTrack);
printf(":: BytesPerSector: %d\n", geom.BytesPerSector);
DWORD ssize;
s = DeviceIoControl(mxsram, (DWORD)IOCTL_MXSRAM_GET_SECTOR_SIZE, NULL, 0, &ssize, sizeof ssize,
&_dummy, NULL);
if (!s) {
CloseHandle(mxsram);
return FALSE;
}
printf(":: Sector Size: %d\n", ssize);
DWORD read;
if (!ReadFile(mxsram, sram_buf, sizeof sram_buf, &read, NULL)) {
CloseHandle(mxsram);
return FALSE;
}
printf("Read %d bytes\n", read);
if (read != sizeof sram_buf) puts("W: incomplete");
FILE *sram;
fopen_s(&sram, "sram.bin", "wb");
fwrite(sram_buf, 1, sizeof sram_buf, sram);
fclose(sram);
puts(" -> Written to sram.bin");
CloseHandle(mxsram);
return TRUE;
}
BYTE superio_read(HANDLE mxsuperio, BYTE chip, BYTE device, BYTE index) {
DWORD _dummy;
BYTE payload[4] = { chip, device, index, 0 };
DeviceIoControl(mxsuperio, (DWORD)IOCTL_MXSUPERIO_READ, payload, sizeof payload, payload,
sizeof payload, &_dummy, NULL);
return payload[3];
}
#define SUPERIO_LD_FDC 0
#define SUPERIO_LD_PARALLEL 1
#define SUPERIO_LD_UART_A 2
#define SUPERIO_LD_UART_B 3
#define SUPERIO_LD_KEYBOARD 5
#define SUPERIO_LD_UART_C 6
#define SUPERIO_LD_GPIO34 7
#define SUPERIO_LD_WDTO_PLED_GPIO56 8
#define SUPERIO_LD_GPIO12_SUSLED 9
#define SUPERIO_LD_ACPI 10
#define SUPERIO_LD_HWMON 11
#define SUPERIO_LD_PECI_SST 12
#define SUPERIO_LD_UART_D 13
#define SUPERIO_LD_UART_E 14
#define SUPERIO_LD_UART_F 15
BOOL dump_superio() {
SECTION_HEAD("mxSuperIO");
HANDLE mxsuperio = OpenDriver("mxsuperio");
if (mxsuperio == INVALID_HANDLE_VALUE) return FALSE;
BOOL s;
DWORD _dummy;
DWORD version;
s = DeviceIoControl(mxsuperio, (DWORD)IOCTL_MXSUPERIO_PING, NULL, 0, &version, sizeof version,
&_dummy, NULL);
if (!s) {
CloseHandle(mxsuperio);
return FALSE;
}
printf("mxSuperIO version: %08x\n", version);
BYTE ver_msb;
ver_msb = superio_read(mxsuperio, 0, SUPERIO_LD_FDC, 0x20);
if (ver_msb != 0xff) {
puts(":: Chip 0 present");
printf(" -> Version: %02x%02x\n", ver_msb,
superio_read(mxsuperio, 0, SUPERIO_LD_FDC, 0x21));
} else
puts(":: Chip 0 unpopulated");
ver_msb = superio_read(mxsuperio, 1, SUPERIO_LD_FDC, 0x20);
if (ver_msb != 0xff) {
puts(":: Chip 1 present");
printf(" -> Version: %02x%02x\n", ver_msb,
superio_read(mxsuperio, 1, SUPERIO_LD_FDC, 0x21));
} else
puts(":: Chip 1 unpopulated");
puts(":: Super lazy dump of chip 1, bank 0:");
for (uint8_t reg = 0; reg < 0xff; reg++) {
unsigned char packet[3] = { 1, reg, 0 };
DeviceIoControl(mxsuperio, (DWORD)IOCTL_MXSUPERIO_HWMONITOR_LPC_READ, &packet,
sizeof packet, &packet, sizeof packet, &_dummy, NULL);
printf(" -> %02x: %02x\n", reg, packet[2]);
}
CloseHandle(mxsuperio);
return TRUE;
}
int main() {
// if (!dump_columba()) {
// printf("Failed to dump DMI: %03x\n", GetLastError());
// }
if (!dump_eeprom()) {
printf("Failed to dump EEPROM: %03x\n", GetLastError());
}
// if (!dump_sram()) {
// printf("Failed to dump SRAM: %03x\n", GetLastError());
// }
// if (!dump_superio()) {
// printf("Failed to dump SuperIO: %03x\n", GetLastError());
// }
return 0;
}