Hey Hominem ... don't commit shit you used for trying to reproduce some bug ;)
[open-ps2-loader/simon.git] / ee_core / src / util.c
bloba2866d7ac96b8eca04637d6ba5f986ea7ed88a12
1 /*
2 Copyright 2009-2010, Ifcaro, jimmikaelkael & Polo
3 Copyright 2006-2008 Polo
4 Licenced under Academic Free License version 3.0
5 Review Open PS2 Loader README & LICENSE files for further details.
7 Some parts of the code are taken from HD Project by Polo
8 */
10 #include "ee_core.h"
11 #include "iopmgr.h"
12 #include "util.h"
14 extern void *cdvdman_irx;
15 extern int size_cdvdman_irx;
17 extern void *cdvdfsv_irx;
18 extern int size_cdvdfsv_irx;
21 /* Do not link to strcpy() from libc */
22 inline void _strcpy(char *dst, const char *src)
24 strncpy(dst, src, strlen(src)+1);
27 /* Do not link to strcat() from libc */
28 inline void _strcat(char *dst, const char *src)
30 _strcpy(&dst[strlen(dst)], src);
33 /* Do not link to strncmp() from libc */
34 int _strncmp(const char *s1, const char *s2, int length)
36 const char *a = s1;
37 const char *b = s2;
39 while (length > 0) {
40 if ((*a == 0) || (*b == 0))
41 return -1;
42 if (*a++ != *b++)
43 return 1;
44 length--;
47 return 0;
50 /* Do not link to strcmp() from libc */
51 int _strcmp(const char *s1, const char *s2)
53 register int i = 0;
55 while ((s1[i] != 0) && (s1[i] == s2[i]))
56 i++;
58 if (s1[i] > s2[i])
59 return 1;
60 else if (s1[i] < s2[i])
61 return -1;
63 return 0;
66 /* Do not link to strchr() from libc */
67 char *_strchr(const char *string, int c)
69 while (*string) {
70 if (*string == c)
71 return (char *)string;
72 string++;
75 if (*string == c)
76 return (char *)string;
78 return NULL;
81 /* Do not link to strrchr() from libc */
82 char *_strrchr(const char * string, int c)
84 /* use the asm strchr to do strrchr */
85 char* lastmatch;
86 char* result;
88 /* if char is never found then this will return 0 */
89 /* if char is found then this will return the last matched location
90 before strchr returned 0 */
92 lastmatch = 0;
93 result = _strchr(string,c);
95 while ((int)result != 0) {
96 lastmatch=result;
97 result = _strchr(lastmatch+1,c);
100 return lastmatch;
103 /* Do not link to strtok() from libc */
104 char *_strtok(char *strToken, const char *strDelimit)
106 static char* start;
107 static char* end;
109 if (strToken != NULL)
110 start = strToken;
111 else {
112 if (*end == 0)
113 return 0;
115 start=end;
118 if(*start == 0)
119 return 0;
121 // Strip out any leading delimiters
122 while (_strchr(strDelimit, *start)) {
123 // If a character from the delimiting string
124 // then skip past it
126 start++;
128 if (*start == 0)
129 return 0;
132 if (*start == 0)
133 return 0;
135 end=start;
137 while (*end != 0) {
138 if (_strchr(strDelimit, *end)) {
139 // if we find a delimiting character
140 // before the end of the string, then
141 // terminate the token and move the end
142 // pointer to the next character
143 *end = 0;
144 end++;
145 return start;
147 end++;
150 // reached the end of the string before finding a delimiter
151 // so dont move on to the next character
152 return start;
155 /* Do not link to strstr() from libc */
156 char *_strstr(const char *string, const char *substring)
158 char* strpos;
160 if (string == 0)
161 return 0;
163 if (strlen(substring)==0)
164 return (char*)string;
166 strpos = (char*)string;
168 while (*strpos != 0) {
169 if (_strncmp(strpos, substring, strlen(substring)) == 0)
170 return strpos;
172 strpos++;
175 return 0;
178 /* Do not link to islower() from libc */
179 inline int _islower(int c)
181 if ((c < 'a') || (c > 'z'))
182 return 0;
184 // passed both criteria, so it
185 // is a lower case alpha char
186 return 1;
189 /* Do not link to toupper() from libc */
190 inline int _toupper(int c)
192 if (_islower(c))
193 c -= 32;
195 return c;
198 /* Do not link to memcmp() from libc */
199 int _memcmp(const void *s1, const void *s2, unsigned int length)
201 const char *a = s1;
202 const char *b = s2;
204 while (length--) {
205 if (*a++ != *b++)
206 return 1;
209 return 0;
212 /*----------------------------------------------------------------------------------------*/
213 /* This function converts string to unsigned integer. Stops on illegal characters. */
214 /* Put here because including atoi rises the size of loader.elf by another kilobyte */
215 /* and that causes some games to stop working. */
216 /*----------------------------------------------------------------------------------------*/
217 unsigned int _strtoui(const char* p)
219 if (!p)
220 return 0;
222 int r = 0;
224 while (*p)
226 if ((*p < '0') || (*p > '9'))
227 return r;
229 r = r * 10 + (*p++ - '0');
232 return r;
235 /*----------------------------------------------------------------------------------------*/
236 /* This function format g_ipconfig with ip, netmask, and gateway */
237 /*----------------------------------------------------------------------------------------*/
238 void set_ipconfig(void)
240 memset(g_ipconfig, 0, IPCONFIG_MAX_LEN);
241 g_ipconfig_len = 0;
243 // add ip to g_ipconfig buf
244 strncpy(&g_ipconfig[g_ipconfig_len], g_ps2_ip, 16);
245 g_ipconfig_len += strlen(g_ps2_ip) + 1;
247 // add netmask to g_ipconfig buf
248 strncpy(&g_ipconfig[g_ipconfig_len], g_ps2_netmask, 16);
249 g_ipconfig_len += strlen(g_ps2_netmask) + 1;
251 // add gateway to g_ipconfig buf
252 strncpy(&g_ipconfig[g_ipconfig_len], g_ps2_gateway, 16);
253 g_ipconfig_len += strlen(g_ps2_gateway) + 1;
256 /*----------------------------------------------------------------------------------------*/
257 /* This function retrieve a pattern in a buffer, using a mask */
258 /*----------------------------------------------------------------------------------------*/
259 u32 *find_pattern_with_mask(u32 *buf, u32 bufsize, u32 *pattern, u32 *mask, u32 len)
261 register u32 i, j;
263 len /= sizeof(u32);
264 bufsize /= sizeof(u32);
266 for (i = 0; i < bufsize - len; i++) {
267 for (j = 0; j < len; j++) {
268 if ((buf[i + j] & mask[j]) != pattern[j])
269 break;
271 if (j == len)
272 return &buf[i];
275 return NULL;
278 /*----------------------------------------------------------------------------------------*/
279 /* Copy 'size' bytes of 'eedata' from EE to 'iopptr' in IOP. */
280 /*----------------------------------------------------------------------------------------*/
281 void CopyToIop(void *eedata, unsigned int size, void *iopptr)
283 SifDmaTransfer_t dmadata;
284 register int id;
286 dmadata.src = eedata;
287 dmadata.dest = iopptr;
288 dmadata.size = size;
289 dmadata.attr = 0;
293 id = SifSetDma(&dmadata, 1);
294 } while (!id);
296 while (SifDmaStat(id) >= 0) {;}
299 /*----------------------------------------------------------------------------------------*/
300 /* Replace a module in a IOPRP image. */
301 /*----------------------------------------------------------------------------------------*/
302 int Patch_Mod(ioprp_t *ioprp_img, const char *name, void *modptr, int modsize)
304 int i, offset_in, bytes_to_move, next_mod_offset, diff;
305 romdir_t *romdir_in;
306 u8 *p = (u8 *)ioprp_img->data_in;
308 // arrange modsize to next 16 bytes align
309 if (modsize % 0x10)
310 modsize = (modsize + 0x10) & 0xfffffff0;
312 offset_in = 0;
313 romdir_in = (romdir_t*)ioprp_img->data_in;
315 // scan for module offset & size
316 while(strlen(romdir_in->fileName) > 0)
318 //scr_printf("%s:%d ", romdir_in->fileName, romdir_in->fileSize);
319 if (!_strcmp(romdir_in->fileName, name))
320 break;
322 if ((romdir_in->fileSize % 0x10)==0)
323 offset_in += romdir_in->fileSize;
324 else
325 offset_in += (romdir_in->fileSize + 0x10) & 0xfffffff0;
327 romdir_in++;
330 // if module found
331 if (offset_in) {
332 if ((romdir_in->fileSize % 0x10)==0)
333 next_mod_offset = offset_in + romdir_in->fileSize;
334 else
335 next_mod_offset = offset_in + ((romdir_in->fileSize + 0x10) & 0xfffffff0);
337 bytes_to_move = ioprp_img->size_in - next_mod_offset;
339 // and greater than one in IOPRP img
340 if (modsize >= romdir_in->fileSize) {
341 diff = modsize - romdir_in->fileSize;
342 if (diff > 0) {
343 if (bytes_to_move > 0) {
344 for (i = ioprp_img->size_in; i >= next_mod_offset; i--)
345 p[i + diff] = p[i];
347 ioprp_img->size_in += diff;
351 // or smaller than one in IOPRP
352 else {
353 diff = romdir_in->fileSize - modsize;
354 if (diff > 0) {
355 if (bytes_to_move > 0) {
356 for (i = 0; i < bytes_to_move; i++)
357 p[offset_in + modsize + i] = p[next_mod_offset + i];
359 ioprp_img->size_in -= diff;
364 // finally replace module
365 DIntr();
366 ee_kmode_enter();
367 memcpy((void *)(ioprp_img->data_in+offset_in), modptr, modsize);
368 ee_kmode_exit();
369 EIntr();
371 // correct filesize in romdir
372 romdir_in->fileSize = modsize;
375 ioprp_img->size_out = ioprp_img->size_in;
377 return 1;
380 /*----------------------------------------------------------------------------------------*/
381 /* Build an EELOAD Config file */
382 /*----------------------------------------------------------------------------------------*/
383 int Build_EELOADCNF_Img(ioprp_t *ioprp_img, int have_xloadfile)
385 int romdir_size, extinfo_size, iopbtconf_size, cdvdman_size, cdvdfsv_size;
386 romdir_t *romdir_in;
388 romdir_in = (romdir_t*)ioprp_img->data_in;
389 memset((void *)romdir_in, 0, 7 * sizeof(romdir_t));
391 // Build ROMDIR fs
392 _strcpy(romdir_in->fileName, "RESET");
393 romdir_in->extinfo_size = 8;
394 romdir_in++;
396 _strcpy(romdir_in->fileName, "ROMDIR");
397 romdir_size = 7 * sizeof(romdir_t);
398 romdir_in->fileSize = romdir_size;
399 romdir_in++;
401 _strcpy(romdir_in->fileName, "EXTINFO");
402 extinfo_size = 8 + 8 + 24 + 24;
403 romdir_in->fileSize = extinfo_size;
404 romdir_in++;
406 _strcpy(romdir_in->fileName, "IOPBTCONF");
407 romdir_in->extinfo_size = 8;
409 // Fill EXTINFO
410 u8 *ptr = (u8 *)(ioprp_img->data_in + romdir_size);
411 memcpy(&ptr[0], "\0\0\x04\x01\x07\x02\x02\x20", 8);
412 memcpy(&ptr[8], "\0\0\x04\x01\x07\x02\x02\x20", 8);
413 memcpy(&ptr[8+8], "\0\0\x04\x01\x12\x04\x88\x19\x99\x99\0\x02\0\0\x08\x03""CDVDMAN\0", 24);
414 memcpy(&ptr[8+8+24], "\0\0\x04\x01\x12\x04\x88\x19\x99\x99\0\x02\0\0\x08\x03""CDVDFSV\0", 24);
415 ptr += extinfo_size;
417 // Fill IOPBTCONF
418 char *iopbtconf_str0 = "@800\nSYSMEM\nLOADCORE\nEXCEPMAN\nINTRMANP\nINTRMANI\nSSBUSC\nDMACMAN\nTIMEMANP\nTIMEMANI\n";
419 char *iopbtconf_str1 = "SYSCLIB\nHEAPLIB\nEECONF\nTHREADMAN\nVBLANK\nIOMAN\nMODLOAD\nROMDRV\nSTDIO\nSIFMAN\n";
420 char *iopbtconf_str2 = "IGREETING\nSIFCMD\nREBOOT\nLOADFILE\nCDVDMAN\nCDVDFSV\nSIFINIT\nFILEIO\nSECRMAN\nEESYNC\n";
421 if (have_xloadfile)
422 iopbtconf_str2 = "IGREETING\nSIFCMD\nREBOOT\nXLOADFILE\nCDVDMAN\nCDVDFSV\nSIFINIT\nFILEIO\nSECRMAN\nEESYNC\n";
424 memcpy(&ptr[0], iopbtconf_str0, strlen(iopbtconf_str0));
425 memcpy(&ptr[strlen(iopbtconf_str0)], iopbtconf_str1, strlen(iopbtconf_str1));
426 memcpy(&ptr[strlen(iopbtconf_str0)+strlen(iopbtconf_str1)], iopbtconf_str2, strlen(iopbtconf_str2));
428 // Fill IOPBTCONF filesize
429 iopbtconf_size = strlen(iopbtconf_str0)+strlen(iopbtconf_str1)+strlen(iopbtconf_str2);
430 romdir_in->fileSize = iopbtconf_size;
431 // arrange size to next 16 bytes multiple
432 if (iopbtconf_size % 0x10)
433 iopbtconf_size = (iopbtconf_size + 0x10) & 0xfffffff0;
434 romdir_in++;
435 ptr += iopbtconf_size;
437 // Fill CDVDMAN
438 _strcpy(romdir_in->fileName, "CDVDMAN");
439 romdir_in->extinfo_size = 24;
440 cdvdman_size = size_cdvdman_irx;
441 romdir_in->fileSize = cdvdman_size;
442 // arrange size to next 16 bytes multiple
443 if (cdvdman_size % 0x10)
444 cdvdman_size = (cdvdman_size + 0x10) & 0xfffffff0;
445 DIntr();
446 ee_kmode_enter();
447 memcpy(&ptr[0], cdvdman_irx, size_cdvdman_irx);
448 ee_kmode_exit();
449 EIntr();
450 romdir_in++;
451 ptr += cdvdman_size;
453 // Fill CDVDFSV
454 _strcpy(romdir_in->fileName, "CDVDFSV");
455 romdir_in->extinfo_size = 24;
456 cdvdfsv_size = size_cdvdfsv_irx;
457 romdir_in->fileSize = cdvdfsv_size;
458 // arrange size to next 16 bytes multiple
459 if (cdvdfsv_size % 0x10)
460 cdvdfsv_size = (cdvdfsv_size + 0x10) & 0xfffffff0;
461 DIntr();
462 ee_kmode_enter();
463 memcpy(&ptr[0], cdvdfsv_irx, size_cdvdfsv_irx);
464 ee_kmode_exit();
465 EIntr();
466 romdir_in++;
467 ptr += cdvdfsv_size;
469 // Fill mini image size
470 ioprp_img->data_out = ioprp_img->data_in;
471 ioprp_img->size_out = ioprp_img->size_in = romdir_size + extinfo_size + iopbtconf_size + cdvdman_size + cdvdfsv_size;
473 return 0;
476 /*----------------------------------------------------------------------------------------*/
477 /* XLoadfileCheck */
478 /*----------------------------------------------------------------------------------------*/
479 inline int XLoadfileCheck(void)
481 register int fd;
483 fd = open("rom0:XLOADFILE", O_RDONLY);
484 if (fd >= 0) {
485 close(fd);
486 return 1;
489 return 0;
492 /*----------------------------------------------------------------------------------------*/
493 /* NOP delay. */
494 /*----------------------------------------------------------------------------------------*/
495 inline void delay(int count)
497 int i, ret;
499 for (i = 0; i < count; i++) {
500 ret = 0x01000000;
501 while(ret--) asm("nop\nnop\nnop\nnop");
505 /*----------------------------------------------------------------------------------------*/
506 /* Apply SBV patchs. */
507 /*----------------------------------------------------------------------------------------*/
508 inline void Sbv_Patch(void)
510 sbv_patch_enable_lmb();
511 sbv_patch_disable_prefix_check();