PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
fileio.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright 2001-2009, ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include "irx_imports.h"
12#include "fileio-common.h"
13#include "iopheap-common.h"
14#define MODNAME "FILEIO_service"
15#ifdef _IOP
16IRX_ID(MODNAME, 1, 1);
17#endif
18// Mostly based on the module from SCE SDK 1.3.4.
19// Additions from XFILEIO from ROM version 1.1.0a have been added, but disabled.
20
21
22#ifdef DEBUG
23#define DPRINTF(x...) printf(MODNAME ": " x)
24#else
25#define DPRINTF(x...)
26#endif
27
28
29static struct _fio_read_data read_data_out __attribute__((aligned(16)));
30static void *xfer_buffer;
31static int xfer_size;
32static int fileio_rpc_tmpbuf[0x4c] __attribute__((aligned(16)));
33
34static void fileio_rpc_start_thread(void *param);
35static void heap_rpc_start_thread(void *param);
36
37int _start(int argc, char *argv[])
38{
39 int *BootMode;
40 int fileio_rpc_thread;
41 int heap_rpc_thread;
42 iop_thread_t thread_param;
43
44 FlushDcache();
45 BootMode = QueryBootMode(3);
46 if (BootMode) {
47 int iop_boot_param;
48
49 iop_boot_param = BootMode[1];
50 if ((iop_boot_param & 1) != 0) {
51 DPRINTF(" No SIF service(fileio)\n");
52 return MODULE_NO_RESIDENT_END;
53 }
54 if ((iop_boot_param & 2) != 0) {
55 DPRINTF(" No FILEIO service\n");
56 return MODULE_NO_RESIDENT_END;
57 }
58 }
60 thread_param.thread = fileio_rpc_start_thread;
61 thread_param.attr = 0x2000000;
62 thread_param.priority = 96;
63 thread_param.stacksize = 4096;
64 thread_param.option = 0;
65 fileio_rpc_thread = CreateThread(&thread_param);
66 if (fileio_rpc_thread <= 0) {
67 return MODULE_NO_RESIDENT_END;
68 }
69 StartThread(fileio_rpc_thread, 0);
70 thread_param.thread = heap_rpc_start_thread;
71 thread_param.attr = 0x2000000;
72 thread_param.priority = 96;
73 thread_param.stacksize = 2048;
74 thread_param.option = 0;
75 heap_rpc_thread = CreateThread(&thread_param);
76 if (heap_rpc_thread <= 0) {
77 return MODULE_NO_RESIDENT_END;
78 }
79 StartThread(heap_rpc_thread, 0);
80 return MODULE_RESIDENT_END;
81}
82
83static void *fileio_allocate_buffer_memory()
84{
85 int i;
86
87 i = 0;
88 xfer_size = 0x4000;
89 for (;;) {
90 xfer_buffer = AllocSysMemory(1, xfer_size, 0);
91 i += 1;
92 if (xfer_buffer) {
93 break;
94 }
95 xfer_size /= 2;
96 if (i >= 8) {
97 return xfer_buffer;
98 }
99 }
100 DPRINTF("read/write allocate memory %x\n", xfer_size);
101 return xfer_buffer;
102}
103
104static void fileio_rpc_open(struct _fio_open_arg *buffer, int length, int *outbuffer)
105{
106 if ((xfer_buffer != NULL) || ((xfer_buffer = fileio_allocate_buffer_memory()) != NULL)) {
107 int fd;
108
109 DPRINTF("open name %s flag %x data %x\n", buffer->name, buffer->mode, (u32)(buffer));
110 fd = io_open(buffer->name, buffer->mode);
111 DPRINTF("open fd = %d\n", fd);
112 *outbuffer = fd;
113 } else {
114 DPRINTF("Error:Cannot alloc r/w buffer\n");
115 *outbuffer = -1;
116 }
117}
118
119static void fileio_rpc_close(int *buffer, int length, int *outbuffer)
120{
121 *outbuffer = io_close(*buffer);
122}
123
124static void fileio_rpc_lseek(struct _fio_lseek_arg *buffer, int length, int *outbuffer)
125{
126 *outbuffer = io_lseek(buffer->p.fd, buffer->offset, buffer->whence);
127}
128
129static void fileio_rpc_read(struct _fio_read_arg *buffer, int length, int *outbuffer)
130{
131 int size;
132 int fd;
133 unsigned int ptr;
134 size_t v6;
135 int v7;
136 char *v8;
137 signed int v9;
138 signed int v10;
139 int v11;
140 int v12;
141 size_t v13;
142 int v14;
143 int v15;
144 int v16;
145 struct _fio_read_data *read_data;
147 int state;
148 void *v21;
149 void *v22;
150
151 size = buffer->size;
152 fd = buffer->fd;
153 ptr = (unsigned int)buffer->ptr;
154 v6 = 0;
155#if 0
156 if (size >= 64) {
157 if ((ptr & 0x3F) != 0) {
158 v7 = (ptr >> 6 << 6) - (ptr - 64);
159 } else {
160 v7 = 0;
161 }
162 v21 = ptr;
163 v8 = (char *)(ptr + v7);
164 v9 = ((ptr + size) >> 6 << 6) - (ptr + v7);
165 v10 = ptr + size - ((ptr + size) >> 6 << 6);
166 v22 = (ptr + size) >> 6 << 6;
167 }
168#else
169 if (size >= 16) {
170 if ((ptr & 0xF) != 0) {
171 v7 = (ptr >> 4 << 4) - (ptr - 16);
172 } else {
173 v7 = 0;
174 }
175 v21 = (void *)ptr;
176 v8 = (char *)(ptr + v7);
177 v9 = ((ptr + size) >> 4 << 4) - (ptr + v7);
178 v10 = ptr + size - ((ptr + size) >> 4 << 4);
179 v22 = (void *)((ptr + size) >> 4 << 4);
180 }
181#endif
182 else
183 {
184 v7 = size;
185 v8 = 0;
186 v9 = 0;
187 v10 = 0;
188 v21 = (void *)ptr;
189 v22 = 0;
190 }
191 v11 = 0;
192 if (v7 > 0) {
193 v12 = io_read(fd, read_data_out.buf1, v7);
194 if (v7 != v12) {
195 v7 = 0;
196 if (v12 > 0) {
197 v7 = v12;
198 }
199 v6 = v7;
200 goto LABEL_26;
201 }
202 v6 = v7;
203 }
204 if (v9 <= 0) {
205 LABEL_21:
206 if (v10 > 0) {
207 v16 = io_read(fd, read_data_out.buf2, v10);
208 if (v10 != v16) {
209 v10 = 0;
210 if (v16 > 0) {
211 v10 = v16;
212 }
213 }
214 v6 += v10;
215 }
216 } else {
217 for (;;) {
218 v13 = v9;
219 if (xfer_size < v9)
220 v13 = xfer_size;
221 while (sceSifDmaStat(v11) >= 0)
222 ;
223 v14 = io_read(fd, xfer_buffer, v13);
224 v15 = v14;
225 if (v13 != v14) {
226 break;
227 }
228 v6 += v14;
229 v9 -= v14;
230 v19.dest = v8;
231 v8 += v14;
232 v19.size = v14;
233 v19.attr = 0;
234 v19.src = xfer_buffer;
235 CpuSuspendIntr(&state);
236 v11 = sceSifSetDma(&v19, 1);
237 CpuResumeIntr(state);
238 if (v9 <= 0) {
239 goto LABEL_21;
240 }
241 }
242 if (v14 > 0) {
243 v19.dest = v8;
244 v19.size = v14;
245 v19.attr = 0;
246 v19.src = xfer_buffer;
247 CpuSuspendIntr(&state);
248 sceSifSetDma(&v19, 1);
249 v6 += v15;
250 CpuResumeIntr(state);
251 }
252 }
253LABEL_26:
254 read_data_out.size1 = v7;
255 read_data_out.size2 = v10;
256 read_data_out.dest1 = v21;
257 read_data_out.dest2 = v22;
258 v19.src = &read_data_out;
259 read_data = buffer->read_data;
260#if 0
261 v19.size = 144;
262#else
263 v19.size = 48;
264#endif
265 v19.attr = 0;
266 v19.dest = read_data;
267 CpuSuspendIntr(&state);
268 sceSifSetDma(&v19, 1);
269 CpuResumeIntr(state);
270 *outbuffer = v6;
271}
272
273static void fileio_rpc_write(struct _fio_write_arg *buffer, int length, int *outbuffer)
274{
275 u32 size;
276 s32 mis;
277 int fd;
278 int v10;
279 char *v11;
280 int v13;
282 int v15;
283
284 if (!xfer_buffer) {
285 xfer_buffer = fileio_allocate_buffer_memory();
286 if (!xfer_buffer) {
287 Kprintf("Error:Cannot alloc r/w buffer\n");
288 *outbuffer = -1;
289 return;
290 }
291 }
292 size = buffer->size;
293 v15 = 0;
294 mis = buffer->mis;
295 fd = buffer->fd;
296 if (mis > 0) {
297 int v9;
298
299 v9 = io_write(fd, buffer->aligned, mis);
300 if (v9 != mis) {
301 if (v9 > 0) {
302 v15 += v9;
303 }
304 *outbuffer = v15;
305 return;
306 }
307 v15 += v9;
308 }
309 v10 = size - mis;
310 v11 = (char *)buffer->ptr + mis;
311 if (!v10) {
312 *outbuffer = v15;
313 return;
314 }
315 for (;;) {
316 int v12;
317
318 v12 = v10;
319 if (xfer_size < v10) {
320 v12 = xfer_size;
321 }
322 sceSifGetOtherData(&v14, v11, xfer_buffer, v12, 0);
323 v13 = io_write(fd, xfer_buffer, v12);
324 v10 -= v12;
325 if (v13 != v12) {
326 break;
327 }
328 v11 += v12;
329 v15 += v12;
330 if (!v10) {
331 *outbuffer = v15;
332 return;
333 }
334 }
335 if (v13 > 0) {
336 v15 += v13;
337 }
338 *outbuffer = v15;
339}
340
341static void fileio_rpc_ioctl(struct _fio_ioctl_arg *buffer, int length, int *outbuffer)
342{
343 *outbuffer = io_ioctl(buffer->p.fd, buffer->request, buffer->data);
344}
345
346static void fileio_rpc_remove(const char *buffer, int length, int *outbuffer)
347{
348 DPRINTF("remove file %s \n", buffer);
349 *outbuffer = io_remove(buffer);
350}
351
352static void fileio_rpc_mkdir(const char *buffer, int length, int *outbuffer)
353{
354 DPRINTF("mkdir name %s \n", buffer);
355 *outbuffer = io_mkdir(buffer);
356}
357
358static void fileio_rpc_rmdir(const char *buffer, int length, int *outbuffer)
359{
360 DPRINTF("rmdir name %s \n", buffer);
361 *outbuffer = io_rmdir(buffer);
362}
363
364static void fileio_rpc_format(const char *buffer, int length, int *outbuffer)
365{
366 DPRINTF("format name %s \n", buffer);
367 *outbuffer = io_format(buffer);
368}
369
370static void fileio_rpc_adddrv(iop_io_device_t **buffer, int length, int *outbuffer)
371{
372 DPRINTF("adddrv device addr %x\n", *buffer);
373 *outbuffer = io_AddDrv(*buffer);
374}
375
376static void fileio_rpc_deldrv(const char *buffer, int length, int *outbuffer)
377{
378 DPRINTF("deldrv device name %s \n", buffer);
379 *outbuffer = io_DelDrv(buffer);
380}
381
382static void fileio_rpc_dopen(const char *buffer, int length, int *outbuffer)
383{
384 int fd;
385
386 DPRINTF("dopen name %s \n", buffer);
387 // FIXME: mode parameter is not passed
388 fd = io_dopen(buffer, 0);
389 DPRINTF("dopen fd = %d\n", fd);
390 *outbuffer = fd;
391}
392
393static void fileio_rpc_dclose(int *buffer, int length, int *outbuffer)
394{
395 *outbuffer = io_dclose(*buffer);
396}
397
398static void fileio_rpc_dread(struct _fio_dread_arg *buffer, int length, int *outbuffer)
399{
400 int v6;
402
403 v6 = io_dread(buffer->p.fd, (io_dirent_t *)fileio_rpc_tmpbuf);
404 if (v6 >= 0) {
405 v8.src = fileio_rpc_tmpbuf;
406 v8.size = 300;
407 v8.attr = 0;
408 v8.dest = (void *)buffer->buf;
409 if (!sceSifSetDma(&v8, 1)) {
410 v6 = -1;
411 }
412 }
413 *outbuffer = v6;
414}
415
416static void fileio_rpc_getstat(struct _fio_getstat_arg *buffer, int length, int *outbuffer)
417{
418 int v6;
420
421 v6 = io_getstat(buffer->name, (io_stat_t *)fileio_rpc_tmpbuf);
422 if (v6 >= 0) {
423 v8.src = fileio_rpc_tmpbuf;
424 v8.size = 40;
425 v8.attr = 0;
426 v8.dest = (void *)buffer->p.result;
427 if (!sceSifSetDma(&v8, 1)) {
428 v6 = -1;
429 }
430 }
431 *outbuffer = v6;
432}
433
434static void fileio_rpc_chstat(struct _fio_chstat_arg *buffer, int length, int *outbuffer)
435{
436 *outbuffer = io_chstat(buffer->name, &buffer->stat, buffer->p.cbit);
437}
438
439static int fileio_rpc_outbuf[0x4] __attribute__((aligned(16)));
440
441static int *fileio_rpc_service_handler(int fno, void *buffer, int length)
442{
443 switch (fno) {
444 case FIO_F_OPEN:
445 fileio_rpc_open((struct _fio_open_arg *)buffer, length, fileio_rpc_outbuf);
446 break;
447 case FIO_F_CLOSE:
448 fileio_rpc_close((int *)buffer, length, fileio_rpc_outbuf);
449 break;
450 case FIO_F_READ:
451 fileio_rpc_read((struct _fio_read_arg *)buffer, length, fileio_rpc_outbuf);
452 break;
453 case FIO_F_WRITE:
454 fileio_rpc_write((struct _fio_write_arg *)buffer, length, fileio_rpc_outbuf);
455 break;
456 case FIO_F_LSEEK:
457 fileio_rpc_lseek((struct _fio_lseek_arg *)buffer, length, fileio_rpc_outbuf);
458 break;
459 case FIO_F_IOCTL:
460 fileio_rpc_ioctl((struct _fio_ioctl_arg *)buffer, length, fileio_rpc_outbuf);
461 break;
462 case FIO_F_REMOVE:
463 fileio_rpc_remove((const char *)buffer, length, fileio_rpc_outbuf);
464 // NOTE: in the original version, there was a missing break here which caused it to fall through to mkdir
465 break;
466 case FIO_F_MKDIR:
467 fileio_rpc_mkdir((const char *)buffer, length, fileio_rpc_outbuf);
468 break;
469 case FIO_F_RMDIR:
470 fileio_rpc_rmdir((const char *)buffer, length, fileio_rpc_outbuf);
471 break;
472 case FIO_F_DOPEN:
473 fileio_rpc_dopen((const char *)buffer, length, fileio_rpc_outbuf);
474 break;
475 case FIO_F_DCLOSE:
476 fileio_rpc_dclose((int *)buffer, length, fileio_rpc_outbuf);
477 break;
478 case FIO_F_DREAD:
479 fileio_rpc_dread((struct _fio_dread_arg *)buffer, length, fileio_rpc_outbuf);
480 break;
481 case FIO_F_GETSTAT:
482 fileio_rpc_getstat((struct _fio_getstat_arg *)buffer, length, fileio_rpc_outbuf);
483 break;
484 case FIO_F_CHSTAT:
485 fileio_rpc_chstat((struct _fio_chstat_arg *)buffer, length, fileio_rpc_outbuf);
486 break;
487 case FIO_F_FORMAT:
488 fileio_rpc_format((const char *)buffer, length, fileio_rpc_outbuf);
489 break;
490 case FIO_F_ADDDRV:
491 fileio_rpc_adddrv((iop_io_device_t **)buffer, length, fileio_rpc_outbuf);
492 break;
493 case FIO_F_DELDRV:
494 fileio_rpc_deldrv((const char *)buffer, length, fileio_rpc_outbuf);
495 break;
496 default:
497 DPRINTF("sce_fileio: unrecognized code %x\n", fno);
498 break;
499 }
500 return fileio_rpc_outbuf;
501}
502
503static SifRpcDataQueue_t fileio_rpc_service_queue __attribute__((aligned(16)));
504static SifRpcServerData_t fileio_rpc_service_data __attribute__((aligned(16)));
505static int fileio_rpc_service_in_buf[0x112] __attribute__((aligned(16)));
506
507static void fileio_rpc_start_thread(void *param)
508{
509 (void)param;
510
511 if (!sceSifCheckInit())
512 sceSifInit();
513 DPRINTF("Multi Threaded Fileio module.(99/11/15) \n");
514 xfer_buffer = NULL;
515 sceSifInitRpc(0);
516 sceSifSetRpcQueue(&fileio_rpc_service_queue, GetThreadId());
517 sceSifRegisterRpc(
518 &fileio_rpc_service_data,
519 0x80000001,
520 (SifRpcFunc_t)fileio_rpc_service_handler,
521 fileio_rpc_service_in_buf,
522 0,
523 0,
524 &fileio_rpc_service_queue);
525 sceSifRpcLoop(&fileio_rpc_service_queue);
526}
527
528static void heap_rpc_load_iop_heap(struct _iop_load_heap_arg *buffer, int length, int *outbuffer)
529{
530 int fd;
531
532 fd = io_open(buffer->path, 1);
533 if (fd >= 0) {
534 int saved_pos;
535
536 saved_pos = io_lseek(fd, 0, 2);
537 io_lseek(fd, 0, 0);
538 io_read(fd, buffer->p.addr, saved_pos);
539 io_close(fd);
540 *outbuffer = 0;
541 } else {
542 DPRINTF("load heap :error \n");
543 *outbuffer = -1;
544 }
545}
546
547static void heap_rpc_alloc_iop_heap(int *buffer, int length, int *outbuffer)
548{
549 *outbuffer = (int)AllocSysMemory(0, *buffer, 0);
550}
551
552static void heap_rpc_free_iop_heap(void **buffer, int length, int *outbuffer)
553{
554 *outbuffer = FreeSysMemory(*buffer);
555}
556
557static int heap_rpc_outbuf[0x4] __attribute__((aligned(16)));
558
559static int *heap_rpc_service_handler(int fno, void *buffer, int length)
560{
561 switch (fno) {
562 case 1:
563 heap_rpc_alloc_iop_heap((int *)buffer, length, heap_rpc_outbuf);
564 break;
565 case 2:
566 heap_rpc_free_iop_heap((void **)buffer, length, heap_rpc_outbuf);
567 break;
568 case 3:
569 heap_rpc_load_iop_heap((struct _iop_load_heap_arg *)buffer, length, heap_rpc_outbuf);
570 break;
571 default:
572 DPRINTF("sce_iopmem: unrecognized code %x\n", fno);
573 break;
574 }
575 return heap_rpc_outbuf;
576}
577
578static SifRpcDataQueue_t heap_rpc_service_queue __attribute__((aligned(16)));
579static SifRpcServerData_t heap_rpc_service_data __attribute__((aligned(16)));
580static int heap_rpc_service_in_buf[0x40] __attribute__((aligned(16)));
581
582static void heap_rpc_start_thread(void *param)
583{
584 (void)param;
585
586 if (!sceSifCheckInit())
587 sceSifInit();
588 DPRINTF("iop heap service (99/11/03)\n");
589 sceSifInitRpc(0);
590 sceSifSetRpcQueue(&heap_rpc_service_queue, GetThreadId());
591 sceSifRegisterRpc(
592 &heap_rpc_service_data,
593 0x80000003,
594 (SifRpcFunc_t)heap_rpc_service_handler,
595 heap_rpc_service_in_buf,
596 0,
597 0,
598 &heap_rpc_service_queue);
599 sceSifRpcLoop(&heap_rpc_service_queue);
600}
601
602#if 0
603// XXX: unused code
604static void iopinfo_rpc_querybootmode(void *buffer, int length, int *outbuffer)
605{
606 int *BootMode;
607
608 BootMode = QueryBootMode(6);
609 *outbuffer = (BootMode != 0) ? (*(u16 *)BootMode & 0xFFFC) : 0x800;
610}
611
612static int iopinfo_rpc_outbuf[0x4] __attribute__((aligned(16)));
613
614static int *iopinfo_rpc_service_handler(int fno, void *buffer, int length)
615{
616 switch (fno) {
617 case 1:
618 iopinfo_rpc_querybootmode(buffer, length, iopinfo_rpc_outbuf);
619 break;
620 default:
621 DPRINTF("sce_iopinfo: unrecognized code %x\n", fno);
622 break;
623 }
624 return iopinfo_rpc_outbuf;
625}
626
627static SifRpcDataQueue_t iopinfo_rpc_service_queue __attribute__((aligned(16)));
628static SifRpcServerData_t iopinfo_rpc_service_data __attribute__((aligned(16)));
629static int iopinfo_rpc_service_in_buf[0x10] __attribute__((aligned(16)));
630
631static void iopinfo_rpc_service_start_thread(void *param)
632{
633 (void)param;
634
635 if (!sceSifCheckInit())
636 sceSifInit();
637 DPRINTF("iop infomation service (00/02/29)\n");
638 sceSifInitRpc(0);
639 sceSifSetRpcQueue(&iopinfo_rpc_service_queue, GetThreadId());
640 sceSifRegisterRpc(
641 &iopinfo_rpc_service_data,
642 0x80000007,
643 (SifRpcFunc_t)iopinfo_rpc_service_handler,
644 iopinfo_rpc_service_in_buf,
645 0,
646 0,
647 &iopinfo_rpc_service_queue);
648 sceSifRpcLoop(&iopinfo_rpc_service_queue);
649}
650#endif
int CpuEnableIntr()
Definition intrman.c:250
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205
typedef __attribute__
Definition tlbfunc.c:60