Created
January 11, 2018 09:09
-
-
Save ashquarky/5f4833b3f75ef73eb74802653297ddaf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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