Disabling auto-refresh of game list by default, as it is causing bugs sometimes
[open-ps2-loader.git] / elfldr / elfldr.c
blob69b969a057782c1a61130c85396534b0a9830c81
1 /*
2 Copyright 2009-2010, jimmikaelkael <jimmikaelkael@wanadoo.fr>
3 Copyright 2009-2010, misfire <misfire@xploderfreax.de>
5 Licenced under Academic Free License version 3.0
6 Review OpenUsbLd README & LICENSE files for further details.
7 */
9 #include <tamtypes.h>
10 #include <kernel.h>
11 #include <stdio.h>
12 #include <iopcontrol.h>
13 #include <iopheap.h>
14 #include <loadfile.h>
15 #include <sifrpc.h>
16 #include <string.h>
18 #define GS_BGCOLOUR *((volatile unsigned long int*)0x120000E0)
20 #define ELF_MAGIC 0x464c457f
21 #define ELF_PT_LOAD 1
23 typedef struct {
24 u8 ident[16];
25 u16 type;
26 u16 machine;
27 u32 version;
28 u32 entry;
29 u32 phoff;
30 u32 shoff;
31 u32 flags;
32 u16 ehsize;
33 u16 phentsize;
34 u16 phnum;
35 u16 shentsize;
36 u16 shnum;
37 u16 shstrndx;
38 } elf_header_t;
40 typedef struct {
41 u32 type;
42 u32 offset;
43 void *vaddr;
44 u32 paddr;
45 u32 filesz;
46 u32 memsz;
47 u32 flags;
48 u32 align;
49 } elf_pheader_t;
51 #define MAX_G_ARGS 16
52 static int g_argc;
53 static char *g_argv[MAX_G_ARGS];
54 static char g_argbuf[1024];
56 static void t_loadElf(void)
58 int i, fd;
59 elf_header_t elf_header;
60 elf_pheader_t elf_pheader;
62 #ifdef DEBUG
63 GS_BGCOLOUR = 0x800080; // mid purple
64 #endif
66 ResetEE(0x7f);
68 // wipe user memory
69 for (i = 0x00100000; i < 0x02000000; i += 64) {
70 __asm__ (
71 "\tsq $0, 0(%0) \n"
72 "\tsq $0, 16(%0) \n"
73 "\tsq $0, 32(%0) \n"
74 "\tsq $0, 48(%0) \n"
75 :: "r" (i)
79 // clear scratchpad memory
80 memset((void*)0x70000000, 0, 16 * 1024);
82 #ifdef DEBUG
83 GS_BGCOLOUR = 0x008000; // mid green
84 #endif
86 // load the elf
87 fioInit();
88 fd = open(g_argv[0], O_RDONLY);
89 if (fd < 0) {
90 goto error; // can't open file, exiting...
93 // read ELF header
94 if (read(fd, &elf_header, sizeof(elf_header)) != sizeof(elf_header)) {
95 close(fd);
96 goto error; // can't read header, exiting...
99 // check ELF magic
100 if ((*(u32*)elf_header.ident) != ELF_MAGIC) {
101 close(fd);
102 goto error; // not an ELF file, exiting...
105 // copy loadable program segments to RAM
106 for (i = 0; i < elf_header.phnum; i++) {
107 lseek(fd, elf_header.phoff+(i*sizeof(elf_pheader)), SEEK_SET);
108 read(fd, &elf_pheader, sizeof(elf_pheader));
110 if (elf_pheader.type != ELF_PT_LOAD)
111 continue;
113 lseek(fd, elf_pheader.offset, SEEK_SET);
114 read(fd, elf_pheader.vaddr, elf_pheader.filesz);
116 if (elf_pheader.memsz > elf_pheader.filesz)
117 memset(elf_pheader.vaddr + elf_pheader.filesz, 0,
118 elf_pheader.memsz - elf_pheader.filesz);
121 close(fd);
123 #ifdef RESET_IOP
124 // reset IOP
125 SifInitRpc(0);
126 SifResetIop();
127 SifInitRpc(0);
129 FlushCache(0);
130 FlushCache(2);
132 // reload modules
133 SifLoadFileInit();
134 SifLoadModule("rom0:SIO2MAN", 0, NULL);
135 SifLoadModule("rom0:MCMAN", 0, NULL);
136 SifLoadModule("rom0:MCSERV", 0, NULL);
137 #endif
139 // exit services
140 fioExit();
141 SifLoadFileExit();
142 SifExitIopHeap();
143 SifExitRpc();
145 FlushCache(0);
146 FlushCache(2);
148 #ifdef DEBUG
149 GS_BGCOLOUR = 0x000000; // black
150 #endif
152 // finally, run ELF...
153 ExecPS2((void*)elf_header.entry, NULL, g_argc, g_argv);
154 error:
155 GS_BGCOLOUR = 0x808080; // gray screen: error
156 SleepThread();
159 int main(int argc, char **argv)
161 char *p = g_argbuf;
162 int i, arglen;
164 #ifdef DEBUG
165 GS_BGCOLOUR = 0x000080; // mid blue
166 #endif
168 DI();
169 ee_kmode_enter();
171 // check args count
172 g_argc = argc > MAX_G_ARGS ? MAX_G_ARGS : argc;
174 memset(g_argbuf, 0, sizeof(g_argbuf));
176 // copy args
177 g_argv[0] = p;
178 for (i = 0; i < g_argc; i++) {
179 arglen = strlen(argv[i]) + 1;
180 memcpy(p, argv[i], arglen);
181 g_argv[i + 1] = p;
182 p += arglen;
185 ee_kmode_exit();
186 EI();
188 ExecPS2(t_loadElf, NULL, 0, NULL);
190 GS_BGCOLOUR = 0xffffff; // white screen: error
191 SleepThread();
193 return 0;