491 |
bool mapped_load_elf_from_chrp(File &f, uint disp_off) |
bool mapped_load_elf_from_chrp(File &f, uint disp_off) |
492 |
{ |
{ |
493 |
String fn; |
String fn; |
494 |
PROMBOOT_OUTPUT("ELF: trying to load '%y'\n", &f.getDesc(fn)); |
PROMBOOT_OUTPUT("ELF: trying to load '%y' (CHRP)\n", &f.getDesc(fn)); |
495 |
try { |
try { |
496 |
ELF_HEADER32 hdr; |
ELF_HEADER32 hdr; |
497 |
ELF_PROGRAM_HEADER32 *phdr; |
ELF_PROGRAM_HEADER32 *phdr; |
703 |
return false; |
return false; |
704 |
} |
} |
705 |
|
|
706 |
|
uint32 entry; |
707 |
uint32 la = ELF_LOAD_ADDRESS; |
uint32 la = ELF_LOAD_ADDRESS; |
708 |
f.seek(0x2c); |
f.seek(0x2c); |
709 |
uint16 program_hdrs; |
uint16 program_hdrs; |
712 |
uint32 stack=0; |
uint32 stack=0; |
713 |
uint32 stackp=0; |
uint32 stackp=0; |
714 |
for (int i=0; i<program_hdrs; i++) { |
for (int i=0; i<program_hdrs; i++) { |
715 |
// IO_PROM_TRACE("program header %d:\n", i); |
IO_PROM_TRACE("program header %d:\n", i); |
716 |
ELF_PROGRAM_HEADER32 program_hdr; |
ELF_PROGRAM_HEADER32 program_hdr; |
717 |
f.seek(0x34+i*sizeof program_hdr); |
f.seek(0x34+i*sizeof program_hdr); |
718 |
f.readx(&program_hdr, sizeof program_hdr); |
f.readx(&program_hdr, sizeof program_hdr); |
719 |
createHostStructx(&program_hdr, sizeof program_hdr, ELF_PROGRAM_HEADER32_struct, big_endian); |
createHostStructx(&program_hdr, sizeof program_hdr, ELF_PROGRAM_HEADER32_struct, big_endian); |
720 |
uint32 pages_from_file = program_hdr.p_filesz / 4096; |
uint32 pages_from_file = program_hdr.p_filesz / 4096; |
721 |
uint32 ea = program_hdr.p_vaddr; |
uint32 ea = program_hdr.p_vaddr; |
722 |
|
ea = 0x00000000; // XXX force load to beginning of RAM |
723 |
|
entry = ea; |
724 |
sint32 vs = program_hdr.p_memsz; |
sint32 vs = program_hdr.p_memsz; |
725 |
f.seek(program_hdr.p_offset); |
f.seek(program_hdr.p_offset); |
726 |
uint32 fo = program_hdr.p_offset; |
uint32 fo = program_hdr.p_offset; |
727 |
byte page[4096]; |
byte page[4096]; |
728 |
while (pages_from_file) { |
while (pages_from_file) { |
729 |
// IO_PROM_TRACE("loading from %08x to ea:%08x (pa:%08x)\n", fo, ea, la); |
IO_PROM_TRACE("loading from %08x to ea:%08x (pa:%08x)\n", fo, ea, la); |
730 |
f.readx(page, sizeof page); |
f.readx(page, sizeof page); |
731 |
if (!init_page_create(ea, la)) return false; |
if (!init_page_create(ea, la)) return false; |
732 |
if (!ppc_dma_write(la, page, 4096)) { |
if (!ppc_dma_write(la, page, 4096)) { |
739 |
vs -= 4096; |
vs -= 4096; |
740 |
} |
} |
741 |
if (program_hdr.p_filesz % 4096) { |
if (program_hdr.p_filesz % 4096) { |
742 |
// ht_printf("loading remaining from %08x to ea:%08x (pa:%08x)\n", fo, ea, la); |
ht_printf("loading remaining from %08x to ea:%08x (pa:%08x)\n", fo, ea, la); |
743 |
f.read(page, program_hdr.p_filesz % 4096); |
f.read(page, program_hdr.p_filesz % 4096); |
744 |
if (!init_page_create(ea, la)) return false; |
if (!init_page_create(ea, la)) return false; |
745 |
if (!ppc_dma_write(la+(ea&0xfff), page, program_hdr.p_filesz % 4096)) { |
if (!ppc_dma_write(la+(ea&0xfff), page, program_hdr.p_filesz % 4096)) { |
751 |
vs -= 4096; |
vs -= 4096; |
752 |
} |
} |
753 |
while (vs > 0) { |
while (vs > 0) { |
754 |
// ht_printf("creating for ea:%08x (pa:%08x)\n", ea, la); |
ht_printf("creating for ea:%08x (pa:%08x)\n", ea, la); |
755 |
if (!init_page_create(ea, la)) return false; |
if (!init_page_create(ea, la)) return false; |
756 |
la += 4096; |
la += 4096; |
757 |
ea += 4096; |
ea += 4096; |
771 |
} |
} |
772 |
|
|
773 |
|
|
774 |
f.seek(0x18); |
IO_PROM_TRACE("starting program from PC %08x\n", entry); |
|
uint32 entry; |
|
|
f.readx(&entry, 4); |
|
|
entry = createHostInt(&entry, 4, big_endian); |
|
775 |
|
|
776 |
// turn on address translation |
// turn on address translation |
777 |
ppc_cpu_set_msr(0, MSR_IR | MSR_DR | MSR_FP); |
ppc_cpu_set_msr(0, MSR_IR | MSR_DR | MSR_FP); |