Skip to content

Commit

Permalink
Add memory device info to system information
Browse files Browse the repository at this point in the history
  • Loading branch information
GaryOderNichts committed Sep 2, 2022
1 parent f54dcf1 commit fc4392d
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 7 deletions.
2 changes: 1 addition & 1 deletion ios_kernel/source/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ int _main(void* arg)

map_info.paddr = 0x05116000 - 0x05100000 + 0x13d80000;
map_info.vaddr = 0x05116000;
map_info.size = 0x6000; // TODO how much can we actually map here?
map_info.size = 0xa000;
map_info.domain = 1; // MCP
map_info.type = 3;
map_info.cached = 0xffffffff;
Expand Down
2 changes: 1 addition & 1 deletion ios_mcp/link.ld
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ SECTIONS {
}
}

ASSERT(SIZEOF(.text) < 0x6000, "ios_mcp text is too big");
ASSERT(SIZEOF(.text) < 0xa000, "ios_mcp text is too big");
ASSERT(SIZEOF(.bss) < 0x3000, "ios_mcp bss is too big");
64 changes: 64 additions & 0 deletions ios_mcp/source/mdinfo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "mdinfo.h"
#include "utils.h"

// Since physical and virtual addresses match for IOS-FS, we can use these without address translation
#define MDBLK_DRIVER_ADDRESS 0x11c39e78
#define MD_DEVICE_POINTERS_ADDRESS 0x10899308

// TODO turn this into a struct eventually
#define MD_DEVICE_CID_OFFSET 0x58
#define MD_DEVICE_CSD_OFFSET 0x68

static MDBlkDrv blkDrvs[2] = { 0 };
static uint32_t devicePointers[8] = { 0 };

int MDReadInfo(void)
{
uint32_t* dst = (uint32_t*) &blkDrvs;
for (uint32_t i = 0; i < sizeof(blkDrvs) / 4; i++) {
// use the kernel to read from IOS-FS memory
dst[i] = kernRead32(MDBLK_DRIVER_ADDRESS + (i * 4));
}

for (uint32_t i = 0; i < sizeof(devicePointers) / 4; i++) {
// use the kernel to read from IOS-FS memory
devicePointers[i] = kernRead32(MD_DEVICE_POINTERS_ADDRESS + (i * 4));
}

return 0;
}

MDBlkDrv* MDGetBlkDrv(int index)
{
return &blkDrvs[index];
}

int MDGetCID(int deviceId, uint32_t* cid)
{
int idx = deviceId - 0x42;
if (idx >= 8 || !devicePointers[idx]) {
return -1;
}

for (uint32_t i = 0; i < 4; i++) {
// use the kernel to read from IOS-FS memory
cid[i] = kernRead32(devicePointers[idx] + MD_DEVICE_CID_OFFSET + (i * 4));
}

return 0;
}

int MDGetCSD(int deviceId, uint32_t* csd)
{
int idx = deviceId - 0x42;
if (idx >= 8 || !devicePointers[idx]) {
return -1;
}

for (uint32_t i = 0; i < 4; i++) {
// use the kernel to read from IOS-FS memory
csd[i] = kernRead32(devicePointers[idx] + MD_DEVICE_CSD_OFFSET + (i * 4));
}

return 0;
}
41 changes: 41 additions & 0 deletions ios_mcp/source/mdinfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include <stdint.h>
#include <assert.h>

enum {
SAL_DEVICE_TYPE_MLC = 5,
SAL_DEVICE_TYPE_SD_CARD = 6,
};

typedef struct __attribute__((packed)) SALDeviceParams {
uint32_t usrptr;
uint32_t mid_prv;
uint32_t device_type;
uint32_t unk[7];
uint64_t numBlocks;
uint32_t blockSize;
uint32_t unk2[6];
char name0[128];
char name1[128];
char name2[128];
uint32_t functions[12];
} SALDeviceParams;

typedef struct MDBlkDrv {
int32_t registered;
int32_t unk[2];
struct SALDeviceParams params;
int sal_handle;
int deviceId;
uint8_t unk2[196];
} MDBlkDrv;
static_assert(sizeof(MDBlkDrv) == 724, "MDBlkDrv: wrong size");

