14 #define MODNAME "UpDate DownLoader"
16 IRX_ID(MODNAME, 1, 1);
19 int CpuExecuteKmode(
void *
function, ...);
24 "\t" ".set noreorder" "\n"
26 "\t" ".globl CpuExecuteKmode" "\n"
27 "\t" ".ent CpuExecuteKmode" "\n"
28 "\t" "CpuExecuteKmode:" "\n"
29 "\t" "\t" "li $v0, 0x0C" "\n"
30 "\t" "\t" "syscall" "\n"
31 "\t" "\t" "jr $ra" "\n"
33 "\t" ".end CpuExecuteKmode" "\n"
40 #define DEBUG_PRINTF(args...) printf(args)
42 #define DEBUG_PRINTF(args...)
45 #define FULL_UDNL 1 // Comment out to build a UDNL module that updates the IOP with only its payload.
46 #define MAX_MODULES 256
48 #define alloca(size) __builtin_alloca(size) // The homebrew PS2SDK lacks alloca.h.
51 static void CopySection(
const void *module,
void *buffer,
unsigned int FileSize);
52 static void *AllocMemory(
int nbytes);
124 unsigned int MemSize;
125 unsigned int BootMode;
129 unsigned int IOPRPBufferSize;
130 unsigned int NumModules;
131 const void **ModData;
136 static int var_00001e20 = 0;
138 static int var_00001850 = 0;
142 #ifdef USE_EMBEDDED_IOPRP
143 extern unsigned char IOPRP_img[];
144 extern unsigned int size_IOPRP_img;
149 const void *ImageStart;
150 const void *RomdirStart;
151 const void *RomdirEnd;
156 const char *filename;
165 unsigned short int ExtInfoEntrySize;
170 static void *GetIOPRPStat(
const void *start,
const void *end,
struct RomImgData *ImageStat)
172 const unsigned int *ptr, *ptr2;
177 while ((
unsigned int)ptr < (
unsigned int)end) {
180 if (ptr[0] == 0x45534552 && ptr2[-6] == 0x54 && (*(
unsigned short int *)&ptr2[-5] == 0) && (((ptr2[-4] + 0xF) & 0xFFFFFFF0) == offset)) {
181 ImageStat->ImageStart = start;
182 ImageStat->RomdirStart = ptr;
183 ImageStat->RomdirEnd = (
void *)((
unsigned int)ptr + *ptr2);
191 ImageStat->ImageStart = 0;
200 unsigned int padding;
206 unsigned int i, offset, ExtInfoOffset;
207 unsigned char filename_temp[12];
215 ((
unsigned int *)filename_temp)[0] = 0;
216 ((
unsigned int *)filename_temp)[1] = 0;
217 ((
unsigned int *)filename_temp)[2] = 0;
218 for (i = 0; *filename >= 0x21 && i <
sizeof(filename_temp); i++) {
219 filename_temp[i] = *filename;
223 if (ImageStat->RomdirStart != NULL) {
224 RomdirEntry = ImageStat->RomdirStart;
227 if (((
unsigned int *)filename_temp)[0] == ((
unsigned int *)RomdirEntry->name)[0] && ((
unsigned int *)filename_temp)[1] == ((
unsigned int *)RomdirEntry->name)[1] && (*(
unsigned short int *)&((
unsigned int *)filename_temp)[2] == *(
unsigned short int *)&((
unsigned int *)RomdirEntry->name)[2])) {
229 stat->romdirent = RomdirEntry;
230 stat->data = (
void *)((u8 *)(ImageStat->ImageStart) + offset);
231 stat->extinfo = NULL;
233 if (RomdirEntry->ExtInfoEntrySize > 0) {
234 stat->extinfo = (
void *)((
unsigned int)ImageStat->RomdirEnd + ExtInfoOffset);
246 offset += (RomdirEntry->size + 0xF) & 0xFFFFFFF0;
247 ExtInfoOffset += RomdirEntry->ExtInfoEntrySize;
249 }
while (((
unsigned int *)RomdirEntry->name)[0] != 0x00000000);
270 static void ScanImagesForFile(
const struct ImageData *ImageDataBuffer,
unsigned int NumFiles,
struct RomdirFileStat *stat,
const char *filename)
291 if (GetFileStatFromImage(&
ImageData->stat, filename, stat) != 0) {
292 DEBUG_PRINTF(
"File: %s, image: %s\n", filename,
ImageData->filename);
303 printf(
"kupdate: panic ! \'%s\' not found\n", filename);
305 printf(
"panic ! \'%s\' not found\n", filename);
311 static void TerminateResidentLibraries(
const char *message,
unsigned int options,
int mode)
320 if ((LoadcoreData = GetLoadcoreInternalData()) != NULL) {
321 ModuleData = LoadcoreData->let_next;
322 while (ModuleData != NULL) {
323 NextModule = ModuleData->prev;
326 if (!(ModuleData->flags & 6)) {
327 ModuleData = NextModule;
330 }
else if ((ModuleData->flags & 6) == 2) {
331 ModuleData = NextModule;
335 ExportTable = ModuleData->exports;
336 if (ExportTable[1] != NULL && ExportTable[2] != NULL) {
337 int (*pexit)(
int arg1);
339 pexit = ExportTable[2];
343 ModuleData = NextModule;
350 volatile unsigned int *address, *delay;
355 (
volatile unsigned int *)0xbf801000,
356 (
volatile unsigned int *)0xbf801008},
357 {(
volatile unsigned int *)0xbf801400,
358 (
volatile unsigned int *)0xbf80100C},
359 {(
volatile unsigned int *)0xbf801404,
360 (
volatile unsigned int *)0xbf801014},
361 {(
volatile unsigned int *)0xbf801408,
362 (
volatile unsigned int *)0xbf801018},
363 {(
volatile unsigned int *)0xbf80140C,
364 (
volatile unsigned int *)0xbf801414},
365 {(
volatile unsigned int *)0xbf801410,
366 (
volatile unsigned int *)0xbf80141C},
371 static volatile unsigned int *func_00000f80(
volatile unsigned int *address)
376 while (pSSBUS_regs->address != NULL) {
377 if (pSSBUS_regs->address == address)
382 return pSSBUS_regs->delay;
386 void func_00001b38(
unsigned int arg1);
389 "\t" ".set push" "\n"
390 "\t" ".set noat" "\n"
391 "\t" ".set noreorder" "\n"
393 "\t" ".globl func_00001b38" "\n"
394 "\t" ".ent func_00001b38" "\n"
395 "\t" "func_00001b38:" "\n"
396 "\t" "\t" "mfc0 $t0, $12" "\n"
398 "\t" "\t" "la $t4, func_00001b38_main" "\n"
399 "\t" "\t" "lui $at, 0xA000" "\n"
400 "\t" "\t" "or $t4, $t4, $at" "\n"
401 "\t" "\t" "jr $t4" "\n"
402 "\t" "\t" "mtc0 $zero, $12" "\n"
403 "\t" "func_00001b38_main:" "\n"
405 "\t" "\t" "lui $at, 0xFFFE" "\n"
406 "\t" "\t" "sw $a0, 0x0130($at)" "\n"
407 "\t" "\t" "lui $at, 0xFFFE" "\n"
408 "\t" "\t" "lw $zero, 0x0130($at)" "\n"
410 "\t" "\t" "mtc0 $t0, $12" "\n"
412 "\t" "\t" "jr $ra" "\n"
414 "\t" ".end func_00001b38" "\n"
419 static void TerminateResidentEntriesDI(
unsigned int options)
422 volatile unsigned int **pReg;
424 TerminateResidentLibraries(
" kupdate:di: Terminate resident Libraries\n", options, 0);
428 if (!(options & 1)) {
429 pReg = (prid < 0x10 || ((*(
volatile unsigned int *)0xbf801450) & 8)) ? *(
volatile unsigned int ***)0xbfc02008 : *(
volatile unsigned int ***)0xbfc0200C;
431 while (pReg[0] != 0) {
432 if (func_00000f80(pReg[0]) != 0)
433 pReg[0] = (
void *)0xFF;
438 if (!(options & 2)) {
439 func_00001b38((prid < 0x10 || ((*(
volatile unsigned int *)0xbf801450) & 8)) ? *(
volatile unsigned int *)0xbfc02010 : *(
volatile unsigned int *)0xbfc02014);
446 unsigned int ModuleType;
450 unsigned int text_size;
451 unsigned int data_size;
452 unsigned int bss_size;
453 unsigned int MemSize;
455 unsigned int unknown_24;
459 void func_00001930(
void);
461 void func_00001440(
void);
466 "\t" ".set push" "\n"
467 "\t" ".set noat" "\n"
468 "\t" ".set noreorder" "\n"
471 "\t" ".globl func_00001930" "\n"
472 "\t" ".ent func_00001930" "\n"
473 "\t" "func_00001930:" "\n"
475 "\t" ".globl func_00001440" "\n"
476 "\t" ".ent func_00001440" "\n"
477 "\t" "func_00001440:" "\n"
479 "\t" "\t" "mfc0 $t0, $12" "\n"
482 "\t" "\t" "la $t4, func_00001930_main" "\n"
484 "\t" "\t" "la $t4, func_00001440_main" "\n"
486 "\t" "\t" "lui $at, 0xA000" "\n"
487 "\t" "\t" "or $t4, $t4, $at" "\n"
488 "\t" "\t" "jr $t4" "\n"
490 "\t" "func_00001930_main:" "\n"
492 "\t" "func_00001440_main:" "\n"
494 "\t" "\t" "mtc0 $zero, $12" "\n"
497 "\t" "\t" "lui $t6, 0xbf80" "\n"
498 "\t" "\t" "lw $t6, 0x1450($t6)" "\n"
500 "\t" "\t" "addiu $t7, $zero, 0xfffe" "\n"
501 "\t" "\t" "and $t1, $t6, $t7" "\n"
502 "\t" "\t" "lui $at, 0xbf80" "\n"
503 "\t" "\t" "sw $t1, 0x1450($at)" "\n"
504 "\t" "\t" "lui $at, 0xbf80" "\n"
505 "\t" "\t" "lw $zero, 0x1450($at)" "\n"
506 "\t" "\t" "lui $t7, 0xbf80" "\n"
507 "\t" "\t" "lw $t7, 0x1578($t7)" "\n"
508 "\t" "\t" "lui $at, 0xbf80" "\n"
509 "\t" "\t" "sw $zero, 0x1578($at)" "\n"
510 "\t" "\t" "lui $at, 0xbf80" "\n"
511 "\t" "\t" "lw $zero, 0x1578($at)" "\n"
512 "\t" "\t" "lui $t5, 0xfffe" "\n"
513 "\t" "\t" "lw $t5, 0x0130($t5)" "\n"
514 "\t" "\t" "addiu $t1, $zero, 0x0c04" "\n"
515 "\t" "\t" "lui $at, 0xfffe" "\n"
516 "\t" "\t" "sw $t1, 0x0130($at)" "\n"
517 "\t" "\t" "lui $t4, 0x0001" "\n"
518 "\t" "\t" "mtc0 $t4, $12" "\n"
521 "\t" "\t" "addiu $t2, $zero, 0x0000" "\n"
522 "\t" "\t" "addiu $t3, $zero, 0x0f80" "\n"
524 "\t" "func_00001930_loop:" "\n"
526 "\t" "func_00001440_loop:" "\n"
528 "\t" "\t" "sw $zero, 0x0000($t2)" "\n"
529 "\t" "\t" "sw $zero, 0x0010($t2)" "\n"
530 "\t" "\t" "sw $zero, 0x0020($t2)" "\n"
531 "\t" "\t" "sw $zero, 0x0030($t2)" "\n"
532 "\t" "\t" "sw $zero, 0x0040($t2)" "\n"
533 "\t" "\t" "sw $zero, 0x0050($t2)" "\n"
534 "\t" "\t" "sw $zero, 0x0060($t2)" "\n"
535 "\t" "\t" "sw $zero, 0x0070($t2)" "\n"
537 "\t" "\t" "bne $t2, $t3, func_00001930_loop" "\n"
539 "\t" "\t" "bne $t2, $t3, func_00001440_loop" "\n"
541 "\t" "\t" "addi $t2, $t2, 0x0080" "\n"
542 "\t" "\t" "mtc0 $zero, $12" "\n"
544 "\t" "\t" "lui $at, 0xfffe" "\n"
545 "\t" "\t" "sw $t5, 0x0130($at)" "\n"
546 "\t" "\t" "lui $at, 0xfffe" "\n"
547 "\t" "\t" "lw $zero, 0x0130($at)" "\n"
549 "\t" "\t" "lui $at, 0xbf80" "\n"
550 "\t" "\t" "sw $t7, 0x1578($at)" "\n"
551 "\t" "\t" "lui $at, 0xbf80" "\n"
552 "\t" "\t" "lw $zero, 0x1578($at)" "\n"
553 "\t" "\t" "lui $at, 0xbf80" "\n"
554 "\t" "\t" "sw $t6, 0x1450($at)" "\n"
555 "\t" "\t" "lui $at, 0xbf80" "\n"
556 "\t" "\t" "lw $zero, 0x1450($at)" "\n"
557 "\t" "\t" "mtc0 $t0, $12" "\n"
559 "\t" "\t" "jr $ra" "\n"
562 "\t" ".end func_00001930" "\n"
564 "\t" ".end func_00001440" "\n"
569 enum IOP_MODULE_TYPES {
570 IOP_MOD_TYPE_COFF = 1,
579 unsigned int Ident_10;
580 const struct scnhdr *COFF_ScnHdr;
592 memcpy(&Ident_10, &((
struct coff_filehdr *)module)->f_opthdr, 4);
595 if (((
struct coff_filehdr *)module)->f_magic == MIPSELMAGIC && COFF_AoutHdr->magic == OMAGIC && ((
struct coff_filehdr *)module)->f_nscns < 0x20 && ((Ident_10 & 0x0002FFFF) == 0x20038) && COFF_ScnHdr->s_paddr == COFF_AoutHdr->text_start) {
596 if (COFF_AoutHdr->vstamp != 0x7001) {
599 ModuleInfo->EntryPoint = (
void *)COFF_AoutHdr->entry;
600 ModuleInfo->gp = (
void *)COFF_AoutHdr->gp_value;
601 ModuleInfo->text_start = (
void *)COFF_AoutHdr->text_start;
605 ModuleInfo->MemSize = COFF_AoutHdr->bss_start + COFF_AoutHdr->bsize - COFF_AoutHdr->text_start;
615 ELF_phdr = (
elf_pheader_t *)((
unsigned int)module + ELF_Hdr->phoff);
617 if (((
unsigned short int *)ELF_Hdr->ident)[2] == 0x101 && ELF_Hdr->machine == 8 && ELF_Hdr->phentsize ==
sizeof(
elf_pheader_t) && ELF_Hdr->phnum == 2 && (ELF_phdr->type == (SHT_LOPROC | SHT_LOPROC_IOPMOD)) && (ELF_Hdr->type == ELF_TYPE_SCE_IRX || ELF_Hdr->type == 2)) {
618 ModuleInfo->ModuleType = ELF_Hdr->type == 0xFF80 ? IOP_MOD_TYPE_IRX : IOP_MOD_TYPE_ELF;
621 iopmod = (
struct iopmod *)((
unsigned int)module + ELF_phdr->offset);
624 ModuleInfo->text_start = (
void *)ELF_phdr[1].vaddr;
639 static void CopySection(
const void *module,
void *buffer,
unsigned int FileSize)
642 const unsigned int *src;
647 src_end = (
const void *)((
unsigned int)module + (FileSize >> 2 << 2));
648 while ((
unsigned int)src < (
unsigned int)src_end) {
656 static void ZeroSection(
unsigned int *buffer,
unsigned int NumWords)
658 while (NumWords > 0) {
666 static void LoadELFModule(
const void *module)
672 ELF_phdr = (
elf_pheader_t *)((
unsigned int)module + ELF_Hdr->phoff);
674 CopySection((
void *)((
unsigned int)module + ELF_phdr[1].offset), (
void *)ELF_phdr[1].vaddr, ELF_phdr[1].filesz);
676 if (ELF_phdr[1].filesz < ELF_phdr[1].memsz) {
677 ZeroSection((
unsigned int *)(ELF_phdr[1].vaddr + ELF_phdr[1].filesz), (ELF_phdr[1].memsz - ELF_phdr[1].filesz) >> 2);
682 static void LoadCOFFModule(
const void *module)
685 const struct scnhdr *ScnHdr;
696 CopySection((
void *)((
unsigned int)module + ScnHdr[0].s_size), (
void *)COFF_AoutHdr->text_start, COFF_AoutHdr->tsize);
697 CopySection((
void *)((
unsigned int)module + COFF_AoutHdr->tsize), (
void *)COFF_AoutHdr->data_start, COFF_AoutHdr->dsize);
699 if (COFF_AoutHdr->bss_start != 0 && COFF_AoutHdr->bsize != 0) {
700 ZeroSection((
unsigned int *)COFF_AoutHdr->bss_start, COFF_AoutHdr->bsize >> 2);
710 unsigned int NumRelocs, i, SectionNum;
712 unsigned int temp, *WordPatchLocation;
715 ELF_phdr = (
elf_pheader_t *)((
unsigned int)module + ELF_hdr->phoff);
720 if (
ModuleInfo->mod_id != (
void *)0xFFFFFFFF) {
724 ELF_shdr = (
elf_shdr_t *)((
unsigned int)module + ELF_hdr->shoff);
726 CopySection((
void *)((
unsigned int)module + ELF_phdr[1].offset),
ModuleInfo->text_start, ELF_phdr[1].filesz);
729 if (ELF_phdr[1].filesz < ELF_phdr[1].memsz) {
730 ZeroSection((
unsigned int *)((u8 *)(
ModuleInfo->text_start) + ELF_phdr[1].filesz), (ELF_phdr[1].memsz - ELF_phdr[1].filesz) >> 2);
734 for (SectionNum = 0, CurrentELF_shdr = ELF_shdr + 1; SectionNum < ELF_hdr->shnum; SectionNum++, CurrentELF_shdr++) {
735 if (CurrentELF_shdr->type == SHT_REL) {
736 NumRelocs = CurrentELF_shdr->size / CurrentELF_shdr->entsize;
739 for (i = 0, ELF_relocation = (
elf_rel *)((
unsigned int)module + CurrentELF_shdr->offset); i < NumRelocs; i++, ELF_relocation++) {
742 switch (ELF_relocation->info & 0xFF) {
746 WordPatchLocation = (
unsigned int *)((u8 *)(
ModuleInfo->text_start) + ELF_relocation->offset);
747 *WordPatchLocation = (*WordPatchLocation & 0xFFFF0000) | (((
unsigned int)
ModuleInfo->text_start + *(
short int *)((u8 *)(
ModuleInfo->text_start) + ELF_relocation->offset)) & 0xFFFF);
750 WordPatchLocation = (
unsigned int *)((u8 *)(
ModuleInfo->text_start) + ELF_relocation->offset);
751 *WordPatchLocation += (
unsigned int)
ModuleInfo->text_start;
756 WordPatchLocation = (
unsigned int *)((u8 *)(
ModuleInfo->text_start) + ELF_relocation->offset);
757 *WordPatchLocation = (((
unsigned int)
ModuleInfo->text_start + ((*WordPatchLocation & 0x03FFFFFF) << 2 | ((
unsigned int)WordPatchLocation & 0xF0000000))) << 4 >> 6) | (*WordPatchLocation & 0xFC000000);
760 temp = (((
unsigned int)*(
unsigned short int *)((u8 *)(
ModuleInfo->text_start) + ELF_relocation->offset)) << 16) + *(
short int *)((u8 *)(
ModuleInfo->text_start) + ELF_relocation[1].offset);
762 WordPatchLocation = (
unsigned int *)((u8 *)(
ModuleInfo->text_start) + ELF_relocation->offset);
763 *WordPatchLocation = (((temp >> 15) + 1) >> 1 & 0xFFFF) | (*WordPatchLocation & 0xFFFF0000);
764 WordPatchLocation = (
unsigned int *)((u8 *)(
ModuleInfo->text_start) + ELF_relocation[1].offset);
765 *WordPatchLocation = (*WordPatchLocation & 0xFFFF0000) | (temp & 0xFFFF);
781 unsigned short int version;
782 unsigned short int newflags;
783 unsigned short int id;
784 unsigned short int flags;
788 unsigned int text_size;
789 unsigned int data_size;
790 unsigned int bss_size;
791 unsigned int unused1;
792 unsigned int unused2;
804 if (
ModuleInfo->mod_id != (
void *)0xFFFFFFFF) {
821 case IOP_MOD_TYPE_ELF:
822 LoadELFModule(module);
824 case IOP_MOD_TYPE_COFF:
825 LoadCOFFModule(module);
827 case IOP_MOD_TYPE_IRX:
849 int (*ModuleEntryPoint)(
int arg1);
853 TerminateResidentEntriesDI(options);
860 MemSizeInBytes =
ResetData->MemSize << 20;
863 switch (InitModuleInfo(
ResetData->ModData[0], &LoadedModules[0])) {
865 case IOP_MOD_TYPE_IRX:
866 LoadedModules[0].text_start = (
void *)((
unsigned int)
ResetData->StartAddress + 0x30);
868 case IOP_MOD_TYPE_COFF:
869 case IOP_MOD_TYPE_ELF:
870 LoadModule(
ResetData->ModData[0], &LoadedModules[0]);
881 ModuleEntryPoint = LoadedModules[0].EntryPoint;
882 FreeMemStart = (
void *)ModuleEntryPoint(MemSizeInBytes);
885 switch (InitModuleInfo(
ResetData->ModData[1], &LoadedModules[1])) {
887 case IOP_MOD_TYPE_IRX:
888 LoadedModules[1].text_start = (
void *)((
unsigned int)FreeMemStart + 0x30);
890 case IOP_MOD_TYPE_COFF:
891 case IOP_MOD_TYPE_ELF:
892 LoadModule(
ResetData->ModData[1], &LoadedModules[1]);
903 ResetData->StartAddress = LoadedModules[0].text_start;
905 ModuleEntryPoint = LoadedModules[1].EntryPoint;
910 *(
volatile unsigned char *)0x80000000 = 2;
914 static void *ParseStartAddress(
const char **line)
921 while (*ptr >= 0x30) {
922 unsigned char character;
926 if (character <
':') {
928 }
else if (character <
'a') {
934 address = (
void *)(((
unsigned int)address << 4) + character);
944 unsigned short int data;
945 unsigned short int header;
952 const void *extinfo_end;
955 RomDirEnt = stat->romdirent;
956 extinfo_end = (
unsigned char *)stat->extinfo + (RomDirEnt->ExtInfoEntrySize >> 2 << 2);
959 while ((
unsigned int)
ExtInfoField < (
unsigned int)extinfo_end) {
960 unsigned int ExtInfoHeader;
964 if (ExtInfoHeader >> 24 == (
unsigned int)mode) {
978 int count, NumFilesRemaining, ImageFileIndexNumber;
983 unsigned int HighestFileVersionNum;
988 filename[
count] = *line;
991 }
while (count < 10 && *line >= 0x21);
993 filename[
count] =
'\0';
996 ImageFileIndexNumber = -1;
997 HighestFileVersionNum = 0;
998 NumFilesRemaining = NumFiles - 1;
1000 ImageDataPtr = &ImageDataBuffer[NumFilesRemaining];
1003 if (ImageDataPtr->filename != NULL) {
1004 if (GetFileStatFromImage(&ImageDataPtr->stat, filename, &stat) != NULL) {
1005 unsigned short int FileVersionNum;
1007 ExtInfofield = GetFileInfo(&stat, 2);
1009 GetFileInfo(&stat, 3);
1012 if (ExtInfofield != NULL) {
1013 FileVersionNum = ExtInfofield->data;
1016 if (ImageFileIndexNumber < 0 || HighestFileVersionNum < FileVersionNum) {
1017 ImageFileIndexNumber = NumFilesRemaining;
1018 HighestFileVersionNum = FileVersionNum;
1020 DEBUG_PRINTF(
"SelectModule: %s, %s, 0x%x\n", filename, ImageDataPtr->filename, FileVersionNum);
1025 }
while (--NumFilesRemaining >= 0);
1028 if (ImageFileIndexNumber >= 0) {
1029 result = GetFileStatFromImage(&ImageDataBuffer[ImageFileIndexNumber].stat, filename, stat_out);
1038 static void DisplayModuleName(
int id,
const char *line)
1043 for (i = 0; i < 11 && line[i] >=
' '; i++) {
1044 filename[i] = line[i];
1048 DEBUG_PRINTF(
"%d: %s\n",
id, filename);
1055 unsigned int FilesRemaining, i, NumModules;
1057 char filename_temp[16];
1060 const void **ModList;
1062 if ((
unsigned int)stat->data < (
unsigned int)stat->data + stat->romdirent->size) {
1063 FilesRemaining = NumFiles - 1;
1073 ResetData->StartAddress = ParseStartAddress(&ptr);
1076 if (strncmp(ptr,
"!addr ", 6) == 0) {
1078 ModList[NumModules] = (
void *)(((
unsigned int)ParseStartAddress(&ptr) << 2) + 1);
1083 ModList[NumModules] = NULL;
1084 }
else if (strncmp(ptr,
"!include ", 9) == 0) {
1088 while ((
unsigned int)ptr < (
unsigned int)stat->data + stat->romdirent->size) {
1090 filename_temp[i] = *ptr;
1096 filename_temp[i] =
'\0';
1098 ScanImagesForFile(ImageDataBuffer, FilesRemaining, &FileStat, filename_temp);
1099 ParseIOPBTCONF(ImageDataBuffer, FilesRemaining, &FileStat,
ResetData);
1132 DisplayModuleName(
ResetData->NumModules, ptr);
1134 if (SelectModuleFromImages(ImageDataBuffer, NumFiles, ptr, &ModuleFileStat) == NULL) {
1138 ModList[NumModules] = ModuleFileStat.data;
1143 ModList[NumModules] = NULL;
1147 if ((
unsigned int)ptr < (
unsigned int)stat->data + stat->romdirent->size) {
1148 while ((
unsigned int)ptr < (
unsigned int)stat->data + stat->romdirent->size) {
1154 if ((
unsigned int)ptr < (
unsigned int)stat->data + stat->romdirent->size) {
1155 while ((
unsigned int)ptr < (
unsigned int)stat->data + stat->romdirent->size) {
1163 }
while ((
unsigned int)ptr < (
unsigned int)stat->data + stat->romdirent->size);
1167 int _start(
int argc,
char *argv[])
1169 int ImageDataTotalSize;
1174 void *buffer, *IoprpBuffer;
1178 int fd, file_sz = 0, i, NumFiles;
1183 unsigned int BootMode4, BootMode3, options;
1187 BootMode4 = 0xFFFFFFFF;
1189 if ((BootModePtr = QueryBootMode(4)) != NULL) {
1190 BootMode4 = *(
unsigned char *)BootModePtr;
1192 if ((BootModePtr = QueryBootMode(3)) != NULL) {
1193 BootMode3 = *(
unsigned int *)((
unsigned char *)BootModePtr + 4);
1215 ImageDataTotalSize = (argc + 2) *
sizeof(
struct ImageData);
1216 ImageDataBuffer = alloca(ImageDataTotalSize);
1217 memset(ImageDataBuffer, 0, ImageDataTotalSize);
1219 TotalSize = MAX_MODULES *
sizeof(
void *) +
sizeof(
struct ResetData);
1220 #ifdef USE_EMBEDDED_IOPRP
1221 TotalSize += ((size_IOPRP_img + 0xF) & ~0xF);
1233 if (strcmp(argv[i],
"-v") == 0) {
1237 if (strcmp(argv[i],
"-v") != 0)
1240 else if (strcmp(argv[i],
"-nobusini") == 0 || strcmp(argv[i],
"-nb") == 0) {
1242 }
else if (strcmp(argv[i],
"-nocacheini") == 0 || strcmp(argv[i],
"-nc") == 0) {
1260 if ((fd = open(argv[i], O_RDONLY)) < 0) {
1262 printf(
"kupdate: pannic ! file \'%s\' can't open\n", argv[i]);
1264 printf(
"file \'%s\' can't open\n", argv[i]);
1267 if (BootMode4 & 2) {
1275 file_sz = lseek(fd, 0, SEEK_END);
1276 lseek(fd, 0, SEEK_SET);
1281 TotalSize += (file_sz + 0xF) & ~0xF;
1300 if ((buffer = AllocMemory(TotalSize)) == NULL) {
1302 printf(
"kupdate: pannic ! can not alloc memory\n");
1304 printf(
"pannic ! can not alloc memory\n");
1307 if (BootMode4 & 2) {
1318 IoprpBuffer = (
void *)((
unsigned int)buffer + MAX_MODULES *
sizeof(
void *) +
sizeof(
struct ResetData));
1319 ResetData->IOPRPBuffer = (
void *)((
unsigned int)IoprpBuffer & 0x1FFFFF00);
1320 ResetData->MemSize = QueryMemSize() >> 20;
1323 if (BootMode3 & 0x00000080) {
1324 printf(
" Logical memory size 8MB ---> 2MB\n");
1331 if (GetIOPRPStat((
void *)0xbfc00000, (
void *)0xbfc10000, &ImageDataBuffer[0].stat) != NULL) {
1332 ImageDataBuffer[0].filename =
"ROM";
1335 if (BootMode3 & 0x00000100) {
1336 if (GetFileStatFromImage(&ImageDataBuffer[0].stat,
"OLDROM", &ROMStat) != 0 && GetIOPRPStat(ROMStat.data, (
const void *)((
const u8 *)(ROMStat.data) + 0x40000), &ImageDataBuffer[1].stat)) {
1337 memcpy(&ImageDataBuffer[0].stat, &ImageDataBuffer[1].stat,
sizeof(ImageDataBuffer[0].stat));
1338 printf(
" use alternate ROM image\n");
1344 #ifdef USE_EMBEDDED_IOPRP
1346 if (size_IOPRP_img >= 0x10 && GetIOPRPStat(IOPRP_img, &IOPRP_img[size_IOPRP_img], &ImageDataBuffer[1].stat) != NULL) {
1347 ImageDataBuffer[1].filename =
"DATA";
1348 ResetData->IOPRPBuffer = (
void*)((
unsigned int)IOPRP_img & ~0xF);
1351 if (size_IOPRP_img >= 0x10) {
1352 memcpy(IoprpBuffer, IOPRP_img, size_IOPRP_img);
1353 if (GetIOPRPStat(IoprpBuffer, (
void *)((
unsigned int)IoprpBuffer + size_IOPRP_img), &ImageDataBuffer[1].stat) != NULL) {
1354 ImageDataBuffer[1].filename =
"DATA";
1355 IoprpBuffer = (
void *)((u8 *)IoprpBuffer + ((size_IOPRP_img + 0xF) & ~0xF));
1368 if (GetIOPRPStat(IoprpBuffer, (
void *)((u8 *)IoprpBuffer + 0x4000), &
ImageData->stat) != NULL) {
1370 IoprpBuffer = (
void *)((u8 *)IoprpBuffer + ((
ImageData->size + 0xF) & ~0xF));
1378 }
while (i < NumFiles);
1385 ScanImagesForFile(ImageDataBuffer, NumFiles, &FileStat,
"IOPBTCONF");
1386 ParseIOPBTCONF(ImageDataBuffer, NumFiles, &FileStat,
ResetData);
1388 ScanImagesForFile(ImageDataBuffer, 2, &FileStat,
"IOPBTCONF");
1389 ParseIOPBTCONF(ImageDataBuffer, 2, &FileStat,
ResetData);
1392 DEBUG_PRINTF(
"Beginning IOP bootup sequence.\n");
1395 TerminateResidentLibraries(
" kupdate:ei: Terminate resident Libraries\n", options, 2);
1396 CpuExecuteKmode(&BeginBootupSequence,
ResetData, options);
1407 return MODULE_NO_RESIDENT_END;
1409 return MODULE_RESIDENT_END;
1414 static void *AllocMemory(
int nbytes)
1416 void *BlockTopAddress;
1419 BlockTopAddress = QueryBlockTopAddress((
void *)0x1860);
1420 BlockTopAddress = (
void *)((
unsigned int)BlockTopAddress & 0x7FFFFFFF);
1422 while ((result = QueryBlockSize(BlockTopAddress)) >= 0 || (result & 0x7FFFFFFF) < nbytes) {
1423 BlockTopAddress = QueryBlockTopAddress((
void *)(((
unsigned int)BlockTopAddress & 0x7FFFFFFF) + (result & 0x7FFFFFFF)));
1424 BlockTopAddress = (
void *)((
unsigned int)BlockTopAddress & 0x7FFFFFFF);
1426 }
while ((result & 0x7FFFFFFF) < nbytes);
1428 return AllocSysMemory(2, nbytes, BlockTopAddress);
1431 #ifdef THIS_IS_UNUSED
1434 "\t" ".set push" "\n"
1435 "\t" ".set noat" "\n"
1436 "\t" ".set noreorder" "\n"
1440 "\t" ".globl func_00001a34" "\n"
1441 "\t" ".ent func_00001a34" "\n"
1442 "\t" "func_00001a34:" "\n"
1444 "\t" ".globl func_00001544" "\n"
1445 "\t" ".ent func_00001544" "\n"
1446 "\t" "func_00001544:" "\n"
1448 "\t" "\t" "mfc0 $t0, $12" "\n"
1449 "\t" "\t" "nop" "\n"
1451 "\t" "\t" "la $t4, func_00001a34_main" "\n"
1453 "\t" "\t" "la $t4, func_00001544_main" "\n"
1455 "\t" "\t" "lui $at, 0xa000" "\n"
1456 "\t" "\t" "or $t4, $t4, $at" "\n"
1457 "\t" "\t" "jr $t4" "\n"
1459 "\t" "func_00001a34_main:" "\n"
1461 "\t" "func_00001544_main:" "\n"
1463 "\t" "\t" "mtc0 $zero, $12" "\n"
1464 "\t" "\t" "nop" "\n"
1465 "\t" "\t" "nop" "\n"
1466 "\t" "\t" "lui $t6, 0xbf80" "\n"
1467 "\t" "\t" "lw $t6, 0x1450($t6)" "\n"
1468 "\t" "\t" "nop" "\n"
1469 "\t" "\t" "addiu $t7, $zero, 0xfffe" "\n"
1470 "\t" "\t" "and $t1, $t6, $t7" "\n"
1471 "\t" "\t" "lui $at, 0xbf80" "\n"
1472 "\t" "\t" "sw $t1, 0x1450($at)" "\n"
1473 "\t" "\t" "lui $at, 0xbf80" "\n"
1474 "\t" "\t" "lw $zero, 0x1450($at)" "\n"
1475 "\t" "\t" "lui $t7, 0xbf80" "\n"
1476 "\t" "\t" "lw $t7, 0x1578($t7)" "\n"
1477 "\t" "\t" "lui $at, 0xbf80" "\n"
1478 "\t" "\t" "sw $zero, 0x1578($at)" "\n"
1479 "\t" "\t" "lui $at, 0xbf80" "\n"
1480 "\t" "\t" "lw $zero, 0x1578($at)" "\n"
1481 "\t" "\t" "lui $t5, 0xfffe" "\n"
1482 "\t" "\t" "lw $t5, 0x0130($t5)" "\n"
1483 "\t" "\t" "addiu $t1, $zero, 0x00c4" "\n"
1484 "\t" "\t" "lui $at, 0xfffe" "\n"
1485 "\t" "\t" "sw $t1, 0x0130($at)" "\n"
1486 "\t" "\t" "lui $t4, 0x0001" "\n"
1487 "\t" "\t" "mtc0 $t4, $12" "\n"
1488 "\t" "\t" "nop" "\n"
1489 "\t" "\t" "nop" "\n"
1490 "\t" "\t" "addiu $t2, $zero, 0x0000" "\n"
1491 "\t" "\t" "addiu $t3, $zero, 0x0380" "\n"
1493 "\t" "func_00001a34_loop:" "\n"
1495 "\t" "func_00001544_loop:" "\n"
1497 "\t" "\t" "sw $zero, 0x0000($t2)" "\n"
1498 "\t" "\t" "sw $zero, 0x0010($t2)" "\n"
1499 "\t" "\t" "sw $zero, 0x0020($t2)" "\n"
1500 "\t" "\t" "sw $zero, 0x0030($t2)" "\n"
1501 "\t" "\t" "sw $zero, 0x0040($t2)" "\n"
1502 "\t" "\t" "sw $zero, 0x0050($t2)" "\n"
1503 "\t" "\t" "sw $zero, 0x0060($t2)" "\n"
1504 "\t" "\t" "sw $zero, 0x0070($t2)" "\n"
1506 "\t" "\t" "bne $t2, $t3, func_00001a34_loop" "\n"
1508 "\t" "\t" "bne $t2, $t3, func_00001544_loop" "\n"
1510 "\t" "\t" "addi $t2, $t2, 0x0080" "\n"
1511 "\t" "\t" "mtc0 $zero, $12" "\n"
1512 "\t" "\t" "nop" "\n"
1513 "\t" "\t" "lui $at, 0xfffe" "\n"
1514 "\t" "\t" "sw $t5, 0x0130($at)" "\n"
1515 "\t" "\t" "lui $at, 0xfffe" "\n"
1516 "\t" "\t" "lw $zero, 0x0130($at)" "\n"
1517 "\t" "\t" "nop" "\n"
1518 "\t" "\t" "lui $at, 0xbf80" "\n"
1519 "\t" "\t" "sw $t7, 0x1578($at)" "\n"
1520 "\t" "\t" "lui $at, 0xbf80" "\n"
1521 "\t" "\t" "lw $zero, 0x1578($at)" "\n"
1522 "\t" "\t" "lui $at, 0xbf80" "\n"
1523 "\t" "\t" "sw $t6, 0x1450($at)" "\n"
1524 "\t" "\t" "lui $at, 0xbf80" "\n"
1525 "\t" "\t" "lw $zero, 0x1450($at)" "\n"
1526 "\t" "\t" "mtc0 $t0, $12" "\n"
1527 "\t" "\t" "nop" "\n"
1528 "\t" "\t" "jr $ra" "\n"
1529 "\t" "\t" "nop" "\n"
1531 "\t" ".end func_00001a34" "\n"
1533 "\t" ".end func_00001544" "\n"
1535 "\t" ".set pop" "\n"