Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 1 addition & 23 deletions ee/iopreboot/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
# Review ps2sdk README & LICENSE files for further details.

IOPCONTROL_SPECIAL_EE_OBJS = _iopcontrol_special_internals.o SifIopRebootBufferEncrypted.o SifIopRebootBuffer.o
IOPCONTROL_SPECIAL_IOP_OBJS = imgdrv_irx.o
IOPCONTROL_SPECIAL_OBJS =

EE_OBJS = $(IOPCONTROL_SPECIAL_EE_OBJS) $(IOPCONTROL_SPECIAL_IOP_OBJS) erl-support.o
EE_OBJS = $(IOPCONTROL_SPECIAL_EE_OBJS) erl-support.o

include $(PS2SDKSRC)/Defs.make
include $(PS2SDKSRC)/ee/Rules.lib.make
Expand All @@ -19,24 +18,3 @@ include $(PS2SDKSRC)/ee/Rules.release
$(IOPCONTROL_SPECIAL_EE_OBJS:%=$(EE_OBJS_DIR)%): $(EE_SRC_DIR)SifIopRebootBuffer.c
$(DIR_GUARD)
$(EE_C_COMPILE) -I$(PS2SDKSRC)/ee/sbv/include -DF_$(*:$(EE_OBJS_DIR)%=%) $< -c -o $@

$(EE_OBJS_DIR)imgdrv_irx.o: $(EE_OBJS_DIR)imgdrv_irx.c
$(DIR_GUARD)
$(EE_C_COMPILE) $< -c -o $@

$(PS2SDKSRC)/tools/bin2c/bin/bin2c: $(PS2SDKSRC)/tools/bin2c
$(MAKEREC) $<

$(EE_SRC_DIR)imgdrv/irx/imgdrv.irx: $(EE_SRC_DIR)imgdrv
$(MAKEREC) $<

$(EE_OBJS_DIR)imgdrv_irx.c: $(EE_SRC_DIR)imgdrv/irx/imgdrv.irx $(PS2SDKSRC)/tools/bin2c/bin/bin2c
$(DIR_GUARD)
$(PS2SDKSRC)/tools/bin2c/bin/bin2c $< $@ _imgdrv_irx

clean::
$(MAKEREC) $(EE_SRC_DIR)imgdrv clean

.NOTPARALLEL:: \
$(PS2SDKSRC)/tools/bin2c/bin/bin2c \
$(EE_SRC_DIR)imgdrv/irx/imgdrv.irx
2 changes: 1 addition & 1 deletion ee/iopreboot/include/iopcontrol_special.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ extern int SifIopRebootBufferEncrypted(const void *udnl, int size);
* @param size Size of the IOPRP image in bytes.
* @return 1 for success or 0 for failure.
*/
extern int SifIopRebootBuffer(const void *ioprp, int size);
extern int SifIopRebootBuffer(void *ioprp, int size);

#ifdef __cplusplus
}
Expand Down
231 changes: 92 additions & 139 deletions ee/iopreboot/src/SifIopRebootBuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,103 +22,114 @@
#include "string.h"
#include "sbv_patches.h"

#define IMGDRV_IRX_SIZE ((size__imgdrv_irx + 15) & ~15) // Was a hardcoded value of 0x400 bytes
#define IOPBTCONF_IOP_MAX_SIZE 0x400

extern int _iop_reboot_count;

extern u8 iopbtconf_img[IOPBTCONF_IOP_MAX_SIZE];
extern unsigned char _imgdrv_irx[];
extern unsigned int size__imgdrv_irx;

extern int imgdrv_offset_ioprpimg;
extern int imgdrv_offset_ioprpsiz;
extern int send_romdrv_rom1_payloads(void *payload1, int payload1_size, void *payload2, int payload2_size);

extern void init_imgdrv_offsets(void);
typedef struct romdir
{
char name[10];
u16 ExtInfoEntrySize;
u32 size;
} romdir_t;

typedef struct extinfo
{
u16 value; /* Only applicable for the version field type. */
u8 ExtLength; /* The length of data appended to the end of this entry. */
u8 type;
} extinfo_t;

enum EXTINFO_TYPE {
EXTINFO_TYPE_DATE = 1,
EXTINFO_TYPE_VERSION,
EXTINFO_TYPE_COMMENT,
EXTINFO_TYPE_FIXED = 0x7F // Must exist at a fixed location.
};

