2 Copyright 2009-2010, Ifcaro, jimmikaelkael & Polo
3 Copyright 2006-2008 Polo
4 Licenced under Academic Free License version 3.0
5 Review OpenUsbLd README & LICENSE files for further details.
7 Some parts of the code are taken from HD Project by Polo
17 extern void *imgdrv_irx
;
18 extern int size_imgdrv_irx
;
20 extern void *usbd_irx
;
21 extern int size_usbd_irx
;
24 extern void *mcemu_irx
;
25 extern int size_mcemu_irx
;
28 extern void *cdvdman_irx
;
29 extern int size_cdvdman_irx
;
31 extern void *cdvdfsv_irx
;
32 extern int size_cdvdfsv_irx
;
34 extern void *eesync_irx
;
35 extern int size_eesync_irx
;
37 extern void *smstcpip_irx
;
38 extern int size_smstcpip_irx
;
40 extern void *smsmap_irx
;
41 extern int size_smsmap_irx
;
43 extern void *udptty_irx
;
44 extern int size_udptty_irx
;
46 extern void *ioptrap_irx
;
47 extern int size_ioptrap_irx
;
49 /*----------------------------------------------------------------------------------------*/
50 /* Reset IOP processor. This fonction hook reset iop if an update sequence is requested. */
51 /*----------------------------------------------------------------------------------------*/
52 int New_Reset_Iop(const char *arg
, int flag
)
57 char ioprp_path
[0x50] = "\0";
58 int eeloadcnf_reset
= 0;
60 DPRINTF("New_Reset_Iop start!\n");
62 GS_BGCOLOUR
= 0xFF00FF;
65 DPRINTF("IOP reboot count = %d\n", iop_reboot_count
);
69 if (iop_reboot_count
> 1) {
70 // above 2nd IOP reset, we can't be sure we'll be able to read IOPRP without
71 // Resetting IOP (game IOPRP is loaded at 2nd reset), so...
81 while (!Reset_Iop("rom0:UDNL rom0:EELOADCNF", 0)) {;}
82 while (!Sync_Iop()){;}
89 if (GameMode
== ETH_MODE
)
90 start_smbauth_thread();
92 LoadIRXfromKernel(cdvdman_irx
, size_cdvdman_irx
, 0, NULL
);
95 GS_BGCOLOUR
= 0x00A5FF;
97 if (GameMode
== USB_MODE
) {
98 LoadIRXfromKernel(usbd_irx
, size_usbd_irx
, 0, NULL
);
100 #ifdef __LOAD_DEBUG_MODULES
101 LoadIRXfromKernel(smstcpip_irx
, size_smstcpip_irx
, 0, NULL
);
102 LoadIRXfromKernel(smsmap_irx
, size_smsmap_irx
, g_ipconfig_len
, g_ipconfig
);
103 LoadIRXfromKernel(udptty_irx
, size_udptty_irx
, 0, NULL
);
104 LoadIRXfromKernel(ioptrap_irx
, size_ioptrap_irx
, 0, NULL
);
107 else if (GameMode
== ETH_MODE
) {
108 LoadIRXfromKernel(smstcpip_irx
, size_smstcpip_irx
, 0, NULL
);
109 LoadIRXfromKernel(smsmap_irx
, size_smsmap_irx
, g_ipconfig_len
, g_ipconfig
);
110 #ifdef __LOAD_DEBUG_MODULES
111 LoadIRXfromKernel(udptty_irx
, size_udptty_irx
, 0, NULL
);
112 LoadIRXfromKernel(ioptrap_irx
, size_ioptrap_irx
, 0, NULL
);
115 else if (GameMode
== HDD_MODE
) {
116 #ifdef __LOAD_DEBUG_MODULES
117 LoadIRXfromKernel(smstcpip_irx
, size_smstcpip_irx
, 0, NULL
);
118 LoadIRXfromKernel(smsmap_irx
, size_smsmap_irx
, g_ipconfig_len
, g_ipconfig
);
119 LoadIRXfromKernel(udptty_irx
, size_udptty_irx
, 0, NULL
);
120 LoadIRXfromKernel(ioptrap_irx
, size_ioptrap_irx
, 0, NULL
);
125 // check for reboot with IOPRP from cdrom
126 char *ioprp_pattern
= "rom0:UDNL cdrom";
127 for (i
=0; i
<0x50; i
++) {
128 for (j
=0; j
<15; j
++) {
129 if (arg
[i
+j
] != ioprp_pattern
[j
])
133 // get IOPRP img file path
134 _strcpy(ioprp_path
, &arg
[i
+10]);
139 // check for reboot with IOPRP from rom
140 char *eeloadcnf_pattern
= "rom0:UDNL rom";
141 for (i
=0; i
<0x50; i
++) {
142 for (j
=0; j
<13; j
++) {
143 if (arg
[i
+j
] != eeloadcnf_pattern
[j
])
147 _strcpy(ioprp_path
, &arg
[i
+10]);
153 if ((eeloadcnf_reset
) || (ioprp_path
[0] == '\0')) {
154 ioprp_img
.data_in
= (void *)g_buf
;
155 Build_EELOADCNF_Img(&ioprp_img
, XLoadfileCheck());
158 DPRINTF("Reading IOPRP: '%s'\n", ioprp_path
);
161 fd
= open(ioprp_path
, O_RDONLY
);
163 DPRINTF("Failed to open IOPRP...\n");
165 GS_BGCOLOUR
= 0x000080;
167 register int retry_count
= 0;
168 while (retry_count
++ < 2) {
169 // some games like SOCOM3 uses faulty IOPRP path like "cdrom0:\RUN\IRX\DNAS300.IMGG;1"
170 // some games from Army Men series uses faulty IOPRP path like "cdrom0:\IRX\IOPRP205.IMG.IMG;1"
171 // this part ensure it will not get stucked on red screen
173 if (retry_count
== 1)
174 p
= _strrchr(ioprp_path
, '.');
175 else if (retry_count
== 2)
176 p
= _strchr(ioprp_path
, '.');
183 fd
= open(ioprp_path
, O_RDONLY
);
191 ioprp_img
.size_in
= lseek(fd
, 0, SEEK_END
);
192 DPRINTF("IOPRP size: %d bytes\n", ioprp_img
.size_in
);
193 if (ioprp_img
.size_in
% 0x40)
194 ioprp_img
.size_in
= (ioprp_img
.size_in
& 0xffffffc0) + 0x40;
196 lseek(fd
, 0, SEEK_SET
);
198 ioprp_img
.data_in
= (void *)g_buf
;
199 ioprp_img
.data_out
= ioprp_img
.data_in
;
200 ioprp_img
.size_out
= ioprp_img
.size_in
;
202 read(fd
, ioprp_img
.data_in
, ioprp_img
.size_in
);
207 DPRINTF("IOPRP readed\n");
209 DPRINTF("Patching CDVDMAN...\n");
210 Patch_Mod(&ioprp_img
, "CDVDMAN", cdvdman_irx
, size_cdvdman_irx
);
211 DPRINTF("Patching CDVDFSV...\n");
212 Patch_Mod(&ioprp_img
, "CDVDFSV", cdvdfsv_irx
, size_cdvdfsv_irx
);
213 DPRINTF("Patching EESYNC...\n");
214 Patch_Mod(&ioprp_img
, "EESYNC", eesync_irx
, size_eesync_irx
);
217 DPRINTF("Exiting services...\n");
223 DPRINTF("Resetting IOP...\n");
224 while (!Reset_Iop("rom0:UDNL rom0:EELOADCNF", 0)) {;}
225 while (!Sync_Iop()){;}
227 DPRINTF("Init services...\n");
231 DPRINTF("Applying Sbv patches...\n");
234 if (GameMode
== ETH_MODE
)
235 start_smbauth_thread();
237 DPRINTF("Sending patched IOPRP on IOP and try to reset with...\n");
238 rom_iop
= SifAllocIopHeap(ioprp_img
.size_out
);
241 CopyToIop(ioprp_img
.data_out
, ioprp_img
.size_out
, rom_iop
);
243 // get back imgdrv from kernel ram
246 memcpy(g_buf
, imgdrv_irx
, size_imgdrv_irx
);
250 *(u32
*)(&g_buf
[0x180]) = (u32
)rom_iop
;
251 *(u32
*)(&g_buf
[0x184]) = ioprp_img
.size_out
;
254 LoadMemModule(g_buf
, size_imgdrv_irx
, 0, NULL
);
255 LoadModuleAsync("rom0:UDNL", 5, "img0:");
262 Old_SifSetReg(SIF_REG_SMFLAG
, 0x10000);
263 Old_SifSetReg(SIF_REG_SMFLAG
, 0x20000);
264 Old_SifSetReg(0x80000002, 0);
265 Old_SifSetReg(0x80000000, 0);
269 DPRINTF("IOP memory allocation (%d bytes) failed!\n", ioprp_img
.size_out
);
271 GS_BGCOLOUR
= 0xFF0000;
275 while (!Sync_Iop()) {;}
278 DPRINTF("Init services...\n");
282 DPRINTF("Applying Sbv patches...\n");
286 GS_BGCOLOUR
= 0x00FFFF;
288 DPRINTF("Loading extra IOP modules...\n");
289 if (GameMode
== USB_MODE
) {
290 LoadIRXfromKernel(usbd_irx
, size_usbd_irx
, 0, NULL
);
292 #ifdef __LOAD_DEBUG_MODULES
293 LoadIRXfromKernel(smstcpip_irx
, size_smstcpip_irx
, 0, NULL
);
294 LoadIRXfromKernel(smsmap_irx
, size_smsmap_irx
, g_ipconfig_len
, g_ipconfig
);
295 LoadIRXfromKernel(udptty_irx
, size_udptty_irx
, 0, NULL
);
296 LoadIRXfromKernel(ioptrap_irx
, size_ioptrap_irx
, 0, NULL
);
299 else if (GameMode
== ETH_MODE
) {
300 LoadIRXfromKernel(smstcpip_irx
, size_smstcpip_irx
, 0, NULL
);
301 LoadIRXfromKernel(smsmap_irx
, size_smsmap_irx
, g_ipconfig_len
, g_ipconfig
);
302 #ifdef __LOAD_DEBUG_MODULES
303 LoadIRXfromKernel(udptty_irx
, size_udptty_irx
, 0, NULL
);
304 LoadIRXfromKernel(ioptrap_irx
, size_ioptrap_irx
, 0, NULL
);
307 else if (GameMode
== HDD_MODE
) {
308 #ifdef __LOAD_DEBUG_MODULES
309 LoadIRXfromKernel(smstcpip_irx
, size_smstcpip_irx
, 0, NULL
);
310 LoadIRXfromKernel(smsmap_irx
, size_smsmap_irx
, g_ipconfig_len
, g_ipconfig
);
311 LoadIRXfromKernel(udptty_irx
, size_udptty_irx
, 0, NULL
);
312 LoadIRXfromKernel(ioptrap_irx
, size_ioptrap_irx
, 0, NULL
);
317 if ((iop_reboot_count
>= 2) && size_mcemu_irx
) {
318 LoadIRXfromKernel(mcemu_irx
, size_mcemu_irx
, 0, NULL
);
324 DPRINTF("Exiting services...\n");
329 if (g_compat_mask
& COMPAT_MODE_8
)
330 ChangeModuleName("dev9", "cdvdman");
332 DPRINTF("New_Reset_Iop complete!\n");
333 // we have 4 SifSetReg calls to skip in ELF's SifResetIop, not when we use it ourselves
334 if (set_reg_disabled
)
340 /*----------------------------------------------------------------------------------------*/
341 /* Reset IOP processor. This fonction replace SifIopReset from Ps2Sdk */
342 /*----------------------------------------------------------------------------------------*/
343 int Reset_Iop(const char *arg
, int flag
)
345 SifCmdResetData reset_pkt
;
346 struct t_SifDmaTransfer dmat
;
352 memset(&reset_pkt
, 0, sizeof(SifCmdResetData
));
354 reset_pkt
.chdr
.psize
= sizeof(SifCmdResetData
);
355 reset_pkt
.chdr
.fcode
= 0x80000003;
357 reset_pkt
.flag
= flag
;
360 strncpy(reset_pkt
.arg
, arg
, 0x50-1);
361 reset_pkt
.arg
[0x50-1] = '\0';
362 reset_pkt
.size
= strlen(reset_pkt
.arg
) + 1;
365 dmat
.src
= &reset_pkt
;
366 dmat
.dest
= (void *)SifGetReg(0x80000000); // SIF_REG_SUBADDR
367 dmat
.size
= sizeof reset_pkt
;
368 dmat
.attr
= 0x40 | SIF_DMA_INT_O
;
369 SifWriteBackDCache(&reset_pkt
, sizeof reset_pkt
);
373 if (!Old_SifSetDma(&dmat
, 1)){
379 Old_SifSetReg(SIF_REG_SMFLAG
, 0x10000);
380 Old_SifSetReg(SIF_REG_SMFLAG
, 0x20000);
381 Old_SifSetReg(0x80000002, 0);
382 Old_SifSetReg(0x80000000, 0);
389 /*----------------------------------------------------------------------------------------*/
390 /* Synchronize IOP processor. This fonction replace SifIopReset from Ps2Sdk */
391 /*----------------------------------------------------------------------------------------*/
394 if (SifGetReg(SIF_REG_SMFLAG
) & 0x40000)