int MDReadInfo(void);

MDBlkDrv* MDGetBlkDrv(int index);

int MDGetCID(int deviceId, uint32_t* cid);

int MDGetCSD(int deviceId, uint32_t* csd);
77 changes: 72 additions & 5 deletions ios_mcp/source/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "ccr.h"
#include "sci.h"
#include "mcp_misc.h"
#include "mdinfo.h"

#include <string.h>
#include <unistd.h>
Expand Down Expand Up @@ -1347,12 +1348,78 @@ static void option_SystemInformation(void)
}
}

// TODO: productArea, gameRegion, IOSU version, Wii U Menu version
// - productArea is set to 2 on my CAT-I that's actually set to USA.
// - gameRegion is set to 0 on all systems I've used.
// TODO: Use MCP_GetSysProdSettings()?

IOS_HeapFree(CROSS_PROCESS_HEAP_ID, dataBuffer);

index += CHAR_SIZE_DRC_Y + 4;

// Read info about IOS-FS' memory devices
res = MDReadInfo();
if (res < 0) {
gfx_set_font_color(COLOR_ERROR);
gfx_printf(16, index, 0, "Failed to read memory device info: %x", res);
waitButtonInput();
return;
}

for (int i = 0; i < 2; i++) {
MDBlkDrv* drv = MDGetBlkDrv(i);
// Ignore unregistered drivers and the SD Card
if (!drv->registered || drv->params.device_type == SAL_DEVICE_TYPE_SD_CARD) {
continue;
}

const char* deviceType = "Unknown";
if (drv->params.device_type == SAL_DEVICE_TYPE_MLC) {
deviceType = "MLC";
}

gfx_printf(16, index, 0, "Memory device %d (Type 0x%lx '%s'):", i, drv->params.device_type, deviceType);
index += CHAR_SIZE_DRC_Y + 4;

const uint16_t mid = drv->params.mid_prv >> 16;

// Find the manufacturer based on the manufacturer ID
// If you have a console with a manufacturer not listed here, please make a PR
const char* manufacturer = "Unknown";
if (mid == 0x11) {
manufacturer = "Toshiba";
} else if (mid == 0x15) {
manufacturer = "Samsung";
} else if (mid == 0x90) {
manufacturer = "Hynix";
}

gfx_printf(16, index, 0, " Manufacturer ID: 0x%02x (%s)", mid, manufacturer);
index += CHAR_SIZE_DRC_Y + 4;

uint16_t prv = drv->params.mid_prv & 0xff;

gfx_printf(16, index, 0, " Product revision: 0x%02x (%d.%d)", prv, prv >> 4, prv & 0xf);
index += CHAR_SIZE_DRC_Y + 4;

gfx_printf(16, index, 0, " Product name: %s", drv->params.name1);
index += CHAR_SIZE_DRC_Y + 4;

uint32_t totalSizeMiB = (uint32_t) ((drv->params.numBlocks * drv->params.blockSize) / 1024ull / 1024ull);
gfx_printf(16, index, 0, " Size: %llu x %lu (%lu MiB)", drv->params.numBlocks, drv->params.blockSize, totalSizeMiB);
index += CHAR_SIZE_DRC_Y + 4;

// Display the full CID and CSD registers
uint32_t cid[4];
res = MDGetCID(drv->deviceId, cid);
if (res == 0) {
gfx_printf(16, index, 0, " CID: %08lx%08lx%08lx%08lx", cid[0], cid[1], cid[2], cid[3]);
index += CHAR_SIZE_DRC_Y + 4;
}

uint32_t csd[4];
res = MDGetCSD(drv->deviceId, csd);
if (res == 0) {
gfx_printf(16, index, 0, " CSD: %08lx%08lx%08lx%08lx", csd[0], csd[1], csd[2], csd[3]);
index += CHAR_SIZE_DRC_Y + 4;
}
}

waitButtonInput();
}

Expand Down

0 comments on commit fc4392d

Please sign in to comment.