Suggestion from "mgh".
[open-ps2-loader.git] / ee_core / src / modmgr.c
blob0bec81ac2e43d7cb124115c9ce1b6887430e6844
1 /*
2 Copyright 2009-2010, Ifcaro, jimmikaelkael & Polo
3 Copyright 2006-2008 Polo
4 Licenced under Academic Free License version 3.0
5 Review OpenUsbLd README & LICENSE files for further details.
7 Some parts of the code are taken from HD Project by Polo
8 */
10 #include "ee_core.h"
11 #include "modmgr.h"
12 #include "util.h"
14 void *imgdrv_irx;
15 int size_imgdrv_irx;
17 void *eesync_irx;
18 int size_eesync_irx;
20 void *cdvdman_irx;
21 int size_cdvdman_irx;
23 void *cdvdfsv_irx;
24 int size_cdvdfsv_irx;
26 void *cddev_irx;
27 int size_cddev_irx;
29 #ifdef VMC
30 void *mcemu_irx;
31 int size_mcemu_irx;
32 #endif
34 void *usbd_irx;
35 int size_usbd_irx;
37 void *ps2dev9_irx;
38 int size_ps2dev9_irx;
40 void *smstcpip_irx;
41 int size_smstcpip_irx;
43 void *smsmap_irx;
44 int size_smsmap_irx;
46 void *udptty_irx;
47 int size_udptty_irx;
49 void *ioptrap_irx;
50 int size_ioptrap_irx;
52 void *smbman_irx;
53 int size_smbman_irx;
55 static SifRpcClientData_t _lf_cd;
56 static int _lf_init = 0;
58 typedef struct {
59 void *irxaddr;
60 int irxsize;
61 } irxptr_t;
63 /*----------------------------------------------------------------------------------------*/
64 /* Init LOADFILE RPC. */
65 /*----------------------------------------------------------------------------------------*/
66 int LoadFileInit()
68 int r;
70 if (_lf_init)
71 return 0;
73 while ((r = SifBindRpc(&_lf_cd, 0x80000006, 0)) >= 0 && (!_lf_cd.server))
74 nopdelay();
76 if (r < 0)
77 return -E_SIF_RPC_BIND;
79 _lf_init = 1;
81 return 0;
85 /*----------------------------------------------------------------------------------------*/
86 /* DeInit LOADFILE RPC. */
87 /*----------------------------------------------------------------------------------------*/
88 void LoadFileExit()
90 _lf_init = 0;
91 memset(&_lf_cd, 0, sizeof(_lf_cd));
95 /*----------------------------------------------------------------------------------------*/
96 /* Load an irx module from path with waiting. */
97 /*----------------------------------------------------------------------------------------*/
98 int LoadModule(const char *path, int arg_len, const char *args)
100 struct _lf_module_load_arg arg;
102 if (LoadFileInit() < 0)
103 return -E_LIB_API_INIT;
105 memset(&arg, 0, sizeof arg);
107 strncpy(arg.path, path, LF_PATH_MAX - 1);
108 arg.path[LF_PATH_MAX - 1] = 0;
110 if ((args) && (arg_len))
112 arg.p.arg_len = arg_len > LF_ARG_MAX ? LF_ARG_MAX : arg_len;
113 memcpy(arg.args, args, arg.p.arg_len);
115 else arg.p.arg_len = 0;
117 if (SifCallRpc(&_lf_cd, LF_F_MOD_LOAD, 0x0, &arg, sizeof(arg), &arg, 8, NULL, NULL) < 0)
118 return -E_SIF_RPC_CALL;
120 return arg.p.result;
124 /*----------------------------------------------------------------------------------------*/
125 /* Load an irx module from path without waiting. */
126 /*----------------------------------------------------------------------------------------*/
127 int LoadModuleAsync(const char *path, int arg_len, const char *args)
129 struct _lf_module_load_arg arg;
131 if (LoadFileInit() < 0)
132 return -E_LIB_API_INIT;
134 memset(&arg, 0, sizeof arg);
136 strncpy(arg.path, path, LF_PATH_MAX - 1);
137 arg.path[LF_PATH_MAX - 1] = 0;
139 if ((args) && (arg_len))
141 arg.p.arg_len = arg_len > LF_ARG_MAX ? LF_ARG_MAX : arg_len;
142 memcpy(arg.args, args, arg.p.arg_len);
144 else arg.p.arg_len = 0;
146 if (SifCallRpc(&_lf_cd, LF_F_MOD_LOAD, SIF_RPC_M_NOWAIT, &arg, sizeof(arg), &arg, 8, NULL, NULL) < 0)
147 return -E_SIF_RPC_CALL;
149 return 0;
152 #ifdef VMC
153 #define IRX_NUM 11
154 #else
155 #define IRX_NUM 10
156 #endif
158 //--------------------------------------------------------------
159 void GetIrxKernelRAM(void) // load needed modules from the kernel ram
161 int n;
162 irxptr_t irxptr_tab[IRX_NUM];
164 DIntr();
165 ee_kmode_enter();
167 void *irx_tab = (void *)(*(u32 *)0x80033000);
168 memcpy(&irxptr_tab[0], irx_tab, sizeof(irxptr_tab));
170 ee_kmode_exit();
171 EIntr();
173 n = 0;
174 size_imgdrv_irx = irxptr_tab[n++].irxsize;
175 size_eesync_irx = irxptr_tab[n++].irxsize;
176 size_cdvdman_irx = irxptr_tab[n++].irxsize;
177 size_cdvdfsv_irx = irxptr_tab[n++].irxsize;
178 size_cddev_irx = irxptr_tab[n++].irxsize;
179 size_usbd_irx = irxptr_tab[n++].irxsize;
180 size_smsmap_irx = irxptr_tab[n++].irxsize;
181 size_udptty_irx = irxptr_tab[n++].irxsize;
182 size_ioptrap_irx = irxptr_tab[n++].irxsize;
183 size_smstcpip_irx = irxptr_tab[n++].irxsize;
184 #ifdef VMC
185 size_mcemu_irx = irxptr_tab[n++].irxsize;
186 #endif
188 n = 0;
189 imgdrv_irx = (void *)irxptr_tab[n++].irxaddr;
190 eesync_irx = (void *)irxptr_tab[n++].irxaddr;
191 cdvdman_irx = (void *)irxptr_tab[n++].irxaddr;
192 cdvdfsv_irx = (void *)irxptr_tab[n++].irxaddr;
193 cddev_irx = (void *)irxptr_tab[n++].irxaddr;
194 usbd_irx = (void *)irxptr_tab[n++].irxaddr;
195 smsmap_irx = (void *)irxptr_tab[n++].irxaddr;
196 udptty_irx = (void *)irxptr_tab[n++].irxaddr;
197 ioptrap_irx = (void *)irxptr_tab[n++].irxaddr;
198 smstcpip_irx = (void *)irxptr_tab[n++].irxaddr;
199 #ifdef VMC
200 mcemu_irx = (void *)irxptr_tab[n++].irxaddr;
201 #endif
204 // ------------------------------------------------------------------------
205 int LoadIRXfromKernel(void *irxkernelmem, int irxsize, int arglen, char *argv)
207 DIntr();
208 ee_kmode_enter();
210 memcpy(g_buf, irxkernelmem, irxsize);
212 ee_kmode_exit();
213 EIntr();
215 return LoadMemModule(g_buf, irxsize, arglen, argv);
218 /*----------------------------------------------------------------------------------------*/
219 /* Load an irx module from a EE buffer. */
220 /*----------------------------------------------------------------------------------------*/
221 int LoadMemModule(void *modptr, unsigned int modsize, int arg_len, const char *args)
223 SifDmaTransfer_t sifdma;
224 void *iopmem;
225 int dma_id;
227 if (LoadFileInit() < 0)
228 return -E_LIB_API_INIT;
230 /* Round the size up to the nearest 16 bytes. */
231 // modsize = (modsize + 15) & -16;
233 iopmem = SifAllocIopHeap(modsize);
234 if (iopmem == NULL) return -E_IOP_NO_MEMORY;
236 sifdma.src = modptr;
237 sifdma.dest = iopmem;
238 sifdma.size = modsize;
239 sifdma.attr = 0;
241 SifWriteBackDCache(modptr, modsize);
245 dma_id = SifSetDma(&sifdma, 1);
246 } while (!dma_id);
248 while (SifDmaStat(dma_id) >= 0) {;}
250 struct _lf_module_buffer_load_arg arg;
252 memset(&arg, 0, sizeof arg);
254 arg.p.ptr = iopmem;
255 if ((args) && (arg_len))
257 arg.q.arg_len = arg_len > LF_ARG_MAX ? LF_ARG_MAX : arg_len;
258 memcpy(arg.args, args, arg.q.arg_len);
260 else arg.q.arg_len = 0;
262 if (SifCallRpc(&_lf_cd, LF_F_MOD_BUF_LOAD, 0, &arg, sizeof(arg), &arg, 8, NULL, NULL) < 0)
263 return -E_SIF_RPC_CALL;
265 SifFreeIopHeap(iopmem);
267 return arg.p.result;
270 /*----------------------------------------------------------------------------------------*/
271 /* Load an elf file from EE buffer. */
272 /*----------------------------------------------------------------------------------------*/
273 int LoadElf(const char *path, t_ExecData *data)
275 struct _lf_elf_load_arg arg;
277 if (LoadFileInit() < 0)
278 return -E_LIB_API_INIT;
280 u32 secname = 0x6c6c61; /* "all" */
282 strncpy(arg.path, path, LF_PATH_MAX - 1);
283 strncpy(arg.secname, (char*)&secname, LF_ARG_MAX - 1);
284 arg.path[LF_PATH_MAX - 1] = 0;
285 arg.secname[LF_ARG_MAX - 1] = 0;
287 if (SifCallRpc(&_lf_cd, LF_F_ELF_LOAD, 0, &arg, sizeof arg, &arg, sizeof(t_ExecData), NULL, NULL) < 0)
288 return -E_SIF_RPC_CALL;
290 if (arg.p.result < 0)
291 return arg.p.result;
293 if (data) {
294 data->epc = arg.p.epc;
295 data->gp = arg.gp;
298 return 0;
301 /*----------------------------------------------------------------------------------------*/
302 /* Find and change a module name. */
303 /*----------------------------------------------------------------------------------------*/
304 void ChangeModuleName(const char *name, const char *newname)
306 u8 search_name[60];
307 smod_mod_info_t info;
309 if (!smod_get_next_mod(0, &info))
310 return;
312 int len = strlen(name);
314 do {
315 smem_read(info.name, search_name, sizeof(search_name));
317 if (!_memcmp(search_name, name, len)) {
318 strncpy(search_name, newname, sizeof(search_name));
319 search_name[sizeof(search_name)-1] = 0;
320 smem_write(info.name, search_name, strlen(search_name));
321 break;
323 } while (smod_get_next_mod(&info, &info));
325 FlushCache(0);
328 /*----------------------------------------------------------------------------------------*/
329 /* List modules currently loaded in the system. */
330 /*----------------------------------------------------------------------------------------*/
331 #ifdef __EESIO_DEBUG
332 void ListModules(void)
334 int c = 0;
335 smod_mod_info_t info;
336 u8 name[60];
338 if (!smod_get_next_mod(0, &info))
339 return;
340 DPRINTF("List of modules currently loaded in the system:\n");
341 do {
342 smem_read(info.name, name, sizeof name);
343 if (!(c & 1)) DPRINTF(" ");
344 DPRINTF(" %-21.21s %2d %3x%c", name, info.id, info.version, (++c & 1) ? ' ' : '\n');
345 } while (smod_get_next_mod(&info, &info));
347 #endif