Skip to content

Commit

Permalink
Make used UDNL configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
rickgaiser committed Sep 2, 2024
1 parent 9f62b41 commit c8c265f
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 25 deletions.
29 changes: 22 additions & 7 deletions ee/ee_core/src/iopmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
extern int _iop_reboot_count;
extern void *ModStorageStart;

int _SifExecModuleBuffer(const void *ptr, u32 size, u32 arg_len, const char *args, int *mod_res, int dontwait);

#ifdef __EESIO_DEBUG
static void print_iop_args(int arg_len, const char *args)
{
Expand Down Expand Up @@ -55,8 +57,8 @@ int New_Reset_Iop(const char *arg, int arglen)
{
int i;
void *pIOP_buffer;
const void *IOPRP_img, *imgdrv_irx;
unsigned int length_rounded, udnl_cmdlen, size_IOPRP_img, size_imgdrv_irx;
const void *IOPRP_img, *imgdrv_irx, *udnl_irx;
unsigned int length_rounded, udnl_cmdlen, size_IOPRP_img, size_imgdrv_irx, size_udnl_irx;
char udnl_mod[10];
char udnl_cmd[RESET_ARG_MAX + 1];
irxtab_t *irxtable = (irxtab_t *)ModStorageStart;
Expand Down Expand Up @@ -105,12 +107,15 @@ int New_Reset_Iop(const char *arg, int arglen)
udnl_cmdlen += 6;

// FIXED modules:
// 0 = IOPRP image
// 1 = imgdrv
// 0 = IOPRP.img
// 1 = imgdrv.irx
// 2 = udnl.irx
IOPRP_img = irxtable->modules[0].ptr;
size_IOPRP_img = irxtable->modules[0].size;
imgdrv_irx = irxtable->modules[1].ptr;
size_imgdrv_irx = irxtable->modules[1].size;
udnl_irx = irxtable->modules[2].ptr;
size_udnl_irx = irxtable->modules[2].size;

// Manually copy IOPRP to IOP
length_rounded = (size_IOPRP_img + 0xF) & ~0xF;
Expand All @@ -136,7 +141,14 @@ int New_Reset_Iop(const char *arg, int arglen)
ee_kmode_exit();
EIntr();

_SifLoadModule(udnl_mod, udnl_cmdlen, udnl_cmd, NULL, LF_F_MOD_LOAD, 1);
if (udnl_irx != NULL) {
// Load custom UDNL
_SifExecModuleBuffer(udnl_irx, size_udnl_irx, udnl_cmdlen, udnl_cmd, NULL, 1);
}
else {
// Load system UDNL
_SifLoadModule(udnl_mod, udnl_cmdlen, udnl_cmd, NULL, LF_F_MOD_LOAD, 1);
}

DIntr();
ee_kmode_enter();
Expand All @@ -161,8 +173,11 @@ int New_Reset_Iop(const char *arg, int arglen)
sbv_patch_enable_lmb();

DPRINTF("Loading extra IOP modules...\n");
// Skip the first 2 modules (IOPRP.IMG and imgdrv.irx)
for (i = 2; i < irxtable->count; i++) {
// Skip the first modules:
// 0 = IOPRP.IMG
// 1 = imgdrv.irx
// 2 = udnl.irx
for (i = 3; i < irxtable->count; i++) {
irxptr_t p = irxtable->modules[i];
SifExecModuleBuffer((void *)p.ptr, p.size, p.arg_len, p.args, NULL);
}
Expand Down
32 changes: 21 additions & 11 deletions ee/ee_core/src/loadfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ extern SifRpcClientData_t _lf_cd;
extern int _lf_init;

int _SifLoadElfPart(const char *path, const char *secname, t_ExecData *data, int fno);
int _SifLoadModuleBuffer(void *ptr, int arg_len, const char *args, int *modres);
int _SifLoadModuleBuffer(void *ptr, int arg_len, const char *args, int *modres, int dontwait);

//#if defined(F_SifLoadFileInit)
SifRpcClientData_t _lf_cd;
Expand Down Expand Up @@ -317,7 +317,7 @@ int SifIopGetVal(u32 iop_addr, void *val, int type)
#endif

//#ifdef F__SifLoadModuleBuffer
int _SifLoadModuleBuffer(void *ptr, int arg_len, const char *args, int *modres)
int _SifLoadModuleBuffer(void *ptr, int arg_len, const char *args, int *modres, int dontwait)
{
struct _lf_module_buffer_load_arg arg;

Expand All @@ -334,7 +334,7 @@ int _SifLoadModuleBuffer(void *ptr, int arg_len, const char *args, int *modres)
arg.q.arg_len = 0;
}

if (SifCallRpc(&_lf_cd, LF_F_MOD_BUF_LOAD, 0, &arg, sizeof arg, &arg, 8,
if (SifCallRpc(&_lf_cd, LF_F_MOD_BUF_LOAD, dontwait, &arg, sizeof arg, &arg, 8,
NULL, NULL) < 0)
return -SCE_ECALLMISS;

Expand All @@ -348,19 +348,19 @@ int _SifLoadModuleBuffer(void *ptr, int arg_len, const char *args, int *modres)
#if defined(F_SifLoadModuleBuffer)
int SifLoadModuleBuffer(void *ptr, int arg_len, const char *args)
{
return _SifLoadModuleBuffer(ptr, arg_len, args, NULL);
return _SifLoadModuleBuffer(ptr, arg_len, args, NULL, 0);
}
#endif

#if defined(F_SifLoadStartModuleBuffer)
int SifLoadStartModuleBuffer(void *ptr, int arg_len, const char *args, int *mod_res)
{
return _SifLoadModuleBuffer(ptr, arg_len, args, mod_res);
return _SifLoadModuleBuffer(ptr, arg_len, args, mod_res, 0);
}
#endif

//#if defined(F_SifExecModuleBuffer)
int SifExecModuleBuffer(void *ptr, u32 size, u32 arg_len, const char *args, int *mod_res)
int _SifExecModuleBuffer(const void *ptr, u32 size, u32 arg_len, const char *args, int *mod_res, int dontwait)
{
SifDmaTransfer_t dmat;
void *iop_addr;
Expand Down Expand Up @@ -394,11 +394,11 @@ int SifExecModuleBuffer(void *ptr, u32 size, u32 arg_len, const char *args, int
// Free temp buffer
SifFreeIopHeap(ptemp);

dmat.src = ptr;
dmat.src = (void *)ptr;
dmat.dest = iop_addr;
dmat.size = size;
dmat.attr = 0;
SifWriteBackDCache(ptr, size);
SifWriteBackDCache((void *)ptr, size);
qid = SifSetDma(&dmat, 1);

if (!qid)
Expand All @@ -407,13 +407,23 @@ int SifExecModuleBuffer(void *ptr, u32 size, u32 arg_len, const char *args, int
while (SifDmaStat(qid) >= 0)
;

res = _SifLoadModuleBuffer(iop_addr, arg_len, args, mod_res);
SifFreeIopHeap(iop_addr);
res = _SifLoadModuleBuffer(iop_addr, arg_len, args, mod_res, dontwait);

if (dontwait == 0) {
// This should only happen when loading UDNL during IOP reboot
// Check if this does not cause a memory leak
SifFreeIopHeap(iop_addr);
}

return res;
}
//#endif

int SifExecModuleBuffer(void *ptr, u32 size, u32 arg_len, const char *args, int *mod_res)
{
return _SifExecModuleBuffer(ptr, size, arg_len, args, mod_res, 0);
}

#if defined(F_SifExecModuleFile)
int SifExecModuleFile(const char *path, u32 arg_len, const char *args, int *mod_res)
{
Expand All @@ -436,7 +446,7 @@ int SifExecModuleFile(const char *path, u32 arg_len, const char *args, int *mod_
return res;
}

res = _SifLoadModuleBuffer(iop_addr, arg_len, args, mod_res);
res = _SifLoadModuleBuffer(iop_addr, arg_len, args, mod_res, 0);
SifFreeIopHeap(iop_addr);

return res;
Expand Down
3 changes: 3 additions & 0 deletions ee/loader/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ GAME = 'DVD/Ratchet Clank - Up Your Arsenal (U).iso'
#GAME = 'DVD/Gran Turismo 4 (U).iso'
#GAME = 'CD/OPL_Accurate_Read_v1.0.iso'
#GAME = 'DVD/Kidou Senshi Gundam - Ichinen Sensou (J).iso'
#GAME = 'DVD/Auto Modellista (E).iso'

# Example arguments
#-bsd=udpbd -dvd=mass:$(GAME)
Expand Down Expand Up @@ -163,6 +164,8 @@ copy:
cp ../../iop/smap_udpbd/irx/smap_udpbd.irx modules
cp ../../iop/usbd_null/irx/usbd_null.irx modules
cp ../ee_core/ee_core.elf modules
cp $(PS2SDK)/iop/irx/udnl.irx modules
cp $(PS2SDK)/iop/irx/udnl-t300.irx modules
cp $(PS2SDK)/iop/irx/eesync.irx modules
cp $(PS2SDK)/iop/irx/iomanX.irx modules
cp $(PS2SDK)/iop/irx/fileXio.irx modules
Expand Down
9 changes: 9 additions & 0 deletions ee/loader/config/system.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,16 @@ ioprp = "EESYNC"
env = ["EE"]
[[module]]
file = "imgdrv.irx"
func = "IMGDRV" # used by EECORE durion IOP reboot
env = ["EE"]
# By default the system rom0:UDNL will be used, but this can be overruled here
# Some games (like Auto Modellista) don't work over USB with the default UDNL.
[[module]]
file = "udnl.irx"
#file = "udnl-t300.irx"
func = "UDNL" # used by EECORE durion IOP reboot
env = ["EE"]
[[module]]
file = "fakemod.irx"
func = "FAKEMOD" # loaded last, so we don't fake our own modules
env = ["EE"]
46 changes: 39 additions & 7 deletions ee/loader/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ struct SModule
{
const char *sFileName;
const char *sUDNL;
const char *sFunc;

off_t iSize;
void *pData;
Expand Down Expand Up @@ -295,6 +296,21 @@ struct SModule *modlist_get_by_udnlname(struct SModList *ml, const char *name)
return NULL;
}

struct SModule *modlist_get_by_func(struct SModList *ml, const char *func)
{
int i;

for (i = 0; i < ml->count; i++) {
struct SModule *m = &ml->mod[i];
if (m->sFunc != NULL) {
if (strcmp(m->sFunc, func) == 0)
return m;
}
}

return NULL;
}

static void print_iop_args(int arg_len, const char *args)
{
// Multiple null terminated strings together
Expand Down Expand Up @@ -326,7 +342,7 @@ static uint8_t * module_install(struct SModule *mod, uint8_t *addr, irxptr_t *ir
{
if (mod == NULL) {
printf("ERROR: mod == NULL\n");
return 0;
return addr;
}

// Install module
Expand Down Expand Up @@ -516,6 +532,9 @@ int modlist_add(struct SModList *ml, toml_table_t *t)
v = toml_string_in(t, "ioprp");
if (v.ok)
m->sUDNL = v.u.s; // NOTE: passing ownership of dynamic memory
v = toml_string_in(t, "func");
if (v.ok)
m->sFunc = v.u.s; // NOTE: passing ownership of dynamic memory
arr = toml_array_in(t, "args");
if (arr != NULL) {
int i;
Expand Down Expand Up @@ -1094,7 +1113,7 @@ int main(int argc, char *argv[])

// FAKEMOD optional module
// Only loaded when modules need to be faked
struct SModule *mod_fakemod = modlist_get_by_name(&drv.mod, "fakemod.irx");
struct SModule *mod_fakemod = modlist_get_by_func(&drv.mod, "FAKEMOD");

// Load module settings for fhi_bd_defrag backing store
struct fhi_bd_defrag *set_fhi_bd_defrag = modlist_get_settings(&drv.mod, "fhi_bd_defrag.irx");
Expand Down Expand Up @@ -1433,12 +1452,16 @@ int main(int argc, char *argv[])
#pragma GCC diagnostic pop

// Count the number of modules to pass to the ee_core
int modcount = 1; // IOPRP
int modcount = 3; // IOPRP, IMGDRV and UDNL
for (i = 0; i < drv.mod.count; i++) {
struct SModule *pm = &drv.mod.mod[i];
if ((pm->env & MOD_ENV_EE) && (pm->sUDNL == NULL))
if ((pm->env & MOD_ENV_EE) && (pm->sUDNL == NULL) && (pm->sFunc == NULL))
modcount++;
}
if (drv.fake.count > 0) {
// FAKEMOD
modcount++;
}

irxtable = (irxtab_t *)get_modstorage(sGameID);
if (irxtable == NULL)
Expand Down Expand Up @@ -1470,15 +1493,24 @@ int main(int argc, char *argv[])
//
// Load modules into place
//
// IMGDRV
irxptr = module_install(modlist_get_by_func(&drv.mod, "IMGDRV"), irxptr, irxptr_tab++);
irxtable->count++;
// UDNL, entry is always present, even if there is no custom UDNL module
if (modlist_get_by_func(&drv.mod, "UDNL") != NULL)
irxptr = module_install(modlist_get_by_func(&drv.mod, "UDNL"), irxptr, irxptr_tab);
irxptr_tab++;
irxtable->count++;
// All other modules
for (i = 0; i < drv.mod.count; i++) {
struct SModule *pm = &drv.mod.mod[i];
// Load only the modules that are not part of IOPRP / UDNL
if ((pm->env & MOD_ENV_EE) && (pm->sUDNL == NULL) && (pm != mod_fakemod)) {
// Load only the modules that are not part of IOPRP and don't have a special function
if ((pm->env & MOD_ENV_EE) && (pm->sUDNL == NULL) && (pm->sFunc == NULL)) {
irxptr = module_install(pm, irxptr, irxptr_tab++);
irxtable->count++;
}
}
// Load FAKEMOD last, to prevent it from faking our own modules
// FAKEMOD last, to prevent it from faking our own modules
if (drv.fake.count > 0) {
irxptr = module_install(mod_fakemod, irxptr, irxptr_tab++);
irxtable->count++;
Expand Down

0 comments on commit c8c265f

Please sign in to comment.