ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
loadfile.c
Go to the documentation of this file.
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # (C)2001, Gustavo Scotti (gustavo@scotti.com)
7 # (c) 2003 Marcus R. Brown (mrbrown@0xd6.org)
8 # Licenced under Academic Free License version 2.0
9 # Review ps2sdk README & LICENSE files for further details.
10 */
11 
18 #include <tamtypes.h>
19 #include <ps2lib_err.h>
20 #include <kernel.h>
21 #include <sifrpc.h>
22 #include <string.h>
23 
24 #include <loadfile.h>
25 #include <iopheap.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 
30  union {
32  int result;
33  } p;
34  int type;
35  union {
36  u8 b;
37  u16 s;
38  u32 l;
39  } val;
40 } ALIGNED(16);
41 
42 extern int _iop_reboot_count;
44 extern int _lf_init;
45 
46 int _SifLoadElfPart(const char *path, const char *secname, t_ExecData *data, int fno);
47 int _SifLoadModuleBuffer(void *ptr, int arg_len, const char *args, int *modres);
48 
49 #if defined(F_SifLoadFileInit)
51 int _lf_init = 0;
52 
53 int SifLoadFileInit()
54 {
55  int res;
56  static int _rb_count = 0;
57  if(_rb_count != _iop_reboot_count)
58  {
59  _rb_count = _iop_reboot_count;
60  memset(&_lf_cd, 0, sizeof _lf_cd);
61  _lf_init = 0;
62  }
63 
64  if (_lf_init)
65  return 0;
66 
67  SifInitRpc(0);
68 
69  while ((res = SifBindRpc(&_lf_cd, 0x80000006, 0)) >= 0 && !_lf_cd.server)
70  nopdelay();
71 
72  if (res < 0)
73  return -E_SIF_RPC_BIND;
74 
75  _lf_init = 1;
76  return 0;
77 }
78 #endif
79 
80 #if defined(F_SifLoadFileExit)
81 void SifLoadFileExit()
82 {
83  _lf_init = 0;
84  memset(&_lf_cd, 0, sizeof _lf_cd);
85 }
86 #endif
87 
88 #ifdef F__SifLoadModule
89 struct _lf_module_load_arg {
90  union {
91  int arg_len;
92  int result;
93  } p;
94  int modres;
95  char path[LF_PATH_MAX];
96  char args[LF_ARG_MAX];
97 } ALIGNED(16);
98 
99 int _SifLoadModule(const char *path, int arg_len, const char *args, int *modres,
100  int fno, int dontwait)
101 {
102  struct _lf_module_load_arg arg;
103 
104  if (SifLoadFileInit() < 0)
105  return -SCE_EBINDMISS;
106 
107  memset(&arg, 0, sizeof arg);
108 
109  strncpy(arg.path, path, LF_PATH_MAX - 1);
110  arg.path[LF_PATH_MAX - 1] = 0;
111 
112  if (args && arg_len) {
113  arg.p.arg_len = arg_len > LF_ARG_MAX ? LF_ARG_MAX : arg_len;
114  memcpy(arg.args, args, arg.p.arg_len);
115  } else {
116  arg.p.arg_len = 0;
117  }
118 
119  if (SifCallRpc(&_lf_cd, fno, dontwait, &arg, sizeof arg, &arg, 8, NULL, NULL) < 0)
120  return -SCE_ECALLMISS;
121 
122  if (modres)
123  *modres = arg.modres;
124 
125  return arg.p.result;
126 }
127 #endif
128 
129 #if defined(F_SifLoadModule)
130 int SifLoadModule(const char *path, int arg_len, const char *args)
131 {
132  return _SifLoadModule(path, arg_len, args, NULL, LF_F_MOD_LOAD, 0);
133 }
134 #endif
135 
136 #if defined(F_SifLoadStartModule)
137 int SifLoadStartModule(const char *path, int arg_len, const char *args, int *mod_res)
138 {
139  return _SifLoadModule(path, arg_len, args, mod_res, LF_F_MOD_LOAD, 0);
140 }
141 #endif
142 
143 #if defined(F_SifLoadModuleEncrypted)
144 int SifLoadModuleEncrypted(const char *path, int arg_len, const char *args)
145 {
146  return _SifLoadModule(path, arg_len, args, NULL, LF_F_MG_MOD_LOAD, 0);
147 }
148 #endif
149 
150 #ifdef F_SifStopModule
151 struct _lf_module_stop_arg {
152  union {
153  int id;
154  int result;
155  } p;
156  union {
157  int arg_len;
158  int modres;
159  } q;
160  char dummy[LF_PATH_MAX];
161  char args[LF_ARG_MAX];
162 } ALIGNED(16);
163 
164 int SifStopModule(int id, int arg_len, const char *args, int *mod_res)
165 {
166  struct _lf_module_stop_arg arg;
167 
168  if (SifLoadFileInit() < 0)
169  return -SCE_EBINDMISS;
170 
171  arg.p.id = id;
172 
173  if (args && arg_len) {
174  arg.q.arg_len = arg_len > LF_ARG_MAX ? LF_ARG_MAX : arg_len;
175  memcpy(arg.args, args, arg.q.arg_len);
176  } else {
177  arg.q.arg_len = 0;
178  }
179 
180  if (SifCallRpc(&_lf_cd, LF_F_MOD_STOP, 0, &arg, sizeof arg, &arg, 8, NULL, NULL) < 0)
181  return -SCE_ECALLMISS;
182 
183  if (mod_res)
184  *mod_res = arg.q.modres;
185 
186  return arg.p.result;
187 }
188 #endif
189 
190 #ifdef F_SifUnloadModule
191 union _lf_module_unload_arg {
192  int id;
193  int result;
194 } ALIGNED(16);
195 
196 int SifUnloadModule(int id)
197 {
198  union _lf_module_unload_arg arg;
199 
200  if (SifLoadFileInit() < 0)
201  return -SCE_EBINDMISS;
202 
203  arg.id = id;
204 
205  if (SifCallRpc(&_lf_cd, LF_F_MOD_UNLOAD, 0, &arg, sizeof arg, &arg, 4, NULL, NULL) < 0)
206  return -SCE_ECALLMISS;
207 
208  return arg.result;
209 }
210 #endif
211 
212 #ifdef F_SifSearchModuleByName
213 struct _lf_search_module_by_name_arg {
214  int id;
215  int dummy1;
216  char name[LF_PATH_MAX];
217  char dummy2[LF_ARG_MAX];
218 } ALIGNED(16);
219 
220 int SifSearchModuleByName(const char * name)
221 {
222  struct _lf_search_module_by_name_arg arg;
223  if (SifLoadFileInit() < 0)
224  return -SCE_EBINDMISS;
225 
226  strncpy(arg.name, name, LF_PATH_MAX - 1);
227  arg.name[LF_PATH_MAX - 1] = 0;
228 
229  if (SifCallRpc(&_lf_cd, LF_F_SEARCH_MOD_BY_NAME, 0, &arg, sizeof arg, &arg, 4, NULL, NULL) < 0)
230  return -SCE_ECALLMISS;
231 
232  return arg.id;
233 }
234 #endif
235 
236 #ifdef F_SifSearchModuleByAddress
237 struct _lf_search_module_by_address_arg {
238  union {
239  const void *ptr;
240  int id;
241  } p;
242 } ALIGNED(16);
243 
244 int SifSearchModuleByAddress(const void *ptr)
245 {
246  struct _lf_search_module_by_address_arg arg;
247  if (SifLoadFileInit() < 0)
248  return -SCE_EBINDMISS;
249 
250  arg.p.ptr = ptr;
251 
252  if (SifCallRpc(&_lf_cd, LF_F_SEARCH_MOD_BY_ADDRESS, 0, &arg, sizeof arg, &arg, 4, NULL, NULL) < 0)
253  return -SCE_ECALLMISS;
254 
255  return arg.p.id;
256 }
257 #endif
258 
259 #ifdef F__SifLoadElfPart
260 struct _lf_elf_load_arg {
261  u32 epc;
262  u32 gp;
263  char path[LF_PATH_MAX];
264  char secname[LF_ARG_MAX];
265 } ALIGNED(16);
266 
267 int _SifLoadElfPart(const char *path, const char *secname, t_ExecData *data, int fno)
268 {
269  struct _lf_elf_load_arg arg;
270 
271  if (SifLoadFileInit() < 0)
272  return -SCE_EBINDMISS;
273 
274  strncpy(arg.path, path, LF_PATH_MAX - 1);
275  strncpy(arg.secname, secname, LF_ARG_MAX - 1);
276  arg.path[LF_PATH_MAX - 1] = 0;
277  arg.secname[LF_ARG_MAX - 1] = 0;
278 
279  if (SifCallRpc(&_lf_cd, fno, 0, &arg, sizeof arg, &arg,
280  sizeof(t_ExecData), NULL, NULL) < 0)
281  return -SCE_ECALLMISS;
282 
283  if (arg.epc != 0)
284  {
285  data->epc = arg.epc;
286  data->gp = arg.gp;
287 
288  return 0;
289  } else
290  return -SCE_ELOADMISS;
291 }
292 #endif
293 
294 #if defined(F_SifLoadElfPart)
295 int SifLoadElfPart(const char *path, const char *secname, t_ExecData *data)
296 {
297  return _SifLoadElfPart(path, secname, data, LF_F_ELF_LOAD);
298 }
299 #endif
300 
301 #if defined(F_SifLoadElf)
302 int SifLoadElf(const char *path, t_ExecData *data)
303 {
304  u32 secname = 0x6c6c61; /* "all" */
305  return _SifLoadElfPart(path, (char *)&secname, data, LF_F_ELF_LOAD);
306 }
307 #endif
308 
309 #if defined(F_SifLoadElfEncrypted)
310 int SifLoadElfEncrypted(const char *path, t_ExecData *data)
311 {
312  u32 secname = 0x6c6c61; /* "all" */
313  return _SifLoadElfPart(path, (char *)&secname, data, LF_F_MG_ELF_LOAD);
314 }
315 #endif
316 
317 #if defined(F_SifIopSetVal)
318 int SifIopSetVal(u32 iop_addr, int val, int type)
319 {
320  struct _lf_iop_val_arg arg;
321 
322  if (SifLoadFileInit() < 0)
323  return -SCE_EBINDMISS;
324 
325  switch (type) {
326  case LF_VAL_BYTE:
327  arg.val.b = (u8)(val & 0xff);
328  break;
329  case LF_VAL_SHORT:
330  arg.val.s = (u16)(val & 0xffff);
331  break;
332  case LF_VAL_LONG:
333  arg.val.l = val;
334  break;
335  default:
336  return -E_LIB_INVALID_ARG;
337  }
338 
339  arg.p.iop_addr = iop_addr;
340  arg.type = type;
341 
342  if (SifCallRpc(&_lf_cd, LF_F_SET_ADDR, 0, &arg, sizeof arg, &arg, 4,
343  NULL, NULL) < 0)
344  return -SCE_ECALLMISS;
345 
346  return arg.p.result;
347 }
348 #endif
349 
350 #if defined(F_SifIopGetVal)
351 int SifIopGetVal(u32 iop_addr, void *val, int type)
352 {
353  struct _lf_iop_val_arg arg;
354 
355  if (SifLoadFileInit() < 0)
356  return -SCE_EBINDMISS;
357 
358  arg.p.iop_addr = iop_addr;
359  arg.type = type;
360 
361  if (SifCallRpc(&_lf_cd, LF_F_GET_ADDR, 0, &arg, sizeof arg, &arg, 4,
362  NULL, NULL) < 0)
363  return -SCE_ECALLMISS;
364 
365  if (val) {
366  switch (type) {
367  case LF_VAL_BYTE:
368  *(u8 *)val = (u8)arg.p.result & 0xff;
369  break;
370  case LF_VAL_SHORT:
371  *(u16 *)val = (u16)arg.p.result & 0xffff;
372  break;
373  case LF_VAL_LONG:
374  *(u32 *)val = arg.p.result;
375  break;
376  }
377  }
378 
379  return 0;
380 }
381 #endif
382 
383 #ifdef F__SifLoadModuleBuffer
384 struct _lf_module_buffer_load_arg {
385  union {
386  void *ptr;
387  int result;
388  } p;
389  union {
390  int arg_len;
391  int modres;
392  } q;
393  char unused[LF_PATH_MAX];
394  char args[LF_ARG_MAX];
395 } ALIGNED(16);
396 
397 int _SifLoadModuleBuffer(void *ptr, int arg_len, const char *args, int *modres)
398 {
399  struct _lf_module_buffer_load_arg arg;
400 
401  if (SifLoadFileInit() < 0)
402  return -SCE_EBINDMISS;
403 
404  memset(&arg, 0, sizeof arg);
405 
406  arg.p.ptr = ptr;
407  if (args && arg_len) {
408  arg.q.arg_len = arg_len > LF_ARG_MAX ? LF_ARG_MAX : arg_len;
409  memcpy(arg.args, args, arg.q.arg_len);
410  } else {
411  arg.q.arg_len = 0;
412  }
413 
414  if (SifCallRpc(&_lf_cd, LF_F_MOD_BUF_LOAD, 0, &arg, sizeof arg, &arg, 8,
415  NULL, NULL) < 0)
416  return -SCE_ECALLMISS;
417 
418  if (modres)
419  *modres = arg.q.modres;
420 
421  return arg.p.result;
422 }
423 #endif
424 
425 #if defined(F_SifLoadModuleBuffer)
426 int SifLoadModuleBuffer(void *ptr, int arg_len, const char *args)
427 {
428  return _SifLoadModuleBuffer(ptr, arg_len, args, NULL);
429 }
430 #endif
431 
432 #if defined(F_SifLoadStartModuleBuffer)
433 int SifLoadStartModuleBuffer(void *ptr, int arg_len, const char *args, int *mod_res)
434 {
435  return _SifLoadModuleBuffer(ptr, arg_len, args, mod_res);
436 }
437 #endif
438 
439 #if defined(F_SifExecModuleBuffer)
440 int SifExecModuleBuffer(void *ptr, u32 size, u32 arg_len, const char *args, int *mod_res)
441 {
442  SifDmaTransfer_t dmat;
443  void *iop_addr;
444  int res;
445  unsigned int qid;
446 
447  /* Round the size up to the nearest 16 bytes. */
448  size = (size + 15) & -16;
449 
450  if (!(iop_addr = SifAllocIopHeap(size)))
451  return -E_IOP_NO_MEMORY;
452 
453  dmat.src = ptr;
454  dmat.dest = iop_addr;
455  dmat.size = size;
456  dmat.attr = 0;
457  SifWriteBackDCache(ptr, size);
458  qid = SifSetDma(&dmat, 1);
459 
460  if (!qid)
461  return -1; // should have a better error here...
462 
463  while(SifDmaStat(qid) >= 0);
464 
465  res = _SifLoadModuleBuffer(iop_addr, arg_len, args, mod_res);
466  SifFreeIopHeap(iop_addr);
467 
468  return res;
469 }
470 #endif
471 
472 #if defined(F_SifExecModuleFile)
473 int SifExecModuleFile(const char *path, u32 arg_len, const char *args, int *mod_res)
474 {
475  void *iop_addr;
476  int res, size, fd;
477 
478  if ((fd = open(path, O_RDONLY)) < 0)
479  return fd;
480 
481  if ((size = lseek(fd, 0, SEEK_END)) < 0)
482  return size;
483 
484  close(fd);
485 
486  if (!(iop_addr = SifAllocIopHeap(size)))
487  return -E_IOP_NO_MEMORY;
488 
489  if ((res = SifLoadIopHeap(path, iop_addr)) < 0) {
490  SifFreeIopHeap(iop_addr);
491  return res;
492  }
493 
494  res = _SifLoadModuleBuffer(iop_addr, arg_len, args, mod_res);
495  SifFreeIopHeap(iop_addr);
496 
497  return res;
498 }
499 #endif
#define gp
Definition: as_reg_compat.h:84
int SifLoadModuleEncrypted(const char *path, int arg_len, const char *args)
int SifLoadModule(const char *path, int arg_len, const char *args)
int SifLoadStartModuleBuffer(void *ptr, int arg_len, const char *args, int *mod_res)
void SifLoadFileExit(void)
int SifLoadElf(const char *path, t_ExecData *data)
int SifLoadElfPart(const char *path, const char *secname, t_ExecData *data)
int SifLoadElfEncrypted(const char *path, t_ExecData *data)
int SifExecModuleBuffer(void *ptr, u32 size, u32 arg_len, const char *args, int *mod_res)
int SifLoadFileInit(void)
int SifIopSetVal(u32 iop_addr, int val, int type)
int SifExecModuleFile(const char *path, u32 arg_len, const char *args, int *mod_res)
int _SifLoadModule(const char *path, int arg_len, const char *args, int *modres, int fno, int dontwait)
int SifIopGetVal(u32 iop_addr, void *val, int type)
int SifLoadModuleBuffer(void *ptr, int arg_len, const char *args)
int SifLoadStartModule(const char *path, int arg_len, const char *args, int *mod_res)
void * SifAllocIopHeap(int size)
int SifFreeIopHeap(void *addr)
int SifLoadIopHeap(const char *path, void *addr)
u32 SifSetDma(SifDmaTransfer_t *sdd, s32 len)
static void nopdelay(void)
Definition: kernel.h:141
#define ALIGNED(x)
Definition: kernel.h:50
s32 SifDmaStat(u32 id)
u32 data
Definition: libmouse.c:36
SifRpcClientData_t _lf_cd
int _SifLoadModuleBuffer(void *ptr, int arg_len, const char *args, int *modres)
int _lf_init
int _iop_reboot_count
int _SifLoadElfPart(const char *path, const char *secname, t_ExecData *data, int fno)
#define LF_PATH_MAX
Definition: loadfile.h:21
int SifSearchModuleByName(const char *name)
#define SCE_ELOADMISS
Definition: loadfile.h:63
@ LF_VAL_BYTE
Definition: loadfile.h:25
@ LF_VAL_LONG
Definition: loadfile.h:27
@ LF_VAL_SHORT
Definition: loadfile.h:26
#define LF_ARG_MAX
Definition: loadfile.h:22
int SifStopModule(int id, int arg_len, const char *args, int *mod_res)
@ LF_F_ELF_LOAD
Definition: loadfile.h:32
@ LF_F_SET_ADDR
Definition: loadfile.h:34
@ LF_F_MOD_UNLOAD
Definition: loadfile.h:43
@ LF_F_SEARCH_MOD_BY_NAME
Definition: loadfile.h:45
@ LF_F_GET_ADDR
Definition: loadfile.h:35
@ LF_F_MG_MOD_LOAD
Definition: loadfile.h:37
@ LF_F_MOD_BUF_LOAD
Definition: loadfile.h:40
@ LF_F_MOD_STOP
Definition: loadfile.h:42
@ LF_F_MG_ELF_LOAD
Definition: loadfile.h:38
@ LF_F_MOD_LOAD
Definition: loadfile.h:31
@ LF_F_SEARCH_MOD_BY_ADDRESS
Definition: loadfile.h:46
#define SCE_ECALLMISS
Definition: loadfile.h:61
#define SCE_EBINDMISS
Definition: loadfile.h:59
int SifUnloadModule(int id)
int SifSearchModuleByAddress(const void *ptr)
@ E_LIB_INVALID_ARG
Definition: ps2lib_err.h:78
@ E_IOP_NO_MEMORY
Definition: ps2lib_err.h:64
@ E_SIF_RPC_BIND
Definition: ps2lib_err.h:86
s32 result
Definition: rpc_client.c:23
void SifWriteBackDCache(void *ptr, int size)
void SifInitRpc(int mode)
int SifBindRpc(SifRpcClientData_t *client, int rpc_number, int mode)
int SifCallRpc(SifRpcClientData_t *client, int rpc_number, int mode, void *send, int ssize, void *receive, int rsize, SifRpcEndFunc_t end_function, void *end_param)
void * dest
Definition: sifdma.h:55
void * src
Definition: sifdma.h:54
struct t_SifRpcServerData * server
Definition: sifrpc.h:142
union _lf_iop_val_arg::@19 val
union _lf_iop_val_arg::@18 p
#define NULL
Definition: tamtypes.h:91
unsigned int u32
Definition: tamtypes.h:30
unsigned short u16
Definition: tamtypes.h:24
unsigned char u8
Definition: tamtypes.h:23