Skip to content

Instantly share code, notes, and snippets.

@ashquarky
Created January 11, 2018 09:09
Show Gist options
  • Save ashquarky/5f4833b3f75ef73eb74802653297ddaf to your computer and use it in GitHub Desktop.
Save ashquarky/5f4833b3f75ef73eb74802653297ddaf to your computer and use it in GitHub Desktop.
unsigned int devbsp_msgqueue[0x40]; //.bss:E6047000 - E60470FC inclusive
unsigned int devbsp_msgqueue_id; //.bss:E6047100
unsigned int devbsp_msgqueue_fdtable[0x40]; //.bss:E6047104 - E6047200 inclusive
unsigned int dword_E6042000 = 0xFFFFFFFF; //.data:E6042000
/* http://wiiubrew.org/wiki/IOSU#IPC */
struct ipc_msg {
/* 1:open, 2:close, 3:read, 4:write, 5:seek, 6:ioctl, 7:ioctlv */
unsigned int cmd;
unsigned int client_reply;
/* Invalid if cmd=open */
unsigned int client_fd;
unsigned int flags;
/* 0:ARM, 1:PPCcore0, 2:PPCcore1, 3:PPCcore2 */
unsigned int client_cpu;
unsigned int client_pid;
unsigned int client_group_id_upper;
unsigned int client_group_id_lower;
unsigned int server_handle;
/* If cmd = ...
1:name, 3:outPtr, 4:inPtr, 5:where, 6:cmd, 7:cmd */
unsigned int arg0;
/* If cmd = ...
1:name_size, 3:outLen, 4:inLen, 5:whence, 6:inPtr, 7:readCount */
unsigned int arg1;
/* If cmd = ...
1:mode (0:none, 1:read, 2:write), 6:inLen, 7:writeCount */
unsigned int arg2;
/* If cmd = ...
1:permissions_upper, 6:outPtr, 7:vector */
unsigned int arg3;
/* If cmd = ...
1:permissions_lower, 6:outLen */
unsigned int arg4;
unsigned int prev_cmd;
unsigned int prev_client_fd;
unsigned int virt0;
unsigned int virt1;
}
/* .text:E6000000
Likely entry point. No obvious arguments/return values.
Name taken from log output */
void main() {
/* ==================================== initialisation bit */
int ret, bsperr/*r9*/, ioserr/*r8*/;
sub_E600E804();
ret = IOS_CreateCrossProcessHeap(0x10000); //UND #0x250, .text:E600FA44
if (ret < 0) {
/* Not 100% sure if this is a generic print or an error reporter */
bsp_print("BSP: IOS_CreateCrossProcessHeap ERROR, rval = %d\n", ret); //.text:E600EC28
return;
}
memset(devbsp_msgqueue_fdtable, 0, 0x100); //.text:E600EAB4
devbsp_msgqueue_id = IOS_CreateMessageQueue(devbsp_msgqueue, 0x40); //UND #0xC0, .text:E600F97C
if (devbsp_msgqueue_id < 0) {
ioserr = devbsp_msgqueue_id;
bsperr = 0;
goto report_err;
}
ret = IOS_RegisterResourceManager("/dev/bsp", devbsp_msgqueue_id); //UND #0x2C0, .text:E600FA7C
if (ret) {
ioserr = ret;
bsperr = 0;
goto report_err;
}
ret = device_assosciate("/dev/bsp", 1); //UND #0x2D0, .text:E600FA84
if (ret) {
ioserr = ret;
bsperr = 0;
goto report_err;
}
ret = init_stuff(); //.text:E6000D78, see below
if (ret) {
ioserr = 0;
bsperr = ret;
goto report_err;
}
set_bsp_ready(); //UND #0x5C0, .text:E600FBFC
/* ==================================== /dev/bsp processing bit */
struct ipc_msg* msg/*sp+0x18,r7*/;
unsigned int cmd, fd, result, perms_u, perms_l, i;
unsigned int* fdtable_entry/*sp+0x14*/, inPtr, outPtr/*sp+0xC*/;
for (;;) {
ret = IOS_ReceiveMessage(devbsp_msgqueue_id, &msg, 0); //UND #0x100, .text:E600F99C
if (ret) {
ioserr = 0;
bsperr = 0;
break; //aka goto report_err;
}
cmd = __builtin_bswap32(msg->cmd);
if (cmd == 2 /* close() */) {
fd = __builtin_bswap32(msg->client_fd);
if (fd > 0x1F || devbsp_msgqueue_fdtable[fd * 2] == 0) {
result = 0xFFFFFFFA;
} else {
memset(&(devbsp_msgqueue_fdtable[fd * 2]), 0/*actually ioserr; yes, really*/, 8);
}
} else if (cmd == 6 /* ioctl() */) {
fd = __builtin_bswap32(msg->client_fd);
if (fd > 0x1F) {
result = 0xFFFFFFFA;
goto reply;
}
/* in bytes, this is (fdtable + (fd << 3)) but I don't want to confuse
by using pointer math */
fdtable_entry = &(devbsp_msgqueue_fdtable[fd * 2]);
if (!fdtable_entry[0]) {
result = 0xFFFFFFFA;
goto reply;
}
/* ... these pointers never seem to be sanity-checked */
cmd = __builtin_bswap32(msg->arg0); //arg0:cmd for ioctls
inPtr = __builtin_bswap32(msg->arg1); //arg1:inPtr for ioctls
outPtr = __builtin_bswap32(msg->arg3); //you get the idea
/* There's a cmd-- here. I've offset the case statements to account
for this.
These ioctls obviously operate on some kind of struct, though I've
no idea what it might look like */
switch (cmd) {
case 0x1: {
if (__builtin_bswap32(inPtr[0x11]/*aka inPtr+0x44*/) != 4) {
result = 0x80;
} else {
result = sub_E6000668(inPtr, outPtr);
}
}
case 0x2: {
if (__builtin_bswap32(inPtr[0x11]/*inPtr+0x44*/) != 4) {
result = 0x80;
} else {
result = sub_E600B62C(outPtr);
}
}
case 0x3: {
if (__builtin_bswap32(inPtr[0x11]/*+0x44*/) != 4) {
result = 0x80;
} else {
result = sub_E600B1A4(outPtr);
}
}
case 0x4: {
result = sub_E6000A90(inPtr, __builtin_bswap32(inPtr[8]/*+0x20*/), &(inPtr[9]/*+0x24*/), __builtin_bswap32(inPtr[0x11]/*+0x44*/) /*stack args, unsure of order*/ outPtr, fdtable_entry[1]);
}
case 0x5: {
result = sub_E6000A14(inPtr, __builtin_bswap32(inPtr[8]/*+0x20*/), &(inPtr[9]/*+0x24*/), __builtin_bswap32(inPtr[0x11]/*+0x44*/), /*stack args, unsure of order*/ outPtr, fdtable_entry[1]);
}
case 0x6: {
result = sub_E6000998(inPtr, __builtin_bswap32(inPtr[8]/*+0x20*/), &(inPtr[9]/*+0x24*/), __builtin_bswap32(inPtr[0x11]/*+0x44*/), &(inPtr[0x12]/*+0x48*/), fdtable_entry[1]);
}
case 0x7: {
result = sub_E6000890(inPtr, __builtin_bswap32(inPtr[8]/*+0x20*/), &(inPtr[9]/*+0x24*/), __builtin_bswap32(inPtr[0x11]/*+0x44*/), &(inPtr[0x12]/*+0x48*/), fdtable_entry[1]);
}
case 0x8: {
result = sub_E6000830(inPtr, __builtin_bswap32(inPtr[8]/*+0x20*/), &(inPtr[9]/*+0x24*/), fdtable_entry[1]);
}
case 0x9: {
if (__builtin_bswap32(inPtr[0x11]/*+0x44*/) != 4) {
result = 0x80;
} else {
result = sub_E600B270(outPtr);
}
}
default: {
result = 0xFFFFFFFC;
}
}
} else if (cmd == 1 /* open() */) {
perms_u = __builtin_bswap32(msg->arg3); //arg3:permissions_upper
perms_l = __builtin_bswap32(msg->arg4); //arg4:permissions_lower
fdtable_entry = devbsp_msgqueue_fdtable;
for (i = 0; i != 0x20 /*yes, really*/; i++) {
if (!fdtable_entry[0]) {
fdtable_entry[0] = 1;
fdtable_entry[1] = perms_l;
result = i;
goto reply;
}
fdtable_entry += 2; //pointer arithmetic: this adds 8 bytes
}
result = i - 0x3E;
} else {
result = 0xFFFFFFFC; //-4?
goto reply;
}
reply:
IOS_ResourceReply(msg, result); //UND #0x490, .text:E600FB64
}
report_err:
sub_E600E264(dword_E6042000, "main", "bsp_main.c", 0x97, /* args on stack */"main() is exiting, ioserr %d, bsp err 0x%x\n", ioserr, bsperr);
}
unsigned int init_stuff() {
unsigned int ret /*r4|r5*/;
ret = sub_E6000CC4();
ret |= sub_E600580C();
ret |= sub_E6006BA4();
ret |= sub_E6006A3C();
ret |= sub_E6007D5C();
ret |= sub_E6004E68();
ret |= sub_E6003198();
ret |= sub_E6000F80();
ret |= sub_E6002800();
ret |= sub_E60068CC();
ret |= sub_E6005D5C();
ret |= sub_E6008C0C();
ret |= sub_E6009584();
ret |= sub_E60095C4();
ret |= sub_E60099CC();
ret |= sub_E6009D68();
ret |= sub_E600A2B0();
ret |= sub_E60040D8();
ret |= sub_E600A398();
ret |= sub_E600B0D8();
ret |= sub_E600B864();
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment