PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
igreeting.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include "irx_imports.h"
12
13#include <iop_mmio_hwport.h>
14#include <tamtypes.h>
15
17{
18 const void *ImageStart;
19 const void *RomdirStart;
20 const void *RomdirEnd;
21};
22
23struct RomDirEntry
24{
25 char name[10];
26 u16 ExtInfoEntrySize;
27 unsigned int size;
28};
29
30struct RomdirFileStat
31{
32 const struct RomDirEntry *romdirent;
33 const void *data;
34 const struct ExtInfoFieldEntry *extinfo;
35};
36
38{
39 // cppcheck-suppress unusedStructMember
40 u16 value;
41 u8 ExtLength;
42 u8 type;
43 u8 payload[];
44};
45
46#ifdef IGREETING_DTL_T
47struct rominfo_item
48{
49 // cppcheck-suppress unusedStructMember
50 const char *m_device_name;
51 void *m_delay_register;
52 int m_delay_register_value;
53 void *m_base_address;
54 int m_chunk_size;
55 int m_config_offset_1;
56 int m_config_offset_2;
57 int m_flash_size;
58 int m_manufacturer;
59 int m_device_id;
60 int m_write_width;
61 int m_address_register;
62 // cppcheck-suppress unusedStructMember
63 int m_flash_offset;
64 int m_flash_blocksize;
65};
66
67struct romflash_sigcheck_res
68{
69 void *m_config_addr_1;
70 void *m_config_addr_2;
71 void *m_base;
72 void *m_base_end;
73 int m_manufacturer_res;
74 int m_device_id_res;
75};
76#endif
77
78#define _mfc0(reg) \
79 ({ \
80 u32 val; \
81 __asm__ volatile("mfc0 %0, " #reg : "=r"(val)); \
82 val; \
83 })
84
85#define mfc0(reg) _mfc0(reg)
86
87#ifdef IGREETING_DTL_T
88static void do_get_dip_switch_values_chr(char *str, int val, int count);
89#endif
90static struct RomImgData *GetIOPRPStat(const u32 *start_addr, const u32 *end_addr, struct RomImgData *rid);
91static struct RomdirFileStat *
92GetFileStatFromImage(const struct RomImgData *rid, const char *filename, struct RomdirFileStat *rdfs);
93static const struct ExtInfoFieldEntry *
94do_find_extinfo_entry(const struct RomdirFileStat *rdfs, unsigned int extinfo_type);
95#ifdef IGREETING_DTL_T
96static const struct rominfo_item *flash_probe(const struct rominfo_item *rii);
97#endif
98
99#ifdef IGREETING_DTL_T
100static const char *boardinfo_uma_dsw202 =
101 "\r\nUMA board DSW202\r\n --- PS kernel --\r\n Sw8 bit0 0^ use H1500, 1_ no use H1500 (CD-BOOT "
102 "only)\r\n Sw7 bit1 0^ display color bar 1_ no color bar\r\n Sw6 bit2 0^ IOP Kernel 1_ PS Kernel "
103 "(when PS mode)\r\n Sw5 bit3 0^ check cd-rom 1_ ignore cdrom always\r\n Sw4 bit4 0^ Dram 16M "
104 "1_ Dram 2M\r\n Sw3 bit5 0^ disable 1_ enable EE ssbus access\r\n --- IOP kernel --\r\n Sw5 bit3 "
105 "0^ Extr Wide DMA 1_ Extr Wide DMA disable\r\n Sw4 bit4 0^ Dram 16M 1_ Dram 2M\r\n Sw3 bit5 "
106 "0^ disable 1_ enable EE ssbus access\r\n --- EE --\r\n Sw2 bit6 0^ -- 1_ --\r\n "
107 "Sw1 bit7 0^ EE normal boot 1_ EE/GS self test\r\n\r\n";
108static const char *boardinfo_common =
109 " --- PS kernel --\r\n D0 0^ use H1500, 1_ no use H1500 (CD-BOOT only)\r\n D1 0^ display color bar "
110 "1_ no color bar\r\n D2 0^ IOP Kernel 1_ PS Kernel (when PS mode)\r\n D3 0^ check cd-rom 1_ "
111 "ignore cdrom always\r\n D4 0^ Dram 8M 1_ Dram 2M\r\n D5 0^ disable 1_ enable EE ssbus "
112 "access\r\n --- IOP kernel --\r\n D0 0^ NTSC mode 1_ PAL mode\r\n D3 0^ Extr Wide DMA 1_ Extr "
113 "Wide DMA disable\r\n D4 0^ Dram 8M 1_ Dram 2M\r\n D5 0^ disable 1_ enable EE ssbus "
114 "access\r\n --- EE --\r\n D6 0^ -- 1_ --\r\n D7 0^ EE normal boot 1_ EE/GS self "
115 "test\r\n\r\n";
116static const char *boardinfo_unknown = "\r\nUnknown board\r\n";
117#endif
118static const char *romgen_eq_str = " ROMGEN=";
119#ifdef IGREETING_DTL_T
120static const char *cpuid_eq_str = " CPUID=";
121#else
122static const char *cpuid_eq_str = ", IOP info (CPUID=";
123#endif
124static const char *cach_config_eq_str = ", CACH_CONFIG=";
125#ifdef IGREETING_DTL_T
126static struct rominfo_item default_list[] = {
127 {"Gmain1-3, flash mode, Fujitsu 512K flash",
128 (void *)0xBF801010,
129 1256783,
130 (void *)0xBFC00000,
131 1,
132 1365,
133 682,
134 524288,
135 4,
136 164,
137 8,
138 0,
139 0,
140 0},
141 {"Gmain4..., flash mode, Fujitsu 2M flash",
142 (void *)0xBF801010,
143 1387855,
144 (void *)0xBFC00000,
145 2,
146 2730,
147 1365,
148 2097152,
149 4,
150 196,
151 8,
152 0,
153 0,
154 0},
155 {"Gmain4..., flash mode, AMD 2M flash",
156 (void *)0xBF801010,
157 1387855,
158 (void *)0xBFC00000,
159 2,
160 2730,
161 1365,
162 2097152,
163 1,
164 196,
165 8,
166 0,
167 0,
168 0},
169 {"shimakawa sp, flash mode, Fujitsu 4M flash",
170 (void *)0xBF801010,
171 1453391,
172 (void *)0xBFC00000,
173 2,
174 2730,
175 1365,
176 4194304,
177 4,
178 95,
179 8,
180 0,
181 0,
182 0},
183 {NULL, NULL, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
184#endif
185
186int _start(int ac, char **av)
187{
188 int *boot_mode_4;
189 int cop0_processor_mode;
190 const char *iop_or_ps_mode_str;
191 const struct ExtInfoFieldEntry *extinfo_entry;
192 const char *extinfo_id_str;
193 const char *comma_index;
194 struct RomImgData rid;
195 struct RomdirFileStat rdfs;
196#ifdef IGREETING_DTL_T
197 int *boot_mode_2;
198 int *boot_mode_3;
199 const char *board_type_str;
200 const char *board_info_str;
201 int boardtype_int;
202 int board_has_wide_dma;
203 const char *rom_or_flashrom_boot_str;
204 u8 tmp_dma_wide_ch;
205 char switch_values_str[16];
206#endif
207 USE_IOP_MMIO_HWPORT();
208
209 (void)ac;
210 (void)av;
211
212 boot_mode_4 = QueryBootMode(4);
213#ifndef IGREETING_DTL_T
214 printf("\nPlayStation 2 ======== ");
215#endif
216 if ( boot_mode_4 )
217 {
218 switch ( *(u16 *)boot_mode_4 )
219 {
220#ifndef IGREETING_DTL_T
221 case 0:
222 printf("Hard reset boot");
223 break;
224#endif
225 case 1:
226 printf("Soft reboot");
227 break;
228 case 2:
229 printf("Update rebooting..");
230#ifdef IGREETING_DTL_T
231 boot_mode_3 = QueryBootMode(3);
232 if ( boot_mode_3 )
233 printf(" reset parameter for IOP=%08x_%08x", boot_mode_3[2], boot_mode_3[1]);
234#endif
235 break;
236 case 3:
237 printf("Update reboot complete");
238 break;
239 default:
240 break;
241 }
242 printf("\n");
243 }
244 if ( !boot_mode_4 || !*(u16 *)boot_mode_4 )
245 {
246 cop0_processor_mode = mfc0($15);
247#ifdef IGREETING_DTL_T
248 board_type_str = "";
249 boardtype_int = iop_mmio_hwport->exp2_r2[4612];
250 board_info_str = boardinfo_common;
251 board_has_wide_dma = 1;
252 switch ( boardtype_int & 0xF8 )
253 {
254 case 16:
255 board_type_str = "\r\nGmain-1.0 board DSW602\r\n";
256 break;
257 case 32:
258 board_type_str = "\r\nGmain-2.0 board DSW602\r\n";
259 break;
260 case 48:
261 board_type_str = "\r\nGmain-3.0 board DSW602\r\n";
262 break;
263 case 64:
264 board_type_str = "\r\nB3system-1.0 front dipsw\r\n";
265 board_has_wide_dma = 0;
266 break;
267 case 80:
268 board_type_str = "\r\nGmain-4.0 board DSW602\r\n";
269 break;
270 case 88:
271 board_type_str = "\r\nGmain-5.0 board DSW602\r\n";
272 break;
273 case 96:
274 board_type_str = "\r\nMPU-4.0 board DSW602\r\n";
275 board_has_wide_dma = 0;
276 break;
277 case 112:
278 board_type_str = "\r\nGmain-10.0/11.0 board DSW602\r\n";
279 break;
280 case 120:
281 board_type_str = "\r\nGmain-12.0 board DSW602\r\n";
282 break;
283 case 124:
284 board_type_str = "\r\nGmain-13.0 board DSW602\r\n";
285 break;
286 default:
287 board_info_str = boardinfo_unknown;
288 board_has_wide_dma = 0;
289 break;
290 }
291 if ( boardtype_int < 2 )
292 {
293 board_info_str = boardinfo_uma_dsw202;
294 board_has_wide_dma = (boardtype_int & 0xFE) == 0;
295 }
296 write(1, (char *)board_type_str, strlen(board_type_str));
297 // Unofficial: make board info string not go through a structure
298 write(1, (char *)board_info_str, strlen(board_info_str));
299 write(1, (char *)cpuid_eq_str, strlen(cpuid_eq_str));
300 printf("%x", cop0_processor_mode);
301 write(1, (char *)romgen_eq_str, strlen(romgen_eq_str));
302 printf("%04x-%04x", *(vu16 *)(0xBFC00102), *(vu16 *)(0xBFC00100));
303#else
304 write(1, (char *)romgen_eq_str, strlen(romgen_eq_str));
305 printf("%04x-%04x", *(vu16 *)(0xBFC00102), *(vu16 *)(0xBFC00100));
306 write(1, (char *)cpuid_eq_str, strlen(cpuid_eq_str));
307 printf("%x", cop0_processor_mode);
308#endif
309 write(1, (char *)cach_config_eq_str, strlen(cach_config_eq_str));
310 printf("%lx, %ldMB", (unsigned long)*(vu32 *)(0xFFFE0130), (long)((u32)QueryMemSize() + 256) >> 20);
311 if ( cop0_processor_mode >= 16 )
312 {
313#ifdef IGREETING_DTL_T
314 iop_or_ps_mode_str = ((iop_mmio_hwport->iop_sbus_ctrl[0] & 8) != 0) ? ", PS mode" : ", IOP mode";
315#else
316 iop_or_ps_mode_str = ((iop_mmio_hwport->iop_sbus_ctrl[0] & 8) != 0) ? ", PS mode)\r\n" : ", IOP mode)\r\n";
317#endif
318 write(1, (char *)iop_or_ps_mode_str, strlen(iop_or_ps_mode_str));
319 }
320#ifdef IGREETING_DTL_T
322 rom_or_flashrom_boot_str = (flash_probe(default_list)) ? ", FlashROM boot\r\n" : ", ROM boot\r\n";
324 write(1, (char *)rom_or_flashrom_boot_str, strlen(rom_or_flashrom_boot_str));
325#endif
326 // Unofficial: pad filename
327 if (
328 GetIOPRPStat((u32 *)0xBFC00000, (u32 *)0xBFC10000, &rid)
329 && GetFileStatFromImage(&rid, "ROMDIR\x00\x00\x00\x00\x00", &rdfs) )
330 {
331 extinfo_entry = do_find_extinfo_entry(&rdfs, 3);
332 if ( extinfo_entry )
333 {
334 extinfo_id_str = (const char *)extinfo_entry->payload;
335 comma_index = rindex(extinfo_id_str, ',');
336 write(1, " <", 2);
337 // Unofficial: if comma not found, just write the whole thing
338 write(1, (char *)extinfo_id_str, comma_index ? (comma_index - extinfo_id_str) : (int)strlen(extinfo_id_str));
339 printf(":%ld>\n", (long)(u16)(uiptr)extinfo_id_str);
340 }
341 }
342#ifdef IGREETING_DTL_T
343 write(1, " SW=b7:", 7);
344 do_get_dip_switch_values_chr(switch_values_str, (u8)iop_mmio_hwport->exp2_r2[4352], 8);
345 write(1, switch_values_str, 8);
346 write(1, ":b0", 3);
347 boot_mode_2 = QueryBootMode(2);
348 if ( boot_mode_2 )
349 {
350 printf(", RESET parameter EE=%08x_%08x", boot_mode_2[2], boot_mode_2[1]);
351 boot_mode_3 = QueryBootMode(3);
352 if ( boot_mode_3 )
353 printf(", IOP=%08x_%08x", boot_mode_3[2], boot_mode_3[1]);
354 }
355 write(1, "\r\n", 2);
356 if ( board_has_wide_dma )
357 {
358 tmp_dma_wide_ch = iop_mmio_hwport->exp2_r2[4608];
359 iop_mmio_hwport->exp2_r2[4608] = -1;
360 printf(" DMA_WIDE_CH=%x\n", (u8)iop_mmio_hwport->exp2_r2[4608]);
361 iop_mmio_hwport->exp2_r2[4608] = tmp_dma_wide_ch;
362 }
363 if ( (iop_mmio_hwport->exp2_r2[4352] & (1 << 5)) != 0 )
364 {
365 iop_mmio_hwport->iop_sbus_ctrl[0] |= 1;
366 }
367#endif
368 }
369 return 1;
370}
371
372#ifdef IGREETING_DTL_T
373static void do_get_dip_switch_values_chr(char *str, int val, int count)
374{
375 int i;
376
377 for ( i = 0; i < count; i += 1 )
378 {
379 str[i] = (((val >> ((count - i) - 1)) & 1) != 0) ? '_' : '^';
380 }
381}
382#endif
383
384static struct RomImgData *GetIOPRPStat(const u32 *start_addr, const u32 *end_addr, struct RomImgData *rid)
385{
386 unsigned int cur_offset;
387
388 for ( cur_offset = 0; &start_addr[cur_offset >> 2] < end_addr; cur_offset += 16 )
389 {
390 if (
391 start_addr[cur_offset >> 2] == 0x45534552 && start_addr[(cur_offset >> 2) + 1] == 0x54
392 && !(start_addr[(cur_offset >> 2) + 2] & 0xFFFF)
393 && ((start_addr[(cur_offset >> 2) + 3] + 15) & 0xFFFFFFF0) == cur_offset )
394 {
395 rid->ImageStart = start_addr;
396 rid->RomdirStart = &start_addr[cur_offset >> 2];
397 rid->RomdirEnd = (char *)&start_addr[cur_offset >> 2] + *(&start_addr[cur_offset >> 2] + 7);
398 return rid;
399 }
400 }
401 rid->ImageStart = 0;
402 return 0;
403}
404
405static struct RomdirFileStat *
406GetFileStatFromImage(const struct RomImgData *rid, const char *filename, struct RomdirFileStat *rdfs)
407{
408 int cur_addr_aligned;
409 int total_extinfo_size;
410 const struct RomDirEntry *RomdirStart;
411 int i;
412 char cur_romdir_name[12];
413
414 cur_addr_aligned = 0;
415 total_extinfo_size = 0;
416 memset(cur_romdir_name, 0, sizeof(cur_romdir_name));
417 for ( i = 0; i < 12 && filename[i] >= ' '; i += 1 )
418 {
419 cur_romdir_name[i] = filename[i];
420 }
421 for ( RomdirStart = (const struct RomDirEntry *)rid->RomdirStart;
422 (u32 *)(RomdirStart->name) != (u32 *)(cur_romdir_name)
423 && (u32 *)(RomdirStart->name + 4) != (u32 *)(cur_romdir_name + 4)
424 && (u16 *)(RomdirStart->name + 8) != (u16 *)(cur_romdir_name + 8);
425 RomdirStart += 1 )
426 {
427 cur_addr_aligned += ((RomdirStart->size) + 15) & 0xFFFFFFF0;
428 total_extinfo_size += (s16)RomdirStart->ExtInfoEntrySize;
429 }
430 if ( !*(u32 *)RomdirStart->name )
431 return 0;
432 rdfs->romdirent = RomdirStart;
433 rdfs->extinfo = RomdirStart->ExtInfoEntrySize ?
434 (const struct ExtInfoFieldEntry *)((const char *)rid->RomdirEnd + total_extinfo_size) :
435 0;
436 rdfs->data = &((char *)rid->ImageStart)[cur_addr_aligned];
437 return rdfs;
438}
439
440const struct ExtInfoFieldEntry *do_find_extinfo_entry(const struct RomdirFileStat *rdfs, unsigned int extinfo_type)
441{
442 const struct ExtInfoFieldEntry *extinfo;
443 const struct ExtInfoFieldEntry *extinfo_end;
444
445 extinfo = rdfs->extinfo;
446 extinfo_end = &extinfo[(unsigned int)((s16)rdfs->romdirent->ExtInfoEntrySize) >> 2];
447 for ( ; extinfo < extinfo_end;
448 extinfo = (const struct ExtInfoFieldEntry *)((char *)extinfo + ((extinfo->ExtLength) & 0xFC) + 4) )
449 {
450 if ( extinfo->type == extinfo_type )
451 {
452 return extinfo;
453 }
454 }
455 return 0;
456}
457
458#ifdef IGREETING_DTL_T
459static void flash_reset(const struct rominfo_item *rii)
460{
462 switch ( rii->m_write_width )
463 {
464 case 8:
465 *((vu8 *)rii->m_base_address + rii->m_config_offset_1) = 0xF0;
466 break;
467 case 16:
468 *((vu16 *)rii->m_base_address + rii->m_config_offset_1) = 0xF0;
469 break;
470 default:
471 break;
472 }
474}
475
476static int checksig(const struct rominfo_item *rii, struct romflash_sigcheck_res *rsr, int offset)
477{
478 u8 *effective_address_1;
479 u16 *effective_address_2;
480 int tmp_manufacturer;
481 USE_IOP_MMIO_HWPORT();
482
483 // Unofficial: don't write to m_manufacturer
484 tmp_manufacturer = rii->m_manufacturer;
485 switch ( rii->m_write_width )
486 {
487 case 8:
488 effective_address_1 = (u8 *)((u8 *)rii->m_base_address + offset);
489 rsr->m_config_addr_1 = &effective_address_1[rii->m_config_offset_1];
490 rsr->m_config_addr_2 = &effective_address_1[rii->m_config_offset_2];
491 rsr->m_base = effective_address_1;
492 rsr->m_base_end = &effective_address_1[rii->m_chunk_size];
493 *(vu8 *)rsr->m_config_addr_1 = 0xAA;
494 *(vu8 *)rsr->m_config_addr_2 = 0x55;
495 *(vu8 *)rsr->m_config_addr_1 = 0x90;
496 *(vu32 *)&iop_mmio_hwport->exp2_r2[4352] = 0xFFFFFF6F;
497 rsr->m_manufacturer_res = *((vu8 *)rsr->m_base);
498 rsr->m_device_id_res = *((vu8 *)rsr->m_base_end);
499 break;
500 case 16:
501 effective_address_2 = (u16 *)((u8 *)rii->m_base_address + offset);
502 rsr->m_config_addr_1 = &effective_address_2[rii->m_config_offset_1];
503 rsr->m_config_addr_2 = &effective_address_2[rii->m_config_offset_2];
504 rsr->m_base = effective_address_2;
505 rsr->m_base_end = &effective_address_2[rii->m_chunk_size];
506 *(vu16 *)rsr->m_config_addr_1 = 0xAA;
507 *(vu16 *)rsr->m_config_addr_2 = 0x55;
508 *(vu16 *)rsr->m_config_addr_1 = 0x90;
509 *(vu32 *)&iop_mmio_hwport->exp2_r2[4352] = 0xFFFFFF6F;
510 rsr->m_manufacturer_res = *((vu16 *)rsr->m_base);
511 rsr->m_device_id_res = *((vu16 *)rsr->m_base_end);
512 break;
513 default:
514 break;
515 }
516 flash_reset(rii);
517 if ( !tmp_manufacturer && (rsr->m_manufacturer_res == 1 || rsr->m_manufacturer_res == 4) )
518 tmp_manufacturer = rsr->m_manufacturer_res;
519 return (rsr->m_manufacturer_res == tmp_manufacturer) && (rsr->m_device_id_res == rii->m_device_id);
520}
521
522static int flash_checksig(const struct rominfo_item *rii)
523{
524 int old_address_reg;
525 int old_delay_reg;
526 int condtmp1;
527 int flash_chunks;
528 int cur_flash_chunk;
529 struct romflash_sigcheck_res rsr;
530 USE_IOP_MMIO_HWPORT();
531
532 memset(&rsr, 0, sizeof(rsr));
533 old_address_reg = 0;
534 old_delay_reg = 0;
535 if ( rii->m_address_register )
536 {
537 old_address_reg = iop_mmio_hwport->ssbus2.ind_1_address;
538 iop_mmio_hwport->ssbus2.ind_1_address = rii->m_address_register;
539 }
540 if ( rii->m_delay_register )
541 {
542 old_delay_reg = *((vu32 *)rii->m_delay_register);
543 *((vu32 *)rii->m_delay_register) = rii->m_delay_register_value;
544 *(vu32 *)&iop_mmio_hwport->exp2_r2[4352] = *(vu32 *)rii->m_delay_register;
545 }
546 flash_chunks = rii->m_flash_size / rii->m_flash_blocksize;
547 for ( cur_flash_chunk = 0;
548 (condtmp1 = checksig(rii, &rsr, flash_chunks * cur_flash_chunk)) && (cur_flash_chunk < rii->m_flash_blocksize);
549 cur_flash_chunk += 1 )
550 {
551 }
552 if ( !condtmp1 )
553 {
554 if ( rii->m_delay_register )
555 {
556 *((vu32 *)rii->m_delay_register) = old_delay_reg;
557 *(vu32 *)&iop_mmio_hwport->exp2_r2[4352] = *(vu32 *)rii->m_delay_register;
558 }
559 if ( rii->m_address_register )
560 iop_mmio_hwport->ssbus2.ind_1_address = old_address_reg;
561 }
562 return condtmp1;
563}
564
565static const struct rominfo_item *flash_probe(const struct rominfo_item *rii)
566{
568 for ( ; rii->m_write_width; rii += 1 )
569 {
570 if ( flash_checksig(rii) )
571 {
573 return rii;
574 }
575 }
577 return 0;
578}
579#endif
int CpuEnableIntr()
Definition intrman.c:250
int CpuDisableIntr()
Definition intrman.c:238
Definition romdrv.h:55
Definition romdrv.h:40
u32 count
start sector of fragmented bd/file