#ifdef F__iopcontrol_special_internals
u8 iopbtconf_img[IOPBTCONF_IOP_MAX_SIZE] __attribute__((aligned(64)));
int imgdrv_offset_ioprpimg = 0;
int imgdrv_offset_ioprpsiz = 0;

void init_imgdrv_offsets(void)
struct payload_img
{
if (imgdrv_offset_ioprpimg == 0 || imgdrv_offset_ioprpsiz == 0) {
int i;

for (i = 0; (unsigned int)i < size__imgdrv_irx; i += 4) {
if (*(u32 *)((&((unsigned char *)_imgdrv_irx)[i])) == 0xDEC1DEC1) {
imgdrv_offset_ioprpimg = i;
}
if (*(u32 *)((&((unsigned char *)_imgdrv_irx)[i])) == 0xDEC2DEC2) {
imgdrv_offset_ioprpsiz = i;
}
}
}
romdir_t romdir[5];
};

static const struct payload_img g_payload_img_base = {
{{"RESET", 0, 0},
{"ROMDIR", 0, 0x50},
{"0", 0, 0},
{"1", 0, 0},
{"", 0, 0}},
};

int send_romdrv_rom1_payloads(void *payload1, int payload1_size, void *payload2, int payload2_size)
{
unsigned int i;
unsigned int size_total;
struct payload_img cur_payload_img __attribute__((__aligned__(64)));
SifDmaTransfer_t dmat[3];
int trid;

cur_payload_img = g_payload_img_base;
dmat[0].src = &cur_payload_img;
dmat[0].size = sizeof(cur_payload_img);
dmat[1].src = payload1;
dmat[1].size = (payload1_size + 15) & -16;
dmat[2].src = payload2;
dmat[2].size = (payload2_size + 15) & -16;
for (i = 0; i < (sizeof(dmat)/sizeof(dmat[0])); i += 1)
dmat[i].attr = 0;
cur_payload_img.romdir[1].size = dmat[0].size;
cur_payload_img.romdir[2].size = dmat[1].size;
cur_payload_img.romdir[3].size = dmat[2].size;
size_total = 0;
for (i = 0; i < (sizeof(dmat)/sizeof(dmat[0])); i += 1)
size_total += dmat[i].size;
dmat[0].dest = SifAllocIopHeap(size_total);
if (!dmat[0].dest)
return -1;
for (i = 1; i < (sizeof(dmat)/sizeof(dmat[0])); i += 1)
dmat[i].dest = ((u8 *)dmat[i - 1].dest) + dmat[i - 1].size;
for (i = 0; i < (sizeof(dmat)/sizeof(dmat[0])); i += 1)
sceSifWriteBackDCache(dmat[i].src, dmat[i].size);
while (!(trid = sceSifSetDma(dmat, sizeof(dmat) / sizeof(dmat[0]))));
while (sceSifDmaStat(trid) >= 0);
return sbv_patch_romdrv_set_rom1_info(dmat[0].dest, dmat[0].size) ? 1 : 0;
}
#endif

// Our LOADFILE functions are slightly different.
#define SifLoadModuleSpecial(path, arg_len, args, dontwait) \
_SifLoadModule(path, arg_len, args, NULL, LF_F_MOD_LOAD, dontwait);
_SifLoadModule(path, arg_len, args, NULL, LF_F_MOD_LOAD, dontwait)

#define SifLoadModuleEncryptedSpecial(path, arg_len, args, dontwait) \
_SifLoadModule(path, arg_len, args, NULL, LF_F_MG_MOD_LOAD, dontwait);
_SifLoadModule(path, arg_len, args, NULL, LF_F_MG_MOD_LOAD, dontwait)

