12#include "irx_imports.h"
19IRX_ID(
"Module_Manager", 2, 6);
24static u32 *reboot_handlers;
108 R_MIPSSCE_MHI16 = 250,
109 R_MIPSSCE_ADDEND = 251,
112#define SHT_LOPROC 0x70000000
113#define SHT_LOPROC_EE_IMPORT_TAB 0x90
114#define SHT_LOPROC_IOPMOD 0x80
115#define SHT_HIPROC 0x7fffffff
116#define SHT_LOUSER 0x80000000
117#define SHT_HIUSER 0xffffffff
121#define SHF_EXECINSTR 0x4
122#define SHF_MASKPROC 0xf0000000
129 unsigned int text_size;
130 unsigned int data_size;
131 unsigned int bss_size;
132 unsigned short int version;
148#define MIPSELMAGIC 0x0162
151#define SOMAGIC 0x0701
189 IOP_MOD_TYPE_COFF = 1,
202 ET_SCE_IOPRELEXEC = 0xFF80,
203 ET_SCE_IOPRELEXEC2 = 0xFF81,
204 ET_SCE_EERELEXEC = 0xFF90,
205 ET_SCE_EERELEXEC2 = 0xFF91,
210 int (*cbCpuSuspendIntr)(
int *state);
211 int (*cbCpuResumeIntr)(
int state);
213 int (*cbQueryIntrContext)(void);
226static void lc_memset32(
int *b,
int c,
int len);
227static int lc_strlen(
const char *s);
228static void lc_memmove(
char *dst,
const char *src,
int len);
229static int cCpuSuspendIntr(
int *state);
230static int cCpuResumeIntr(
int state);
231static void loadcoff(
const void *module);
232static void loadelf(
const void *module);
234static void CopySection(
const void *module,
void *buffer,
unsigned int FileSize);
235static void ZeroSection(
unsigned int *buffer,
unsigned int NumWords);
239 unsigned int MemSize;
240 unsigned int BootMode;
244 unsigned int IOPRPBufferSize;
245 unsigned int NumModules;
246 const void **ModData;
249static u32 bootmodes[17];
251static u32 **
const bootmodes_start_ptr = (
void *)0x3F0;
252static u32 **
const bootmodes_end_ptr = (
void *)0x3F4;
261 "\t" ".set push" "\n"
262 "\t" ".set noat" "\n"
263 "\t" ".set noreorder" "\n"
264 "\t" ".global _start" "\n"
266 "\t" " mtc0 $zero, $12" "\n"
267 "\t" " lw $v0, 0x0($a0)" "\n"
269 "\t" " sll $sp, $v0, 20" "\n"
270 "\t" " addiu $sp, $sp, -0x40" "\n"
271 "\t" " addu $fp, $sp, $zero" "\n"
272 "\t" " lui $gp, %hi(_gp)" "\n"
273 "\t" " j loadcore_init" "\n"
274 "\t" " addiu $gp, $gp, %lo(_gp)" "\n"
281 const void **ModData;
285 char *blocksize_mask_1;
287 int blocksize_mask_2;
288 void *curmodaddr_align;
295 int *frame_pointer_curfunc;
298 u32 *stack_reboot_handlers;
301 params.MemSize = in_params->MemSize;
302 params.BootMode = in_params->BootMode;
303 params.command = in_params->command;
304 params.StartAddress = in_params->StartAddress;
305 params.IOPRPBuffer = in_params->IOPRPBuffer;
306 params.IOPRPBufferSize = in_params->IOPRPBufferSize;
307 params.NumModules = in_params->NumModules;
308 ModData = in_params->ModData;
309 loadcore_internals.let_next = (
iop_library_t *)params.StartAddress;
310#pragma GCC diagnostic push
311#pragma GCC diagnostic ignored "-Warray-bounds"
312 *bootmodes_start_ptr = bootmodes;
313 *bootmodes_end_ptr = bootmodes;
314#pragma GCC diagnostic pop
315 loadcore_internals.intr_suspend_tbl = NULL;
316 loadcore_internals.let_prev = (
iop_library_t *)params.StartAddress;
317 params.ModData = ModData;
318 loadcore_internals.let_prev->prev = NULL;
319 loadcore_internals.module_count = 2;
320 loadcore_internals.mda_next = 0;
321 loadcore_internals.mda_prev = 0;
322 loadcore_internals.module_index = 3;
323 for ( i = 0; i < 17; i += 1 )
330 bootmode_tmp[0] = (params.BootMode & 0xFFFF) | 0x40000;
333 sysmemmi = (
ModuleInfo_t *)((
char *)loadcore_internals.let_prev - 0x30);
336 sysmemmi->newflags = 3;
337#pragma GCC diagnostic push
338#pragma GCC diagnostic ignored "-Warray-bounds"
339 sysmemmi->next = (
ModuleInfo_t *)((u8 *)&_ftext - 0x30);
342#pragma GCC diagnostic pop
344 LinkLibraryEntries((u32 *)&_ftext, (u8 *)&_etext - (u8 *)&_ftext);
345 RegisterLibraryEntries(&_exp_loadcore);
346#pragma GCC diagnostic push
347#pragma GCC diagnostic ignored "-Warray-bounds"
350 (u32)(((u8 *)&_end) - ((u32)(((u8 *)&_ftext) - 0x30) >> 8 << 8)),
351 (
void *)(((u32)(((u8 *)&_ftext) - 0x30) >> 8 << 8) & 0x1FFFFFFF));
352#pragma GCC diagnostic pop
353 if ( params.IOPRPBuffer )
354 params.IOPRPBuffer = AllocSysMemory(2, params.IOPRPBufferSize, params.IOPRPBuffer);
355 frame_pointer_curfunc = __builtin_frame_address(0);
358 lc_memset32((
int *)((
unsigned int)frame_pointer_curfunc & 0x1FFFFF00), stack_pointer_curfunc, 0x11111111);
360 if ( ((
unsigned int)frame_pointer_curfunc & 0x1FFFFF00) < QueryMemSize() )
362 MemSize = QueryMemSize();
365 MemSize - ((
unsigned int)frame_pointer_curfunc & 0x1FFFFF00),
366 (
void *)((
unsigned int)frame_pointer_curfunc & 0x1FFFFF00));
368 if ( params.command )
371 int stack_command_size;
374 stack_command_size = lc_strlen(params.command) + 1;
375 stack_command = __builtin_alloca(stack_command_size);
376 lc_memmove(stack_command, params.command, stack_command_size);
378 params.command = stack_command;
379 bootmode_tmp[0] = 0x1050000;
380 bootmode_tmp[1] = (u32)stack_command;
385 int stack_moddata_size;
387 stack_moddata_size = (params.NumModules + 1) * 4;
388 stack_moddata = __builtin_alloca(stack_moddata_size);
389 lc_memmove(stack_moddata, (
const char *)params.ModData, stack_moddata_size);
390 params.ModData = (
const void **)stack_moddata;
392 stack_reboot_handlers = __builtin_alloca(params.NumModules * (
sizeof(u32) * 2));
393 reboot_handlers = stack_reboot_handlers;
395 for ( i = (
unsigned int)QueryBlockTopAddress(0); i != 0xFFFFFFFF;
396 i = (
unsigned int)QueryBlockTopAddress(&blocksize_mask_1[blocksize_mask_2]) )
398 blocksize_mask_1 = (
char *)(i & 0x7FFFFFFF);
399 BlockSize = QueryBlockSize(blocksize_mask_1);
400 blocksize_mask_2 = BlockSize & 0x7FFFFFFF;
402 lc_memset32((
int *)blocksize_mask_1, 0x400D, blocksize_mask_2);
404 curmodaddr_align = 0;
405 stack_reboot_handlers[0] = 0;
409 cur_module_addr = (
elf_header_t **)(params.ModData + 2);
412 if ( !*cur_module_addr )
414 if ( params.IOPRPBuffer )
416 lc_memset32((
int *)params.IOPRPBuffer, 0x400D, params.IOPRPBufferSize);
417 FreeSysMemory(params.IOPRPBuffer);
419 for ( i = 0; i < 4; i += 1 )
421 u32 *reboot_handler_ptr;
424 reboot_handlers = NULL;
425 reboot_handler_ptr = stack_reboot_handlers;
426 while ( *reboot_handler_ptr )
428 if ( (*reboot_handler_ptr & 3) == i )
432 next.callback = (
void *)*stack_reboot_handlers;
434 next.callback = (
void *)*reboot_handler_ptr;
435 __asm__ __volatile__(
"\tmove $gp, %0\n" : :
"r"(reboot_handler_ptr[1]));
436 ((void (*)(
iop_init_entry_t *, int))(*reboot_handler_ptr & (~3)))(&next, 1);
438 reboot_handler_ptr += 2;
442 while ( stack_reboot_handlers < reboot_handler_ptr )
444 reboot_handler_ptr -= 2;
445 if ( (*reboot_handler_ptr & 3) == 3 )
447 *reboot_handler_ptr = 0;
453 if ( ((
unsigned int)*cur_module_addr & 1) != 0 )
455 if ( ((
unsigned int)*cur_module_addr & 0xF) == 1 )
456 curmodaddr_align = (
void *)((
unsigned int)*cur_module_addr >> 2);
464 executable_type = ProbeExecutableObject(*cur_module_addr, &fi);
465 if ( executable_type == IOP_MOD_TYPE_IRX )
467 if ( curmodaddr_align )
470 memallocaddr = curmodaddr_align;
477 fi.text_start = AllocSysMemory(memalloctype, fi.MemSize + 0x30, memallocaddr);
478 if ( !fi.text_start )
480 fi.text_start = (
char *)fi.text_start + 0x30;
483 if ( executable_type == IOP_MOD_TYPE_COFF || executable_type == IOP_MOD_TYPE_ELF )
485 if ( !AllocSysMemory(
487 (
int)fi.text_start + fi.MemSize - ((((u32)mi) >> 8 << 8) & 0x1FFFFFFF),
488 (
void *)((((u32)mi) >> 8 << 8) & 0x1FFFFFFF)) )
491 LoadExecutableObject(*cur_module_addr, &fi);
492 if ( LinkLibraryEntries(fi.text_start, fi.text_size) == 0 )
495 entrypoint_ret = ((int (*)(u32, u32,
elf_header_t **, u32))fi.EntryPoint)(0, 0, cur_module_addr, 0);
496 if ( (entrypoint_ret & 3) != 1 )
500 if ( (entrypoint_ret & 3) == 2 )
501 mi->newflags |= 0x10;
502 if ( (entrypoint_ret & (~3)) != 0 )
503 AddRebootNotifyHandler((BootupCallback_t)(entrypoint_ret & (~3)), 2, 0);
507 UnLinkLibraryEntries(fi.text_start, fi.text_size);
508 FreeSysMemory((
void *)(((u32)mi) >> 8 << 8));
513 FreeSysMemory((
void *)(((u32)mi) >> 8 << 8));
515 curmodaddr_align = 0;
517 cur_module_addr += 1;
520 *(vu8 *)0x80000000 = 2;
528#pragma GCC diagnostic push
529#pragma GCC diagnostic ignored "-Warray-bounds"
530 bootmode_dst = *bootmodes_end_ptr;
531#pragma GCC diagnostic pop
532 effective_len = b->len + 1;
533 if (
sizeof(bootmodes) >= (effective_len *
sizeof(bootmodes[0])) )
537 for ( i = 0; i < effective_len; i += 1 )
539 bootmode_dst[i] = ((u32 *)b)[i];
541 bootmode_dst[effective_len] = 0;
542#pragma GCC diagnostic push
543#pragma GCC diagnostic ignored "-Warray-bounds"
544 *bootmodes_end_ptr = bootmode_dst;
545#pragma GCC diagnostic pop
549int *QueryBootMode(
int mode)
553#pragma GCC diagnostic push
554#pragma GCC diagnostic ignored "-Warray-bounds"
556#pragma GCC diagnostic pop
557 while ( *(u32 *)bootmode_cur )
559 if ( mode == bootmode_cur->id )
560 return (
int *)bootmode_cur;
561 bootmode_cur = (
iop_bootmode_t *)((u8 *)bootmode_cur + ((bootmode_cur->len + 1)) * 4);
566int AddRebootNotifyHandler(BootupCallback_t func,
int priority,
int *stat)
571 next.callback = (
void *)1;
573 __asm__ __volatile__(
"\tmove %0, $gp\n" :
"=r"(gp_val) :);
575 if ( !reboot_handlers )
585 reboot_handlers[0] = (u32)func + (priority & 3);
586 reboot_handlers[1] = gp_val;
587 reboot_handlers += 2;
588 reboot_handlers[0] = 0;
598 while ( image_info && image_info->next && (image_info->next < mi) )
600 image_info = image_info->next;
602 mi->next = image_info;
604 module_index = loadcore_internals.module_index;
605 mi->id = loadcore_internals.module_index & 0xFFFF;
606 loadcore_internals.module_index = module_index + 1;
607 loadcore_internals.module_count += 1;
620 while ( image_info && (image_info->next != mi) )
622 image_info = image_info->next;
628 image_info->next = image_info->next->next;
629 loadcore_internals.module_count -= 1;
639 if ( (
unsigned int)addr >= image_info->text_start )
643 < image_info->text_start + image_info->text_size + image_info->data_size + image_info->bss_size )
646 image_info = image_info->next;
664 if ( !exports || exports->magic != 0x41C00000 )
665 return KE_ILLEGAL_LIBRARY;
666 cCpuSuspendIntr(&state);
671 if ( IsSameLibrary(exports, let_next) && !compLibMinVersion_major(exports, let_next) )
675 if ( compLibMinVersion_minor(exports, let_next) <= 0 )
677 cCpuResumeIntr(state);
678 return KE_LIBRARY_FOUND;
680 p_next = &let_next->next;
681 next = let_next->next;
682 nexttmp2 = let_next->next;
686 nexttmp2 = next->next;
687 if ( (next->mode & 1) != 0 )
690 p_next = &next->next;
695 next->next = nexttmp1;
703 p_mda_next = &loadcore_internals.mda_next;
704 while ( p_mda_next[1] )
708 || compLibMinVersion_major_1(exports, (
struct irx_export_table *)p_mda_next[1]) )
714 nexttmp3 = p_mda_next[1];
718 p_mda_next[1] = caller;
725 nexttmp4 = nexttmp1->next;
726 aLinkClient(nexttmp5, exports);
727 nexttmp1->next = exports->next;
728 exports->next = nexttmp1;
733 exports->magic = (u32)loadcore_internals.let_next;
735 cCpuResumeIntr(state);
742 if ( !exports || exports->magic != 0x41C00000 )
743 return KE_ILLEGAL_LIBRARY;
745 exports->magic = (u32)loadcore_internals.let_next;
758 cCpuSuspendIntr(&state);
759 lcitmp = &loadcore_internals;
761 while ( let_next && let_next != exports )
766 if ( let_next != exports )
768 cCpuResumeIntr(state);
769 return KE_LIBRARY_NOTFOUND;
773 cCpuResumeIntr(state);
774 return KE_LIBRARY_INUSE;
776 magic = exports->magic;
779 exports->magic = 0x41C00000;
780 cCpuResumeIntr(state);
793 if ( compLibMinVersion_major_1(let_next, (
struct irx_export_table *)library) == 0 )
794 return let_next->fptrs;
801int LinkLibraryEntries(
void *addr,
int size)
805 for ( i = 0; i < (
unsigned int)size >> 2; i += 1 )
810 if ( importtmp1->magic == 0x41E00000 && CheckCallerStub(importtmp1) && (importtmp1->mode & 7) == 0 )
812 if ( aLinkLibEntries(importtmp1) )
814 UnLinkLibraryEntries(addr, size);
822int UnLinkLibraryEntries(
void *addr,
int size)
833 nexttmp1 = (
struct irx_import_table *)((
char *)addr + 4 * ((
unsigned int)size >> 2));
836 next = let_next->next;
840 if ( (u8 *)next >= (u8 *)addr && next < nexttmp1 )
842 if ( aUnLinkLibEntries(let_next, next) != 0 )
849#pragma GCC diagnostic push
850#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
851 if ( (u8 *)let_next >= (u8 *)addr && let_next < nexttmp1 )
852 ReleaseLibraryEntries((
void *)let_next);
853#pragma GCC diagnostic pop
857 while ( p_mda_next->next )
859 next = p_mda_next->next;
862 p_mda_next = p_mda_next->next;
867 cleanStub(p_mda_next->next);
868 nexttmp2 = p_mda_next->next;
869 nexttmp3 = nexttmp2->next;
871 p_mda_next->next = nexttmp3;
879 return &loadcore_internals;
892int SetRebootTimeLibraryHandlingMode(
struct irx_export_table *exports,
int mode)
898 return KE_ILLEGAL_LIBRARY;
899 cCpuSuspendIntr(&state);
901 while ( let_next && let_next->magic )
905 if ( let_next != exports && exports->magic != 0x41C00000 )
907 cCpuResumeIntr(state);
908 return KE_LIBRARY_NOTFOUND;
911 exports->mode |= (mode & 6);
912 cCpuResumeIntr(state);
918 return (*(u32 *)src->name == *(u32 *)dst->name) && (*(u32 *)&src->name[4] == *(u32 *)&dst->name[4]);
923 return ((src->version & 0xFF00) >> 8) - ((dst->version & 0xFF00) >> 8);
928 return (src->version & 0xFF) - (dst->version & 0xFF);
933 return (*(u32 *)dst->name == *(u32 *)src->name) && (*(u32 *)&dst->name[4] == *(u32 *)&src->name[4]);
938 return ((src->version & 0xFF00) >> 8) - ((dst->version & 0xFF00) >> 8);
945#pragma GCC diagnostic push
946#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
947 stubs = (
const void **)(imp->stubs);
948#pragma GCC diagnostic pop
949 while ( stubs[0] && (
unsigned int)stubs[1] >> 26 != 9 )
951 stubs[0] = (
void *)0x3E00008;
960 if ( imp->magic != 0x41E00000 )
962#pragma GCC diagnostic push
963#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
964 stubs = (
const void **)(imp->stubs);
965#pragma GCC diagnostic pop
966 while ( stubs[0] && (
unsigned int)stubs[1] >> 26 == 9
967 && (stubs[0] == (
void *)0x3E00008 || (
unsigned int)(stubs[0]) >> 26 == 2) )
971 if ( stubs[0] || stubs[1] )
973 return (
const void **)(imp->stubs) < stubs;
980 let_next = loadcore_internals.let_next;
981#pragma GCC diagnostic push
982#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
987 let_next = let_next->prev;
989#pragma GCC diagnostic pop
993 imp->next = let_next->caller;
994 let_next->caller = imp;
1002 unsigned int fptrs_count;
1005#pragma GCC diagnostic push
1006#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
1008#pragma GCC diagnostic pop
1010 fptrs = (
const void **)exp->fptrs;
1011 while ( fptrs[fptrs_count] )
1015 for ( ; *stubs; stubs += 2 )
1017 unsigned int stubtmp;
1019 stubtmp = (u16)(uiptr)stubs[1];
1020 if ( (
unsigned int)stubs[1] >> 26 != 9 )
1023 (
void *)(stubtmp >= fptrs_count ? 0x3E00008 : (((unsigned int)fptrs[stubtmp] >> 2) & 0x3FFFFFF) | 0x8000000);
1037 a1->next = a2->next;
1040 while ( next->next )
1042 nexttmp1 = next->next;
1043 if ( nexttmp1 == a2 )
1045 next->next = nexttmp1->next;
1049 if ( !nexttmp1->next )
1056static void lc_memset32(
int *b,
int c,
int len)
1059 for ( i = 0; i < len; i += 1 )
1065static int lc_strlen(
const char *s)
1077static void lc_memmove(
char *dst,
const char *src,
int len)
1087 for ( ; len > 0; v3 += 1 )
1100 for ( i = len - 1; i >= 0; *v5 = v6 )
1110static int cCpuSuspendIntr(
int *state)
1113 if ( intrman_callbacks && intrman_callbacks->cbCpuSuspendIntr )
1114 return intrman_callbacks->cbCpuSuspendIntr(state);
1119static int cCpuResumeIntr(
int state)
1122 if ( intrman_callbacks && intrman_callbacks->cbCpuResumeIntr )
1123 return intrman_callbacks->cbCpuResumeIntr(state);
1129static int cQueryIntrContext(
void)
1132 if ( intrman_callbacks && intrman_callbacks->cbQueryIntrContext )
1133 return intrman_callbacks->cbQueryIntrContext();
1139int ProbeExecutableObject(
void *image,
FileInfo_t *result)
1141 const struct scnhdr *COFF_ScnHdr;
1148 ((
struct coff_filehdr *)image)->f_magic == MIPSELMAGIC && COFF_AoutHdr->magic == OMAGIC
1150 && ((((
struct coff_filehdr *)image)->f_flags & 0x2) != 0) && COFF_ScnHdr->s_paddr == COFF_AoutHdr->text_start )
1152 if ( COFF_AoutHdr->vstamp != 0x7001 )
1154 result->ModuleType = IOP_MOD_TYPE_COFF;
1155 result->EntryPoint = (
void *)COFF_AoutHdr->entry;
1156 result->gp = (
void *)COFF_AoutHdr->gp_value;
1157 result->text_start = (
void *)COFF_AoutHdr->text_start;
1158 result->text_size = COFF_AoutHdr->tsize;
1159 result->data_size = COFF_AoutHdr->dsize;
1160 result->bss_size = COFF_AoutHdr->bsize;
1161 result->MemSize = COFF_AoutHdr->bss_start + COFF_AoutHdr->bsize - COFF_AoutHdr->text_start;
1162 result->mod_id = COFF_AoutHdr->mod_id;
1164 return result->ModuleType;
1173 ELF_phdr = (
elf_pheader_t *)((
unsigned int)image + ELF_Hdr->phoff);
1176 ((
unsigned short int *)ELF_Hdr->ident)[2] == 0x101 && ELF_Hdr->machine == 8
1177 && ELF_Hdr->phentsize ==
sizeof(
elf_pheader_t) && ELF_Hdr->phnum == 2
1178 && (ELF_phdr->type == (SHT_LOPROC | SHT_LOPROC_IOPMOD))
1179 && (ELF_Hdr->type == ET_SCE_IOPRELEXEC || ELF_Hdr->type == ET_SCE_IOPRELEXEC2 || ELF_Hdr->type == ET_EXEC) )
1181 result->ModuleType = (ELF_Hdr->type == ET_SCE_IOPRELEXEC || ELF_Hdr->type == ET_SCE_IOPRELEXEC2) ?
1185 iopmod = (
struct iopmod *)((
unsigned int)image + ELF_phdr->offset);
1186 result->EntryPoint = (
void *)
iopmod->EntryPoint;
1187 result->gp = (
void *)
iopmod->gp;
1188 result->text_start = (
void *)ELF_phdr[1].vaddr;
1189 result->text_size =
iopmod->text_size;
1190 result->data_size =
iopmod->data_size;
1191 result->bss_size =
iopmod->bss_size;
1192 result->MemSize = ELF_phdr[1].memsz;
1193 result->mod_id =
iopmod->mod_id;
1195 return result->ModuleType;
1202int LoadExecutableObject(
void *image,
FileInfo_t *fi)
1204 switch ( fi->ModuleType )
1206 case IOP_MOD_TYPE_ELF:
1209 case IOP_MOD_TYPE_COFF:
1212 case IOP_MOD_TYPE_IRX:
1213 loadrelelf(image, fi);
1219 CopyModInfo(fi, (
void *)((u8 *)(fi->text_start) - 0x30));
1234 mi->name = (
char *)(fi->mod_id->name);
1235 mi->version = fi->mod_id->version;
1237 mi->
entry = (u32)fi->EntryPoint;
1238 mi->gp = (u32)fi->gp;
1239 mi->text_start = (u32)fi->text_start;
1240 mi->text_size = fi->text_size;
1241 mi->data_size = fi->data_size;
1242 mi->bss_size = fi->bss_size;
1245static void loadcoff(
const void *module)
1248 const struct scnhdr *ScnHdr;
1250 COFF_AoutHdr = (
AOUTHDR *)((u8 *)
module + sizeof(struct coff_filehdr));
1251 ScnHdr = (
struct scnhdr *)((u8 *)
module + sizeof(struct coff_filehdr) + sizeof(AOUTHDR));
1253 CopySection((
void *)((u8 *)module + ScnHdr[0].s_size), (
void *)COFF_AoutHdr->text_start, COFF_AoutHdr->tsize);
1254 CopySection((
void *)((u8 *)module + COFF_AoutHdr->tsize), (
void *)COFF_AoutHdr->data_start, COFF_AoutHdr->dsize);
1256 if ( COFF_AoutHdr->bss_start != 0 && COFF_AoutHdr->bsize != 0 )
1258 ZeroSection((
unsigned int *)COFF_AoutHdr->bss_start, COFF_AoutHdr->bsize >> 2);
1262static void loadelf(
const void *module)
1268 ELF_phdr = (
elf_pheader_t *)((u8 *)ELF_Hdr + ELF_Hdr->phoff);
1270 CopySection((
void *)((u8 *)module + ELF_phdr[1].offset), (
void *)ELF_phdr[1].vaddr, ELF_phdr[1].filesz);
1272 if ( ELF_phdr[1].filesz < ELF_phdr[1].memsz )
1275 (
unsigned int *)((u8 *)(ELF_phdr[1].vaddr) + ELF_phdr[1].filesz), (ELF_phdr[1].memsz - ELF_phdr[1].filesz) >> 2);
1283 const elf_shdr_t *ELF_shdr, *CurrentELF_shdr;
1284 unsigned int NumRelocs, SectionNum;
1287 ELF_phdr = (
elf_pheader_t *)((u8 *)
module + ELF_hdr->phoff);
1292 if (
ModuleInfo->mod_id != (
void *)0xFFFFFFFF )
1297 ELF_shdr = (
elf_shdr_t *)((u8 *)
module + ELF_hdr->shoff);
1299 CopySection((
void *)((u8 *)module + ELF_phdr[1].offset),
ModuleInfo->text_start, ELF_phdr[1].filesz);
1301 if ( ELF_phdr[1].filesz < ELF_phdr[1].memsz )
1304 (
unsigned int *)((u8 *)(
ModuleInfo->text_start) + ELF_phdr[1].filesz),
1305 (ELF_phdr[1].memsz - ELF_phdr[1].filesz) >> 2);
1308 for ( SectionNum = 0, CurrentELF_shdr = ELF_shdr + 1; SectionNum < ELF_hdr->shnum;
1309 SectionNum += 1, CurrentELF_shdr += 1 )
1311 if ( CurrentELF_shdr->type == SHT_REL )
1314 entsize = CurrentELF_shdr->entsize;
1317 NumRelocs = CurrentELF_shdr->size / entsize;
1318 ApplyElfRelSection(
ModuleInfo->text_start, (
const elf_rel *)((u8 *)module + CurrentELF_shdr->offset), NumRelocs);
1323void ApplyElfRelSection(
void *buffer,
const void *module,
int element_count)
1327 const elf_rel *ELF_relocation;
1329 startaddr = (u32)buffer;
1330 ELF_relocation =
module;
1331 for ( i = 0; i < element_count; i += 1 )
1337 datal = (u32 *)((u8 *)buffer + ELF_relocation[i].offset);
1338 switch ( ELF_relocation[i].
info & 0xFF )
1341 datai = startaddr + (s16) * (u32 *)datal;
1342 *(u32 *)datal &= 0xFFFF0000;
1343 *(u32 *)datal |= (u16)datai;
1346 *(u32 *)datal += startaddr;
1349 datai = startaddr + ((ELF_relocation[i].offset & 0xF0000000) | (4 * (*(u32 *)datal & 0x3FFFFFF)));
1350 *(u32 *)datal &= 0xFC000000;
1351 *(u32 *)datal |= datai << 4 >> 6;
1354 datai = startaddr + (s16) * (u32 *)((u8 *)buffer + ELF_relocation[i + 1].offset) + (*(u32 *)datal << 16);
1355 *(u32 *)datal &= 0xFFFF0000;
1356 *(u32 *)datal |= (u16)(((datai >> 15) + 1) >> 1);
1359 datai = (startaddr + *(u32 *)datal) & 0xFFFF;
1360 *(u32 *)datal &= 0xFFFF0000;
1361 *(u32 *)datal |= datai;
1363 case R_MIPSSCE_MHI16:
1364 datai = ((((startaddr + ELF_relocation[i + 1].offset) >> 15) + 1) >> 1) & 0xFFFF;
1365 for ( daddr = 1; daddr != 0; datal += daddr )
1367 daddr = *(u16 *)datal << 16 >> 14;
1368 *(u32 *)datal &= 0xFFFF0000;
1369 *(u32 *)datal |= datai;
1379static void CopySection(
const void *module,
void *buffer,
unsigned int FileSize)
1382 const unsigned int *src;
1383 const void *src_end;
1387 src_end = (
const void *)((
unsigned int)
module + (FileSize >> 2 << 2));
1388 while ( (
unsigned int)src < (
unsigned int)src_end )
1396static void ZeroSection(
unsigned int *buffer,
unsigned int NumWords)
1398 while ( NumWords > 0 )
1408 "\t" ".set push" "\n"
1409 "\t" ".set noat" "\n"
1410 "\t" ".set noreorder" "\n"
1411 "\t" ".global FlushIcache" "\n"
1412 "\t" "FlushIcache:" "\n"
1413 "\t" " mfc0 $t0, $12" "\n"
1415 "\t" " lui $t4, %hi(FlushIcache_inner)" "\n"
1416 "\t" " addiu $t4, $t4, %lo(FlushIcache_inner)" "\n"
1417 "\t" " lui $at, (0xA0000000 >> 16)" "\n"
1418 "\t" " or $t4, $t4, $at" "\n"
1420 "\t" "FlushIcache_inner:" "\n"
1421 "\t" " mtc0 $zero, $12" "\n"
1424 "\t" " lui $t6, 0xBF80" "\n"
1425 "\t" " lw $t6, (0xBF801450 & 0xFFFF)($t6)" "\n"
1427 "\t" " addiu $t7, $zero, -0x2" "\n"
1428 "\t" " and $t1, $t6, $t7" "\n"
1429 "\t" " lui $at, 0xBF80" "\n"
1430 "\t" " sw $t1, (0xBF801450 & 0xFFFF)($at)" "\n"
1431 "\t" " lui $at, 0xBF80" "\n"
1432 "\t" " lw $zero, (0xBF801450 & 0xFFFF)($at)" "\n"
1433 "\t" " lui $t7, 0xBF80" "\n"
1434 "\t" " lw $t7, (0xBF801578 & 0xFFFF)($t7)" "\n"
1435 "\t" " lui $at, 0xBF80" "\n"
1436 "\t" " sw $zero, (0xBF801578 & 0xFFFF)($at)" "\n"
1437 "\t" " lui $at, 0xBF80" "\n"
1438 "\t" " lw $zero, (0xBF801578 & 0xFFFF)($at)" "\n"
1439 "\t" " lui $t5, (0xFFFE0130 >> 16)" "\n"
1440 "\t" " lw $t5, (0xFFFE0130 & 0xFFFF)($t5)" "\n"
1441 "\t" " addiu $t1, $zero, 0xC04" "\n"
1442 "\t" " lui $at, (0xFFFE0130 >> 16)" "\n"
1443 "\t" " sw $t1, (0xFFFE0130 & 0xFFFF)($at)" "\n"
1444 "\t" " lui $t4, (0x10000 >> 16)" "\n"
1445 "\t" " mtc0 $t4, $12" "\n"
1448 "\t" " addiu $t2, $zero, 0x0" "\n"
1449 "\t" " addiu $t3, $zero, 0xF80" "\n"
1450 "\t" ".LFlushIcache_1:" "\n"
1451 "\t" " sw $zero, 0x0($t2)" "\n"
1452 "\t" " sw $zero, 0x10($t2)" "\n"
1453 "\t" " sw $zero, 0x20($t2)" "\n"
1454 "\t" " sw $zero, 0x30($t2)" "\n"
1455 "\t" " sw $zero, 0x40($t2)" "\n"
1456 "\t" " sw $zero, 0x50($t2)" "\n"
1457 "\t" " sw $zero, 0x60($t2)" "\n"
1458 "\t" " sw $zero, 0x70($t2)" "\n"
1459 "\t" " bne $t2, $t3, .LFlushIcache_1" "\n"
1460 "\t" " addi $t2, $t2, 0x80" "\n"
1461 "\t" " mtc0 $zero, $12" "\n"
1463 "\t" " lui $at, (0xFFFE0130 >> 16)" "\n"
1464 "\t" " sw $t5, (0xFFFE0130 & 0xFFFF)($at)" "\n"
1465 "\t" " lui $at, (0xFFFE0130 >> 16)" "\n"
1466 "\t" " lw $zero, (0xFFFE0130 & 0xFFFF)($at)" "\n"
1468 "\t" " lui $at, 0xBF80" "\n"
1469 "\t" " sw $t7, (0xBF801578 & 0xFFFF)($at)" "\n"
1470 "\t" " lui $at, 0xBF80" "\n"
1471 "\t" " lw $zero, (0xBF801578 & 0xFFFF)($at)" "\n"
1472 "\t" " lui $at, 0xBF80" "\n"
1473 "\t" " sw $t6, (0xBF801450 & 0xFFFF)($at)" "\n"
1474 "\t" " lui $at, 0xBF80" "\n"
1475 "\t" " lw $zero, (0xBF801450 & 0xFFFF)($at)" "\n"
1476 "\t" " mtc0 $t0, $12" "\n"
1480 "\t" ".set pop" "\n"
1484 "\t" ".set push" "\n"
1485 "\t" ".set noat" "\n"
1486 "\t" ".set noreorder" "\n"
1487 "\t" ".global FlushDcache" "\n"
1488 "\t" "FlushDcache:" "\n"
1489 "\t" " mfc0 $t0, $12" "\n"
1491 "\t" " lui $t4, %hi(FlushDcache_inner)" "\n"
1492 "\t" " addiu $t4, $t4, %lo(FlushDcache_inner)" "\n"
1493 "\t" " lui $at, (0xA0000000 >> 16)" "\n"
1494 "\t" " or $t4, $t4, $at" "\n"
1496 "\t" "FlushDcache_inner:" "\n"
1497 "\t" " mtc0 $zero, $12" "\n"
1500 "\t" " lui $t6, 0xBF80" "\n"
1501 "\t" " lw $t6, (0xBF801450 & 0xFFFF)($t6)" "\n"
1503 "\t" " addiu $t7, $zero, -0x2" "\n"
1504 "\t" " and $t1, $t6, $t7" "\n"
1505 "\t" " lui $at, 0xBF80" "\n"
1506 "\t" " sw $t1, (0xBF801450 & 0xFFFF)($at)" "\n"
1507 "\t" " lui $at, 0xBF80" "\n"
1508 "\t" " lw $zero, (0xBF801450 & 0xFFFF)($at)" "\n"
1509 "\t" " lui $t7, 0xBF80" "\n"
1510 "\t" " lw $t7, (0xBF801578 & 0xFFFF)($t7)" "\n"
1511 "\t" " lui $at, 0xBF80" "\n"
1512 "\t" " sw $zero, (0xBF801578 & 0xFFFF)($at)" "\n"
1513 "\t" " lui $at, 0xBF80" "\n"
1514 "\t" " lw $zero, (0xBF801578 & 0xFFFF)($at)" "\n"
1515 "\t" " lui $t5, (0xFFFE0130 >> 16)" "\n"
1516 "\t" " lw $t5, (0xFFFE0130 & 0xFFFF)($t5)" "\n"
1517 "\t" " addiu $t1, $zero, 0xC4" "\n"
1518 "\t" " lui $at, (0xFFFE0130 >> 16)" "\n"
1519 "\t" " sw $t1, (0xFFFE0130 & 0xFFFF)($at)" "\n"
1520 "\t" " lui $t4, (0x10000 >> 16)" "\n"
1521 "\t" " mtc0 $t4, $12" "\n"
1524 "\t" " addiu $t2, $zero, 0x0" "\n"
1525 "\t" " addiu $t3, $zero, 0x380" "\n"
1526 "\t" ".LFlushDcache_1:" "\n"
1527 "\t" " sw $zero, 0x0($t2)" "\n"
1528 "\t" " sw $zero, 0x10($t2)" "\n"
1529 "\t" " sw $zero, 0x20($t2)" "\n"
1530 "\t" " sw $zero, 0x30($t2)" "\n"
1531 "\t" " sw $zero, 0x40($t2)" "\n"
1532 "\t" " sw $zero, 0x50($t2)" "\n"
1533 "\t" " sw $zero, 0x60($t2)" "\n"
1534 "\t" " sw $zero, 0x70($t2)" "\n"
1535 "\t" " bne $t2, $t3, .LFlushDcache_1" "\n"
1536 "\t" " addi $t2, $t2, 0x80" "\n"
1537 "\t" " mtc0 $zero, $12" "\n"
1539 "\t" " lui $at, (0xFFFE0130 >> 16)" "\n"
1540 "\t" " sw $t5, (0xFFFE0130 & 0xFFFF)($at)" "\n"
1541 "\t" " lui $at, (0xFFFE0130 >> 16)" "\n"
1542 "\t" " lw $zero, (0xFFFE0130 & 0xFFFF)($at)" "\n"
1544 "\t" " lui $at, 0xBF80" "\n"
1545 "\t" " sw $t7, (0xBF801578 & 0xFFFF)($at)" "\n"
1546 "\t" " lui $at, 0xBF80" "\n"
1547 "\t" " lw $zero, (0xBF801578 & 0xFFFF)($at)" "\n"
1548 "\t" " lui $at, 0xBF80" "\n"
1549 "\t" " sw $t6, (0xBF801450 & 0xFFFF)($at)" "\n"
1550 "\t" " lui $at, 0xBF80" "\n"
1551 "\t" " lw $zero, (0xBF801450 & 0xFFFF)($at)" "\n"
1552 "\t" " mtc0 $t0, $12" "\n"
1556 "\t" ".set pop" "\n"
1560 "\t" ".set push" "\n"
1561 "\t" ".set noat" "\n"
1562 "\t" ".set noreorder" "\n"
1563 "\t" ".global SetCacheCtrl" "\n"
1564 "\t" "SetCacheCtrl:" "\n"
1565 "\t" " mfc0 $t0, $12" "\n"
1567 "\t" " lui $t4, %hi(SetCacheCtrl_inner)" "\n"
1568 "\t" " addiu $t4, $t4, %lo(SetCacheCtrl_inner)" "\n"
1569 "\t" " lui $at, (0xA0000000 >> 16)" "\n"
1570 "\t" " or $t4, $t4, $at" "\n"
1572 "\t" "SetCacheCtrl_inner:" "\n"
1573 "\t" " mtc0 $zero, $12" "\n"
1575 "\t" " lui $at, (0xFFFE0130 >> 16)" "\n"
1576 "\t" " sw $a0, (0xFFFE0130 & 0xFFFF)($at)" "\n"
1577 "\t" " lui $at, (0xFFFE0130 >> 16)" "\n"
1578 "\t" " lw $zero, (0xFFFE0130 & 0xFFFF)($at)" "\n"
1580 "\t" " mtc0 $t0, $12" "\n"
1584 "\t" ".set pop" "\n"
ModuleInfo_t * image_info