usbloadergx/source/mload/mload.c
giantpune 30535c6f5d *code beautification*
formatted the code to make it easier to read.  no functional changes at all.

i didn't put anything from the libwiigui folder or banner folder in the beautifier.

my automated .bat seems to have done a good job.  the only places i see it fucked up was on (GXColor){blablabla}.  it treated the brackets in the color like all the other brackets and put the color on a new line and indented it.  i think i fixed most of them.  not sure if it messed up anywhere else.  also not sure about how it handled different linebreaks.  it looks fine on windows.  if it looks messed up on linux, it can be reverted.

the code still compiles and runs fine.
2009-07-30 05:41:12 +00:00

472 lines
12 KiB
C

/* mload.c (for PPC) (c) 2009, Hermes
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "mload.h"
#include "ehcmodule.h"
#include "dip_plugin.h"
static const char mload_fs[] ATTRIBUTE_ALIGN(32) = "/dev/mload";
static u32 patch_datas[8] ATTRIBUTE_ALIGN(32);
static s32 mload_fd = -1;
/*--------------------------------------------------------------------------------------------------------------*/
// to init/test if the device is running
int mload_init() {
int n;
if (mload_fd>=0) return 0;
for (n=0;n<10;n++) { // try 2.5 seconds
mload_fd=IOS_Open(mload_fs, 0);
if (mload_fd>=0) break;
usleep(250*1000);
}
return mload_fd;
}
/*--------------------------------------------------------------------------------------------------------------*/
// to close the device (remember call it when rebooting the IOS!)
int mload_close() {
int ret;
if (mload_fd<0) return -1;
ret=IOS_Close(mload_fd);
mload_fd=-1;
return ret;
}
/*--------------------------------------------------------------------------------------------------------------*/
// to get the thread id of mload
int mload_get_thread_id() {
int ret;
s32 hid = -1;
if (mload_init()<0) return -1;
hid = iosCreateHeap(0x800);
if (hid<0) return hid;
ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_MLOAD_THREAD_ID, ":");
iosDestroyHeap(hid);
return ret;
}
/*--------------------------------------------------------------------------------------------------------------*/
// get the base and the size of the memory readable/writable to load modules
int mload_get_load_base(u32 *starlet_base, int *size) {
int ret;
s32 hid = -1;
if (mload_init()<0) return -1;
hid = iosCreateHeap(0x800);
if (hid<0) return hid;
ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_LOAD_BASE, ":ii",starlet_base, size);
iosDestroyHeap(hid);
return ret;
}
/*--------------------------------------------------------------------------------------------------------------*/
// load and run a module from starlet (it need to allocate MEM2 to send the elf file)
// the module must be a elf made with stripios
int mload_module(void *addr, int len) {
int ret;
void *buf=NULL;
s32 hid = -1;
if (mload_init()<0) return -1;
hid = iosCreateHeap(len+0x800);
if (hid<0) return hid;
buf= iosAlloc(hid, len);
if (!buf) {
ret= -1;
goto out;
}
memcpy(buf, addr,len);
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_LOAD_MODULE, ":d", buf, len);
if (ret<0) goto out;
ret=IOS_IoctlvFormat(hid, mload_fd, MLOAD_RUN_MODULE, ":");
if (ret<0) {
ret= -666;
goto out;
}
out:
iosDestroyHeap(hid);
return ret;
}
/*--------------------------------------------------------------------------------------------------------------*/
// load a module from the PPC
// the module must be a elf made with stripios
int mload_elf(void *my_elf, data_elf *data_elf) {
int n,m;
int p;
u8 *adr;
u32 elf=(u32) my_elf;
if (elf & 3) return -1; // aligned to 4 please!
elfheader *head=(void *) elf;
elfphentry *entries;
if (head->ident0!=0x7F454C46) return -1;
if (head->ident1!=0x01020161) return -1;
if (head->ident2!=0x01000000) return -1;
p=head->phoff;
data_elf->start=(void *) head->entry;
for (n=0; n<head->phnum; n++) {
entries=(void *) (elf+p);
p+=sizeof(elfphentry);
if (entries->type == 4) {
adr=(void *) (elf + entries->offset);
if (getbe32(0)!=0) return -2; // bad info (sure)
for (m=4; m < entries->memsz; m+=8) {
switch (getbe32(m)) {
case 0x9:
data_elf->start= (void *) getbe32(m+4);
break;
case 0x7D:
data_elf->prio= getbe32(m+4);
break;
case 0x7E:
data_elf->size_stack= getbe32(m+4);
break;
case 0x7F:
data_elf->stack= (void *) (getbe32(m+4));
break;
}
}
} else
if (entries->type == 1 && entries->memsz != 0 && entries->vaddr!=0) {
if (mload_memset((void *) entries->vaddr, 0, entries->memsz)<0) return -1;
if (mload_seek(entries->vaddr, SEEK_SET)<0) return -1;
if (mload_write((void *) (elf + entries->offset), entries->filesz)<0) return -1;
}
}
return 0;
}
/*--------------------------------------------------------------------------------------------------------------*/
// run one thread (you can use to load modules or binary files)
int mload_run_thread(void *starlet_addr, void *starlet_top_stack, int stack_size, int priority) {
int ret;
s32 hid = -1;
if (mload_init()<0) return -1;
hid = iosCreateHeap(0x800);
if (hid<0) return hid;
ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_RUN_THREAD, "iiii:", starlet_addr,starlet_top_stack, stack_size, priority);
iosDestroyHeap(hid);
return ret;
}
/*--------------------------------------------------------------------------------------------------------------*/
// stops one starlet thread
int mload_stop_thread(int id) {
int ret;
s32 hid = -1;
if (mload_init()<0) return -1;
hid = iosCreateHeap(0x800);
if (hid<0) return hid;
ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_STOP_THREAD, "i:", id);
iosDestroyHeap(hid);
return ret;
}
/*--------------------------------------------------------------------------------------------------------------*/
// continue one stopped starlet thread
int mload_continue_thread(int id) {
int ret;
s32 hid = -1;
if (mload_init()<0) return -1;
hid = iosCreateHeap(0x800);
if (hid<0) return hid;
ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_CONTINUE_THREAD, "i:", id);
iosDestroyHeap(hid);
return ret;
}
/*--------------------------------------------------------------------------------------------------------------*/
// fix starlet address to read/write (uses SEEK_SET, etc as mode)
int mload_seek(int offset, int mode) {
if (mload_init()<0) return -1;
return IOS_Seek(mload_fd, offset, mode);
}
/*--------------------------------------------------------------------------------------------------------------*/
// read bytes from starlet (it update the offset)
int mload_read(void* buf, u32 size) {
if (mload_init()<0) return -1;
return IOS_Read(mload_fd, buf, size);
}
/*--------------------------------------------------------------------------------------------------------------*/
// write bytes from starlet (it update the offset)
int mload_write(const void * buf, u32 size) {
if (mload_init()<0) return -1;
return IOS_Write(mload_fd, buf, size);
}
/*--------------------------------------------------------------------------------------------------------------*/
// fill a block (similar to memset)
int mload_memset(void *starlet_addr, int set, int len) {
int ret;
s32 hid = -1;
if (mload_init()<0) return -1;
hid = iosCreateHeap(0x800);
if (hid<0) return hid;
ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_MEMSET, "iii:", starlet_addr, set, len);
iosDestroyHeap(hid);
return ret;
}
/*--------------------------------------------------------------------------------------------------------------*/
// get the ehci datas ( ehcmodule.elf uses this address)
void * mload_get_ehci_data() {
int ret;
s32 hid = -1;
if (mload_init()<0) return NULL;
hid = iosCreateHeap(0x800);
if (hid<0) return NULL;
ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_EHCI_DATA, ":");
if (ret<0) return NULL;
iosDestroyHeap(hid);
return (void *) ret;
}
/*--------------------------------------------------------------------------------------------------------------*/
// set the dev/es ioctlv in routine
int mload_set_ES_ioctlv_vector(void *starlet_addr) {
int ret;
s32 hid = -1;
if (mload_init()<0) return -1;
hid = iosCreateHeap(0x800);
if (hid<0) return hid;
ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_SET_ES_IOCTLV, "i:", starlet_addr);
iosDestroyHeap(hid);
return ret;
}
static u32 ios_36[16] ATTRIBUTE_ALIGN(32)= {
0, // DI_EmulateCmd
0,
0x2022DDAC, // dvd_read_controlling_data
0x20201010+1, // handle_di_cmd_reentry (thumb)
0x20200b9c+1, // ios_shared_alloc_aligned (thumb)
0x20200b70+1, // ios_shared_free (thumb)
0x20205dc0+1, // ios_memcpy (thumb)
0x20200048+1, // ios_fatal_di_error (thumb)
0x20202b4c+1, // ios_doReadHashEncryptedState (thumb)
0x20203934+1, // ios_printf (thumb)
};
static u32 ios_38[16] ATTRIBUTE_ALIGN(32)= {
0, // DI_EmulateCmd
0,
0x2022cdac, // dvd_read_controlling_data
0x20200d38+1, // handle_di_cmd_reentry (thumb)
0x202008c4+1, // ios_shared_alloc_aligned (thumb)
0x20200898+1, // ios_shared_free (thumb)
0x20205b80+1, // ios_memcpy (thumb)
0x20200048+1, // ios_fatal_di_error (thumb)
0x20202874+1, // ios_doReadHashEncryptedState (thumb)
0x2020365c+1, // ios_printf (thumb)
};
int load_ehc_module() {
int is_ios=0;
if (mload_module(ehcmodule, size_ehcmodule)<0) return -1;
usleep(350*1000);
// Test for IOS
mload_seek(0x20207c84, SEEK_SET);
mload_read(patch_datas, 4);
if (patch_datas[0]==0x6e657665) {
is_ios=38;
} else {
is_ios=36;
}
if (is_ios==36) {
// IOS 36
memcpy(ios_36, dip_plugin, 4); // copy the entry_point
memcpy(dip_plugin, ios_36, 4*10); // copy the adresses from the array
mload_seek(0x1377E000, SEEK_SET); // copy dip_plugin in the starlet
mload_write(dip_plugin,size_dip_plugin);
// enables DIP plugin
mload_seek(0x20209040, SEEK_SET);
mload_write(ios_36, 4);
}
if (is_ios==38) {
// IOS 38
memcpy(ios_38, dip_plugin, 4); // copy the entry_point
memcpy(dip_plugin, ios_38, 4*10); // copy the adresses from the array
mload_seek(0x1377E000, SEEK_SET); // copy dip_plugin in the starlet
mload_write(dip_plugin,size_dip_plugin);
// enables DIP plugin
mload_seek(0x20208030, SEEK_SET);
mload_write(ios_38, 4);
}
mload_close();
return 0;
}
int patch_cios_data() {
patch_datas[0]=*((u32 *) (dip_plugin+16*4));
mload_set_ES_ioctlv_vector((void *) patch_datas[0]);
return 1;
}