#ifdef F_SifIopRebootBufferEncrypted
int SifIopRebootBufferEncrypted(const void *udnl, int size)
{
int iopbtconf_img_size;
void *imgdrv_iop, *udnl_iop, *iopbtconf_img_iop;
int *imgdrv_img_size;
void **imgdrv_img;
SifDmaTransfer_t dmat[3];

sceSifInitRpc(0);
sceSifExitRpc();

SifIopReset("", 0);
while (!SifIopSync()) {};

SifLoadFileInit();
SifInitIopHeap();
while (!SifIopSync());

imgdrv_iop = SifAllocIopHeap(IMGDRV_IRX_SIZE);
udnl_iop = SifAllocIopHeap(size);
iopbtconf_img_iop = SifAllocIopHeap(IOPBTCONF_IOP_MAX_SIZE);
iopbtconf_img_size = 0; // No support for IOPBTCONF manipulation

if (imgdrv_iop == NULL || udnl_iop == NULL || iopbtconf_img_iop == NULL)
/* Unofficial: Use following instead of patching LoadModuleBuffer and using embedded imgdrv */
if (send_romdrv_rom1_payloads((void *)udnl, size, iopbtconf_img, iopbtconf_img_size))
return -1;

iopbtconf_img_size = 0; // No support for IOPBTCONF manipulation

init_imgdrv_offsets();
imgdrv_img = (void **)&_imgdrv_irx[imgdrv_offset_ioprpimg];
imgdrv_img_size = (int *)&_imgdrv_irx[imgdrv_offset_ioprpsiz];
dmat[0].src = _imgdrv_irx;
dmat[0].dest = imgdrv_iop;
dmat[0].size = IMGDRV_IRX_SIZE;
dmat[0].attr = 0;
dmat[1].src = (void *)udnl;
dmat[1].dest = udnl_iop;
dmat[1].size = size;
dmat[1].attr = 0;
dmat[2].src = iopbtconf_img;
dmat[2].dest = iopbtconf_img_iop;
dmat[2].size = iopbtconf_img_size;
dmat[2].attr = 0;
imgdrv_img[0] = udnl_iop;
imgdrv_img[1] = iopbtconf_img_iop;
imgdrv_img_size[0] = size;
imgdrv_img_size[1] = iopbtconf_img_size;
FlushCache(0);
sceSifSetDma(dmat, 3);

sbv_patch_enable_lmb();

SifLoadModule("rom0:SYSCLIB", 0, NULL);
SifLoadModuleBuffer(imgdrv_iop, 0, NULL);
SifLoadModuleEncryptedSpecial("img0:", 0, NULL, 1);
/* Unofficial: do not load rom:SYSCLIB (DMA end checking is done above) */
/* If ELF header detected, load UDNL as unencrypted module */
(void)((((u32 *)udnl)[0] == 0x464c457f) ? SifLoadModuleSpecial("rom1:0", 0, NULL, 1) : SifLoadModuleEncryptedSpecial("rom1:0", 0, NULL, 1));

sceSifExitRpc();
SifLoadFileExit();
Expand All @@ -136,61 +147,26 @@ int SifIopRebootBufferEncrypted(const void *udnl, int size)
#endif

#ifdef F_SifIopRebootBuffer
static int generateIOPBTCONF_img(void *output, const void *ioprp);
static int generateIOPBTCONF_img(void *output, void *ioprp);

int SifIopRebootBuffer(const void *ioprp, int size)
int SifIopRebootBuffer(void *ioprp, int size)
{
int iopbtconf_img_size;
void *imgdrv_iop, *ioprp_iop, *iopbtconf_img_iop;
int *imgdrv_img_size;
void **imgdrv_img;
SifDmaTransfer_t dmat[3];

sceSifInitRpc(0);
sceSifExitRpc();

SifIopReset("", 0);
while (!SifIopSync()) {};
while (!SifIopSync());

SifLoadFileInit();
SifInitIopHeap();

imgdrv_iop = SifAllocIopHeap(IMGDRV_IRX_SIZE);
ioprp_iop = SifAllocIopHeap(size);
iopbtconf_img_iop = SifAllocIopHeap(IOPBTCONF_IOP_MAX_SIZE);
iopbtconf_img_size = generateIOPBTCONF_img(iopbtconf_img, ioprp);

if (imgdrv_iop == NULL || ioprp_iop == NULL || iopbtconf_img_iop == NULL)
/* Unofficial: Use following instead of patching LoadModuleBuffer and using embedded imgdrv */
if (send_romdrv_rom1_payloads((void *)ioprp, size, iopbtconf_img, iopbtconf_img_size))
return -1;

iopbtconf_img_size = generateIOPBTCONF_img(iopbtconf_img, ioprp);

init_imgdrv_offsets();
imgdrv_img = (void **)&_imgdrv_irx[imgdrv_offset_ioprpimg];
imgdrv_img_size = (int *)&_imgdrv_irx[imgdrv_offset_ioprpsiz];
dmat[0].src = _imgdrv_irx;
dmat[0].dest = imgdrv_iop;
dmat[0].size = IMGDRV_IRX_SIZE;
dmat[0].attr = 0;
dmat[1].src = (void *)ioprp;
dmat[1].dest = ioprp_iop;
dmat[1].size = size;
dmat[1].attr = 0;
dmat[2].src = iopbtconf_img;
dmat[2].dest = iopbtconf_img_iop;
dmat[2].size = iopbtconf_img_size;
dmat[2].attr = 0;
imgdrv_img[0] = ioprp_iop;
imgdrv_img[1] = iopbtconf_img_iop;
imgdrv_img_size[0] = size;
imgdrv_img_size[1] = iopbtconf_img_size;
FlushCache(0);
sceSifSetDma(dmat, 3);

sbv_patch_enable_lmb();

SifLoadModule("rom0:SYSCLIB", 0, NULL);
SifLoadModuleBuffer(imgdrv_iop, 0, NULL);
SifLoadModuleSpecial("rom0:UDNL", 11, "img0:\0img1:", 1);
/* Unofficial: do not load rom:SYSCLIB (DMA end checking is done above) */
SifLoadModuleSpecial("rom:UDNL", 13, "rom1:0\x00rom1:1", 1);

sceSifExitRpc();
SifLoadFileExit();
Expand All @@ -206,27 +182,6 @@ int SifIopRebootBuffer(const void *ioprp, int size)
return 1;
}

typedef struct romdir
{
char name[10];
u16 ExtInfoEntrySize;
u32 size;
} romdir_t;

typedef struct extinfo
{
u16 value; /* Only applicable for the version field type. */
u8 ExtLength; /* The length of data appended to the end of this entry. */
u8 type;
} extinfo_t;

enum EXTINFO_TYPE {
EXTINFO_TYPE_DATE = 1,
EXTINFO_TYPE_VERSION,
EXTINFO_TYPE_COMMENT,
EXTINFO_TYPE_FIXED = 0x7F // Must exist at a fixed location.
};

struct iopbtconf_img
{
romdir_t romdir[5];
Expand All @@ -248,35 +203,33 @@ static const struct iopbtconf_img iopbtconf_img_base = {

/* Generate an IOPRP image that contains IOPBTCONF, if the original contains IOPBTCONF.
This is required because UDNL will only seach succeeding IOPRP images for modules specified within IOPBTCONF. */
static int generateIOPBTCONF_img(void *output, const void *ioprp)
static int generateIOPBTCONF_img(void *output, void *ioprp)
{
int size, offset, fsize_rounded;
int offset, fsize_rounded;
romdir_t *romdir;
const u8 *ptr_in;
u8 *ptr_in;
u8 *ptr_out;

romdir = (romdir_t *)ioprp;
if (strcmp(romdir[0].name, "RESET") || strcmp(romdir[1].name, "ROMDIR"))
return -1;

// Now locate IOPBTCONF
size = 0;
offset = 0;
for (; romdir->name[0] != '\0'; romdir++, offset += fsize_rounded) {
for (offset = 0; romdir->name[0] != '\0'; romdir++, offset += fsize_rounded) {
fsize_rounded = (romdir->size + 15) & ~15;
if (strcmp(romdir->name, "IOPBTCONF") == 0) {
/* Unofficial: Check for already-patched image */
if (!strcmp(romdir->name, "IOPBTCONF") || !strcmp(romdir->name, "XOPBTCONF")) {
romdir->name[0] = 'X'; // Change 'IOPBTCONF' to 'XOPBTCONF', so that UDNL will not find the original.
// Copy IOPBTCONF into the new image.
size = romdir->size + sizeof(iopbtconf_img_base);
ptr_out = (u8 *)output;
ptr_in = (const u8 *)ioprp;
ptr_in = (u8 *)ioprp;
memcpy(ptr_out, &iopbtconf_img_base, sizeof(iopbtconf_img_base));
memcpy(ptr_out + sizeof(iopbtconf_img_base), &ptr_in[offset], romdir->size);
((romdir_t *)ptr_out)[3].size = romdir->size; // Update the size of IOPBTCONF within the generated IOPRP image.
break;
return romdir->size + sizeof(iopbtconf_img_base);
}
}

return size;
return 0;
}
#endif
19 changes: 0 additions & 19 deletions ee/iopreboot/src/imgdrv/Makefile

This file was deleted.

Loading
Loading