├── contrib ├── icon.sys └── PS2LINK.icn ├── bin └── IPCONFIG.DAT ├── iop ├── excepHandler.h ├── nprintf.h ├── net_fsys.h ├── cmdHandler.h ├── irx_imports.h ├── Makefile ├── ps2link.c ├── net_fio.h ├── imports.lst ├── nprintf.c ├── excepHandler.c ├── net_fsys.c ├── cmdHandler.c └── net_fio.c ├── .gitattributes ├── ee ├── ps2link.h ├── excepHandler.h ├── exceptions.h ├── cmdHandler.h ├── irx_variables.h ├── Makefile ├── r5900_regs.h ├── linkfile ├── linkfile.loadhigh ├── excepHandler.c ├── exceptions.S ├── ps2link.c ├── ps2regs.h └── cmdHandler.c ├── .editorconfig ├── .gitignore ├── Makefile ├── include ├── byteorder.h ├── globals.h └── hostlink.h ├── README.md ├── .github └── workflows │ └── compilation.yml ├── CHANGELOG ├── .clang-format ├── LICENSE └── doxy.conf /contrib/icon.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ps2dev/ps2link/HEAD/contrib/icon.sys -------------------------------------------------------------------------------- /bin/IPCONFIG.DAT: -------------------------------------------------------------------------------- 1 | 192.168.0.10 255.0.0.0 192.168.0.1 2 | # EXTRACNF = mc0:extra.cnf; 3 | -------------------------------------------------------------------------------- /contrib/PS2LINK.icn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ps2dev/ps2link/HEAD/contrib/PS2LINK.icn -------------------------------------------------------------------------------- /iop/excepHandler.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * This file is subject to the terms and conditions of the PS2Link License. 4 | * See the file LICENSE in the main directory of this distribution for more 5 | * details. 6 | */ 7 | 8 | #ifndef _EXCEPTION_H_ 9 | #define _EXCEPTION_H_ 10 | 11 | void installExceptionHandlers(void); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /ee/ps2link.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com) 4 | * Copyright (C) 2021 fjtrujy (fjtrujy@gmail.com) 5 | * This file is subject to the terms and conditions of the PS2Link License. 6 | * See the file LICENSE in the main directory of this distribution for more 7 | * details. 8 | */ 9 | 10 | #ifndef PS2LINK_H 11 | #define PS2LINK_H 12 | 13 | extern char elfName[]; 14 | 15 | #endif /* PS2LINK_H */ -------------------------------------------------------------------------------- /iop/nprintf.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com) 4 | * Copyright (C) 2021 fjtrujy (fjtrujy@gmail.com) 5 | * This file is subject to the terms and conditions of the PS2Link License. 6 | * See the file LICENSE in the main directory of this distribution for more 7 | * details. 8 | */ 9 | 10 | #ifndef NPRINTF_H 11 | #define NPRINTF_H 12 | 13 | int naplinkRpcInit(void); 14 | 15 | #endif /* NPRINTF_H */ -------------------------------------------------------------------------------- /ee/excepHandler.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * This file is subject to the terms and conditions of the PS2Link License. 4 | * See the file LICENSE in the main directory of this distribution for more 5 | * details. 6 | */ 7 | 8 | #ifndef _EXCEPTION_H_ 9 | #define _EXCEPTION_H_ 10 | 11 | void installExceptionHandlers(void); 12 | void iopException(int cause, int badvaddr, int status, int epc, u32 *regs, int repc, char *name); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /ee/exceptions.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com) 4 | * Copyright (C) 2021 fjtrujy (fjtrujy@gmail.com) 5 | * This file is subject to the terms and conditions of the PS2Link License. 6 | * See the file LICENSE in the main directory of this distribution for more 7 | * details. 8 | */ 9 | 10 | #ifndef EXCEPTION_H 11 | #define EXCEPTION_H 12 | 13 | void pkoExceptionHandler(void); 14 | 15 | #endif /* EXCEPTION_H */ -------------------------------------------------------------------------------- /iop/net_fsys.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com) 4 | * Copyright (C) 2021 fjtrujy (fjtrujy@gmail.com) 5 | * This file is subject to the terms and conditions of the PS2Link License. 6 | * See the file LICENSE in the main directory of this distribution for more 7 | * details. 8 | */ 9 | 10 | #ifndef NET_FSYS_H 11 | #define NET_FSYS_H 12 | 13 | int fsysUnmount(void); 14 | int fsysMount(void); 15 | 16 | #endif /* NET_FSYS_H */ -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig: http://EditorConfig.org 2 | 3 | # Top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | charset = utf-8 12 | 13 | # 4 space indentation 14 | [*.{c,h,js,css,html}] 15 | indent_style = space 16 | indent_size = 4 17 | 18 | # 2 space indentation 19 | [*.{json,xml,yaml,yml}] 20 | indent_style = space 21 | indent_size = 2 22 | 23 | # Tab indentation 24 | [{Makefile, linkfile}*] 25 | indent_style = tab 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE! Please use 'git ls-files -i --exclude-standard -c' 3 | # command after changing this file, to see if there are 4 | # any tracked files which get ignored after the change. 5 | # 6 | # Normal rules 7 | # 8 | .* 9 | *.a 10 | *.diff 11 | *.elf 12 | *.ELF 13 | *.erl 14 | *.exe 15 | *.irx 16 | *.map 17 | *.o 18 | *.patch 19 | *.rej 20 | *.s 21 | *.zip 22 | *.ZIP 23 | *.a 24 | 25 | # 26 | # files that we don't want to ignore 27 | # 28 | !.gitignore 29 | !.gitattributes 30 | !.github 31 | !.editorconfig 32 | !.clang-format 33 | 34 | # 35 | # Generated source files 36 | # 37 | *_irx.c -------------------------------------------------------------------------------- /ee/cmdHandler.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com) 4 | * Copyright (C) 2021 fjtrujy (fjtrujy@gmail.com) 5 | * This file is subject to the terms and conditions of the PS2Link License. 6 | * See the file LICENSE in the main directory of this distribution for more 7 | * details. 8 | */ 9 | 10 | #ifndef CMD_HANDLER_H 11 | #define CMD_HANDLER_H 12 | 13 | int initCmdRpc(void); 14 | void pkoReset(void); 15 | 16 | extern int userThreadID; 17 | extern int excepscrdump; 18 | 19 | #endif /* CMD_HANDLER_H */ -------------------------------------------------------------------------------- /iop/cmdHandler.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com) 4 | * Copyright (C) 2021 fjtrujy (fjtrujy@gmail.com) 5 | * This file is subject to the terms and conditions of the PS2Link License. 6 | * See the file LICENSE in the main directory of this distribution for more 7 | * details. 8 | */ 9 | 10 | #ifndef CMD_HANDLER_H 11 | #define CMD_HANDLER_H 12 | 13 | extern int excepscrdump; 14 | 15 | unsigned int pkoSendSifCmd(unsigned int cmd, void *src, unsigned int len); 16 | int cmdHandlerInit(void); 17 | 18 | #endif /* CMD_HANDLER_H */ -------------------------------------------------------------------------------- /iop/irx_imports.h: -------------------------------------------------------------------------------- 1 | /* 2 | * irx_imports.h - Defines all IRX imports. 3 | * 4 | * Copyright (c) 2003 Marcus R. Brown 5 | * 6 | * See the file LICENSE included with this distribution for licensing terms. 7 | */ 8 | 9 | #ifndef IOP_IRX_IMPORTS_H 10 | #define IOP_IRX_IMPORTS_H 11 | 12 | #include "irx.h" 13 | 14 | 15 | /* Please keep these in alphabetical order! */ 16 | #include "cdvdman.h" 17 | #include "intrman.h" 18 | #include "ioman.h" 19 | #include "ioptrap.h" 20 | #include "loadcore.h" 21 | #include "modload.h" 22 | #include "ps2ip.h" 23 | #include "sifcmd.h" 24 | #include "sifman.h" 25 | #include "stdio.h" 26 | #include "sysclib.h" 27 | #include "thbase.h" 28 | #include "thsemap.h" 29 | #include "poweroff.h" 30 | 31 | #endif /* IOP_IRX_IMPORTS_H */ 32 | -------------------------------------------------------------------------------- /iop/Makefile: -------------------------------------------------------------------------------- 1 | # _____ ___ ____ 2 | # ____| | ____| PSX2 OpenSource Project 3 | # | ___| |____ (C)2002, David Ryan ( Oobles@hotmail.com ) 4 | # ------------------------------------------------------------------------ 5 | 6 | # Generated automatically from Makefile.in by configure. 7 | #.SUFFIXES: .S .c .o .s .elf .irx 8 | 9 | IOP_BIN = ps2link.irx 10 | IOP_OBJS = net_fsys.o net_fio.o ps2link.o cmdHandler.o nprintf.o excepHandler.o imports.o 11 | 12 | IOP_INCS += -I../include 13 | IOP_LIBS += 14 | IOP_LDFLAGS += 15 | IOP_CFLAGS += -Werror 16 | 17 | # Enable zero-copy on fileio writes. 18 | ifeq ($(ZEROCOPY),1) 19 | IOP_CFLAGS += -DZEROCOPY 20 | endif 21 | 22 | # Enable debug mode 23 | ifeq ($(DEBUG),1) 24 | IOP_CFLAGS += -DDEBUG 25 | endif 26 | 27 | ifeq ($(PWOFFONRESET),1) 28 | IOP_CFLAGS += -DPWOFFONRESET 29 | endif 30 | 31 | 32 | all: $(IOP_BIN) 33 | 34 | clean: 35 | -rm -f $(IOP_OBJS) $(IOP_BIN) 36 | 37 | include $(PS2SDK)/Defs.make 38 | include $(PS2SDK)/samples/Makefile.iopglobal 39 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Compilation variables 2 | 3 | # Set this to 1 to enable debug mode 4 | DEBUG ?= 0 5 | 6 | # Set this to 1 to build a highloading version, 0 for normal low version 7 | LOADHIGH ?= 0 8 | 9 | # Set this to 1 to enable zero-copy on fileio writes. 10 | ZEROCOPY ?= 0 11 | 12 | # Set this to 1 to power off the ps2 when the reset button is tapped 13 | # otherwise it will try and reset ps2link 14 | PWOFFONRESET ?= 0 15 | 16 | RM=rm -f 17 | 18 | # 19 | # You shouldn't need to modify anything below this point 20 | # 21 | include $(PS2SDK)/Defs.make 22 | 23 | EE_BIN_PKD = bin/PS2LINK.ELF 24 | EE_BIN = ee/ps2link.elf 25 | 26 | all: $(EE_BIN_PKD) 27 | 28 | $(EE_BIN): ee 29 | $(EE_BIN_PKD): $(EE_BIN) 30 | ps2-packer $< $@ > /dev/null 31 | 32 | export DEBUG LOADHIGH ZEROCOPY PWOFFONRESET 33 | 34 | ee: iop 35 | $(MAKE) -C ee 36 | 37 | iop: 38 | $(MAKE) -C iop 39 | 40 | clean: 41 | $(MAKE) -C ee clean 42 | $(MAKE) -C iop clean 43 | @rm -f ee/*_irx.o ee/*_irx.c bin/*.ELF bin/*.IRX 44 | 45 | docs: 46 | doxygen doxy.conf 47 | 48 | .PHONY: iop ee 49 | -------------------------------------------------------------------------------- /ee/irx_variables.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com) 4 | * Copyright (C) 2021 fjtrujy (fjtrujy@gmail.com) 5 | * This file is subject to the terms and conditions of the PS2Link License. 6 | * See the file LICENSE in the main directory of this distribution for more 7 | * details. 8 | */ 9 | 10 | #ifndef IRX_VARIABLES_H 11 | #define IRX_VARIABLES_H 12 | 13 | extern unsigned char ps2link_irx[]; 14 | extern unsigned int size_ps2link_irx; 15 | 16 | extern unsigned char ioptrap_irx[]; 17 | extern unsigned int size_ioptrap_irx; 18 | 19 | extern unsigned char poweroff_irx[]; 20 | extern unsigned int size_poweroff_irx; 21 | 22 | extern unsigned char ps2dev9_irx[]; 23 | extern unsigned int size_ps2dev9_irx; 24 | 25 | extern unsigned char ps2ip_nm_irx[]; 26 | extern unsigned int size_ps2ip_nm_irx; 27 | 28 | extern unsigned char netman_irx[]; 29 | extern unsigned int size_netman_irx; 30 | 31 | extern unsigned char smap_irx[]; 32 | extern unsigned int size_smap_irx; 33 | 34 | extern unsigned char udptty_irx[]; 35 | extern unsigned int size_udptty_irx; 36 | 37 | #endif /* IRX_VARIABLES_H */ 38 | -------------------------------------------------------------------------------- /include/byteorder.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * This file is subject to the terms and conditions of the PS2Link License. 4 | * See the file LICENSE in the main directory of this distribution for more 5 | * details. 6 | */ 7 | 8 | #ifndef BYTEORDER_H 9 | #define BYTEORDER_H 10 | 11 | #include 12 | #include 13 | 14 | #if BYTE_ORDER == BIG_ENDIAN 15 | static inline unsigned int htonl(unsigned int x) { return x; } 16 | static inline unsigned short htons(unsigned short x) { return x; } 17 | #else // LITTLE_ENDIAN 18 | static unsigned int htonl(unsigned int x) 19 | { 20 | return ((x & 0xff) << 24) | 21 | ((x & 0xff00) << 8) | 22 | ((x & 0xff0000) >> 8) | 23 | ((x & 0xff000000) >> 24); 24 | } 25 | 26 | static inline unsigned short htons(unsigned short x) 27 | { 28 | return ((x & 0xff) << 8) | ((x & 0xff00) >> 8); 29 | } 30 | #endif 31 | 32 | #define ntohl htonl 33 | #define ntohs htons 34 | 35 | #define IP4_ADDR(ipaddr, a, b, c, d) (ipaddr)->s_addr = htonl(((u32)(a & 0xff) << 24) | ((u32)(b & 0xff) << 16) | ((u32)(c & 0xff) << 8) | (u32)(d & 0xff)) 36 | 37 | #endif /* BYTEORDER_H */ 38 | -------------------------------------------------------------------------------- /iop/ps2link.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * This file is subject to the terms and conditions of the PS2Link License. 4 | * See the file LICENSE in the main directory of this distribution for more 5 | * details. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "excepHandler.h" 17 | #include "net_fsys.h" 18 | #include "cmdHandler.h" 19 | #include "nprintf.h" 20 | 21 | #define MODNAME "ps2link" 22 | IRX_ID(MODNAME, 1, 8); 23 | 24 | //////////////////////////////////////////////////////////////////////// 25 | // main 26 | // start threads & init rpc & filesys 27 | int _start(int argc, char **argv) 28 | { 29 | FlushDcache(); 30 | CpuEnableIntr(); 31 | 32 | sceCdInit(1); 33 | sceCdStop(); 34 | 35 | SifInitRpc(0); 36 | 37 | fsysMount(); 38 | printf("host: mounted\n"); 39 | cmdHandlerInit(); 40 | printf("IOP cmd thread started\n"); 41 | naplinkRpcInit(); 42 | printf("Naplink thread started\n"); 43 | 44 | installExceptionHandlers(); 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /include/globals.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com) 4 | * Copyright (C) 2021 fjtrujy (fjtrujy@gmail.com) 5 | * This file is subject to the terms and conditions of the PS2Link License. 6 | * See the file LICENSE in the main directory of this distribution for more 7 | * details. 8 | */ 9 | 10 | #ifndef GLOBALS_H 11 | #define GLOBALS_H 12 | 13 | #ifdef DEBUG 14 | #define dbgprintf(args...) printf("[PS2Link] " args) 15 | #define dbgscr_printf(args...) scr_printf(args) 16 | #else 17 | #define dbgprintf(args...) \ 18 | do { \ 19 | } while (0) 20 | #define dbgscr_printf(args...) \ 21 | do { \ 22 | } while (0) 23 | #endif 24 | 25 | // DEFAULT IPCONFIG IF FILE CONFIG CAN NOT BE READ 26 | //////////////////////////////////////////////////////////////////////// 27 | 28 | #define DEFAULT_IP "192.168.1.10" 29 | #define DEFAULT_NETMASK "255.255.255.0" 30 | #define DEFAULT_GW "192.168.1.0" 31 | //////////////////////////////////////////////////////////////////////// 32 | 33 | // Globals 34 | extern void __start(void); 35 | extern int _end; 36 | 37 | #endif /* GLOBALS_H */ 38 | -------------------------------------------------------------------------------- /iop/net_fio.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com) 4 | * This file is subject to the terms and conditions of the PS2Link License. 5 | * See the file LICENSE in the main directory of this distribution for more 6 | * details. 7 | */ 8 | 9 | #ifndef _NETFIO_H_ 10 | #define _NETFIO_H_ 11 | 12 | #include 13 | 14 | int pko_file_serv(void *arg); 15 | int pko_recv_bytes(int fd, char *buf, int bytes); 16 | int pko_accept_pkt(int fd, char *buf, int len, int pkt_type); 17 | int pko_open_file(char *path, int flags); 18 | int pko_close_file(int fd); 19 | int pko_read_file(int fd, char *buf, int length); 20 | int pko_write_file(int fd, char *buf, int length); 21 | int pko_lseek_file(int fd, unsigned int offset, int whence); 22 | void pko_close_socket(void); 23 | void pko_close_fsys(void); 24 | int pko_remove(char *name); 25 | int pko_mkdir(char *name, int mode); 26 | int pko_rmdir(char *name); 27 | int pko_open_dir(char *path); 28 | int pko_read_dir(int fd, void *buf); 29 | int pko_close_dir(int fd); 30 | int pko_get_stat(const char *name, io_stat_t *stat); 31 | 32 | /* 33 | * Don't want printfs to broadcast in case more than 1 ps2 on the same network, so at 34 | * connect time, the remote PC's IP is stored here and used as destination for printfs. 35 | */ 36 | extern unsigned int remote_pc_addr; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /iop/imports.lst: -------------------------------------------------------------------------------- 1 | stdio_IMPORTS_start 2 | I_printf 3 | stdio_IMPORTS_end 4 | 5 | sysclib_IMPORTS_start 6 | I_memset 7 | I_memcpy 8 | I_strlen 9 | I_strncpy 10 | sysclib_IMPORTS_end 11 | 12 | thsemap_IMPORTS_start 13 | I_CreateSema 14 | I_SignalSema 15 | I_WaitSema 16 | I_DeleteSema 17 | thsemap_IMPORTS_end 18 | 19 | thbase_IMPORTS_start 20 | I_CreateThread 21 | I_DeleteThread 22 | I_StartThread 23 | I_GetThreadId 24 | I_ExitDeleteThread 25 | thbase_IMPORTS_end 26 | 27 | ioman_IMPORTS_start 28 | I_open 29 | I_close 30 | I_AddDrv 31 | I_DelDrv 32 | ioman_IMPORTS_end 33 | 34 | ps2ip_IMPORTS_start 35 | I_lwip_send 36 | I_lwip_sendto 37 | I_lwip_socket 38 | I_lwip_listen 39 | I_lwip_recv 40 | I_lwip_recvfrom 41 | I_lwip_close 42 | I_lwip_bind 43 | I_lwip_accept 44 | ps2ip_IMPORTS_end 45 | 46 | sifcmd_IMPORTS_start 47 | I_sceSifInitRpc 48 | I_sceSifSetRpcQueue 49 | I_sceSifRegisterRpc 50 | I_sceSifRpcLoop 51 | sifcmd_IMPORTS_end 52 | 53 | sifman_IMPORTS_start 54 | I_sceSifSetDma 55 | sifman_IMPORTS_end 56 | 57 | intrman_IMPORTS_start 58 | I_CpuEnableIntr 59 | I_CpuSuspendIntr 60 | I_CpuResumeIntr 61 | intrman_IMPORTS_end 62 | 63 | loadcore_IMPORTS_start 64 | I_FlushDcache 65 | loadcore_IMPORTS_end 66 | 67 | modload_IMPORTS_start 68 | I_LoadStartModule 69 | modload_IMPORTS_end 70 | 71 | cdvdman_IMPORTS_start 72 | I_sceCdInit 73 | I_sceCdStop 74 | cdvdman_IMPORTS_end 75 | 76 | ioptrap_IMPORTS_start 77 | I_set_exception_handler 78 | ioptrap_IMPORTS_end 79 | 80 | poweroff_IMPORTS_start 81 | I_SetPowerButtonHandler 82 | I_PoweroffShutdown 83 | poweroff_IMPORTS_end 84 | -------------------------------------------------------------------------------- /ee/Makefile: -------------------------------------------------------------------------------- 1 | EE_BIN = ps2link.elf 2 | EE_OBJS = ps2link.o cmdHandler.o excepHandler.o exceptions.o 3 | EE_INCS += -I../include 4 | 5 | # This is for the sbv patch 6 | EE_LIBS += -lpatches -ldebug 7 | 8 | # IRX libs 9 | IRX_FILES += ioptrap.irx ps2dev9.irx poweroff.irx 10 | IRX_FILES += ps2ip.irx netman.irx smap.irx udptty.irx 11 | IRX_FILES += ps2link.irx 12 | EE_OBJS += $(IRX_FILES:.irx=_irx.o) ps2ip_nm_irx.o 13 | 14 | # Compile with -Werror 15 | EE_CFLAGS += -Werror 16 | 17 | # This is to enable the debug mode into ps2link 18 | ifeq ($(DEBUG),1) 19 | EE_CFLAGS += -DDEBUG -g 20 | else 21 | EE_CFLAGS += -Os 22 | EE_CFLAGS += -fdata-sections -ffunction-sections 23 | endif 24 | 25 | ifeq ($(DEBUG),1) 26 | EE_LDFLAGS += -g 27 | else 28 | EE_LDFLAGS += -s 29 | EE_LDFLAGS += -Wl,--gc-sections 30 | endif 31 | EE_LDFLAGS += -Wl,-Map,ps2link.map 32 | 33 | # This is to read the closest tag version 34 | APP_VERSION := $(shell git describe --tags --abbrev=0) 35 | EE_CFLAGS += -DAPP_VERSION=\"$(APP_VERSION)\" 36 | 37 | # Use NEWLIB NANO for making smaller binaries 38 | NEWLIB_NANO = 1 39 | 40 | # Use custom linkfile 41 | ifeq ($(LOADHIGH),1) 42 | EE_LINKFILE = linkfile.loadhigh 43 | else 44 | EE_LINKFILE = linkfile 45 | endif 46 | 47 | all: $(EE_BIN) 48 | 49 | clean: 50 | -rm -f $(EE_OBJS) $(EE_BIN) 51 | 52 | # IRX files 53 | # Special rule for ps2ip-nm.irx becasue - aren't valid 54 | ps2ip_nm_irx.c: 55 | $(PS2SDK)/bin/bin2c $(PS2SDK)/iop/irx/ps2ip-nm.irx $@ ps2ip_nm_irx 56 | # Special rule for local ps2link.irx 57 | ps2link_irx.c: 58 | $(PS2SDK)/bin/bin2c ../iop/ps2link.irx $@ ps2link_irx 59 | %_irx.c: 60 | $(PS2SDK)/bin/bin2c $(PS2SDK)/iop/irx/$*.irx $@ $*_irx 61 | 62 | 63 | include $(PS2SDK)/Defs.make 64 | include $(PS2SDK)/samples/Makefile.eeglobal_cpp 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ps2link 2 | 3 | [![CI](https://github.com/ps2dev/ps2link/workflows/CI/badge.svg)](https://github.com/ps2dev/ps2link/actions?query=workflow%3ACI) 4 | 5 | PS2Link (C) 2003 Tord Lindstrom (pukko@home.se) 6 | (C) 2003,2004 adresd (adresd_ps2dev@yahoo.com) 7 | (C) 2003,2004,2005 Khaled (khaled@w-arts.com) 8 | (C) 2019,2020,2021 fjtrujy (fjtrujy@gmail.com) 9 | 10 | ## **ATTENTION** 11 | 12 | If you are confused on how to start developing for PS2, see the 13 | [getting started](https://ps2dev.github.io/#getting-started) section on 14 | the ps2dev main page. 15 | 16 | ## Overview 17 | 18 | Please read the file LICENSE regarding PS2Link licensing. 19 | 20 | PS2Link is a 'bootloader' which, used together with an Ethernet driver and 21 | a TCP/IP stack, enables you to download and execute software on your PS2. 22 | 23 | It is designed to run from memory card, cdrom or host drives. 24 | 25 | It loads all IRX's at startup and IPCONFIG.DAT for the network settings. 26 | The IRX's and the IPCONFIG.DAT should be in the directory which PS2LINK is loaded from. 27 | 28 | ## Required modules 29 | 30 | `PS2Link` requires the following IRX modules: 31 | 32 | PS2LINK.IRX from: ps2link 33 | PS2DEV9.IRX ps2sdk 34 | PS2IP-NM.IRX ps2sdk 35 | NETMAN.IRX ps2sdk 36 | SMAP.IRX ps2sdk 37 | IOPTRAP.IRX ps2sdk 38 | POWEROFF.IRX ps2sdk 39 | UDPTTY.IRX ps2sdk 40 | 41 | ## Compilation 42 | 43 | Building `ps2link` just requires project `PS2SDK`. 44 | 45 | For building against ps2sdk make sure `PS2SDK` is set to your ps2sdk release 46 | dir. 47 | 48 | make clean all 49 | 50 | Credit for the icon logo goes to Revolt from `ps2dev`. 51 | 52 | NOTES + WARNINGS: 53 | IPCONFIG.DAT FILENAME SHOULD BE UPPERCASE. 54 | 55 | IPCONFIG.DAT uses the following format: 56 | PS2IPADDRESS NETMASK GATEWAYIP 57 | seperated by a single space. 58 | 59 | ## Community 60 | 61 | Links for discussion and chat are available 62 | [here](https://ps2dev.github.io/#community). 63 | -------------------------------------------------------------------------------- /iop/nprintf.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * This file is subject to the terms and conditions of the PS2Link License. 4 | * See the file LICENSE in the main directory of this distribution for more 5 | * details. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | //////////////////////////////////////////////////////////////////////// 18 | #define NPM_PUTS 0x01 19 | #define RPC_NPM_USER 0x014d704e 20 | 21 | //////////////////////////////////////////////////////////////////////// 22 | static void * 23 | naplinkRpcHandler(int cmd, void *buffer, int size) 24 | { 25 | // Only supports npmPrintf of course 26 | switch (cmd) { 27 | case NPM_PUTS: 28 | printf(buffer); 29 | break; 30 | default: 31 | printf("unknown npm rpc call\n"); 32 | } 33 | 34 | return buffer; 35 | } 36 | 37 | //////////////////////////////////////////////////////////////////////// 38 | static SifRpcServerData_t server __attribute((aligned(16))); 39 | static SifRpcDataQueue_t queue __attribute((aligned(16))); 40 | static unsigned char rpc_buffer[512] __attribute((aligned(16))); 41 | 42 | static void 43 | napThread(void *arg) 44 | { 45 | int pid; 46 | 47 | SifInitRpc(0); 48 | pid = GetThreadId(); 49 | SifSetRpcQueue(&queue, pid); 50 | SifRegisterRpc(&server, RPC_NPM_USER, naplinkRpcHandler, 51 | rpc_buffer, 0, 0, &queue); 52 | SifRpcLoop(&queue); // Never exits 53 | ExitDeleteThread(); 54 | } 55 | //////////////////////////////////////////////////////////////////////// 56 | int naplinkRpcInit(void) 57 | { 58 | struct _iop_thread th_attr; 59 | int ret; 60 | int pid; 61 | 62 | th_attr.attr = 0x02000000; 63 | th_attr.option = 0; 64 | th_attr.thread = napThread; 65 | th_attr.stacksize = 0x800; 66 | th_attr.priority = 79; 67 | 68 | pid = CreateThread(&th_attr); 69 | if (pid < 0) { 70 | printf("IOP: napRpc createThread failed %d\n", pid); 71 | return -1; 72 | } 73 | 74 | ret = StartThread(pid, 0); 75 | if (ret < 0) { 76 | printf("IOP: napRpc startThread failed %d\n", ret); 77 | DeleteThread(pid); 78 | return -1; 79 | } 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /.github/workflows/compilation.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - "*" 7 | tags: 8 | - v* 9 | pull_request: 10 | repository_dispatch: 11 | types: [run_build] 12 | workflow_dispatch: {} 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | container: ghcr.io/ps2dev/ps2-packer:latest 18 | strategy: 19 | matrix: 20 | version: [[default, 0], [highloading, 1]] 21 | 22 | steps: 23 | - name: Install dependencies 24 | run: | 25 | apk add build-base git 26 | 27 | - uses: actions/checkout@v4 28 | - name: Compile project 29 | run: | 30 | make -j $(getconf _NPROCESSORS_ONLN) clean 31 | make -j $(getconf _NPROCESSORS_ONLN) LOADHIGH=${{ matrix.version[1] }} 32 | 33 | - name: Get short SHA 34 | id: slug 35 | run: | 36 | printf '%s\n' "sha8=$(printf '%s\n' ${GITHUB_SHA} | cut -c1-8)" >> $GITHUB_OUTPUT 37 | 38 | - name: Extract tag name 39 | if: startsWith(github.ref, 'refs/tags/') 40 | run: | 41 | echo "DOCKER_TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV 42 | 43 | - name: Compress & Rename bin folder 44 | run: | 45 | mv bin/ ps2link/ 46 | mv contrib/icon.sys ps2link/icon.sys 47 | mv contrib/PS2LINK.icn ps2link/PS2LINK.icn 48 | tar -zcvf ps2link-${{ steps.slug.outputs.sha8 }}-${{ matrix.version[0] }}.tar.gz ps2link 49 | 50 | - name: Upload artifacts 51 | uses: actions/upload-artifact@v4 52 | with: 53 | name: ps2link-${{ steps.slug.outputs.sha8 }}-${{ matrix.version[0] }} 54 | path: ps2link-${{ steps.slug.outputs.sha8 }}-${{ matrix.version[0] }}.tar.gz 55 | 56 | - name: Upload uncompressd artifacts 57 | uses: actions/upload-artifact@v4 58 | with: 59 | name: ps2link-uncompressed-${{ steps.slug.outputs.sha8 }}-${{ matrix.version[0] }} 60 | path: ee/ps2link.elf 61 | 62 | release: 63 | needs: [build] 64 | runs-on: ubuntu-latest 65 | if: startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/master' 66 | steps: 67 | - name: Download all artifacts 68 | uses: actions/download-artifact@v4 69 | with: 70 | path: ps2link 71 | 72 | - name: Create pre-release 73 | if: github.ref == 'refs/heads/master' 74 | uses: marvinpinto/action-automatic-releases@latest 75 | with: 76 | repo_token: ${{ secrets.GITHUB_TOKEN }} 77 | prerelease: true 78 | automatic_release_tag: latest 79 | title: Development build 80 | files: ps2link/**/*.tar.gz 81 | 82 | - name: Create Tagged Release Draft 83 | if: startsWith(github.ref, 'refs/tags/v') 84 | uses: marvinpinto/action-automatic-releases@latest 85 | with: 86 | repo_token: ${{ secrets.GITHUB_TOKEN }} 87 | prerelease: false 88 | draft: true 89 | automatic_release_tag: RenameMe 90 | files: ps2link/**/*.tar.gz 91 | -------------------------------------------------------------------------------- /ee/r5900_regs.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------ 2 | // File: regs.h 3 | // Author: Tony Saveski, t_saveski@yahoo.com 4 | // Notes: Playstation 2 Register Definitions 5 | //------------------------------------------------------------------------ 6 | #ifndef R5900_REGS_H 7 | #define R5900_REGS_H 8 | 9 | // MIPS CPU Registsers 10 | #define zero $0 // Always 0 11 | #define at $1 // Assembler temporary 12 | #define v0 $2 // Function return 13 | #define v1 $3 // 14 | #define a0 $4 // Function arguments 15 | #define a1 $5 16 | #define a2 $6 17 | #define a3 $7 18 | #define t0 $8 // Temporaries. No need 19 | #define t1 $9 // to preserve in your 20 | #define t2 $10 // functions. 21 | #define t3 $11 22 | #define t4 $12 23 | #define t5 $13 24 | #define t6 $14 25 | #define t7 $15 26 | #define s0 $16 // Saved Temporaries. 27 | #define s1 $17 // Make sure to restore 28 | #define s2 $18 // to original value 29 | #define s3 $19 // if your function 30 | #define s4 $20 // changes their value. 31 | #define s5 $21 32 | #define s6 $22 33 | #define s7 $23 34 | #define t8 $24 // More Temporaries. 35 | #define t9 $25 36 | #define k0 $26 // Reserved for Kernel 37 | #define k1 $27 38 | #define gp $28 // Global Pointer 39 | #define sp $29 // Stack Pointer 40 | #define fp $30 // Frame Pointer 41 | #define ra $31 // Function Return Address 42 | 43 | // COP0 44 | #define Index $0 // Index into the TLB array 45 | #define Random $1 // Randomly generated index into the TLB array 46 | #define EntryLo0 $2 // Low-order portion of the TLB entry for.. 47 | #define EntryLo1 $3 // Low-order portion of the TLB entry for 48 | #define Context $4 // Pointer to page table entry in memory 49 | #define PageMask $5 // Control for variable page size in TLB entries 50 | #define Wired $6 // Controls the number of fixed ("wired") TLB entries 51 | #define BadVAddr $8 // Address for the most recent address-related exception 52 | #define Count $9 // Processor cycle count 53 | #define EntryHi $10 // High-order portion of the TLB entry 54 | #define Compare $11 // Timer interrupt control 55 | #define Status $12 // Processor status and control 56 | #define Cause $13 // Cause of last general exception 57 | #define EPC $14 // Program counter at last exception 58 | #define PRId $15 // Processor identification and revision 59 | #define Config $16 // Configuration register 60 | #define LLAddr $17 // Load linked address 61 | #define WatchLo $18 // Watchpoint address Section 6.25 on 62 | #define WatchHi $19 // Watchpoint control 63 | #define Debug $23 // EJTAG Debug register 64 | #define DEPC $24 // Program counter at last EJTAG debug exception 65 | #define PerfCnt $25 // Performance counter interface 66 | #define ErrCtl $26 // Parity/ECC error control and status 67 | #define CacheErr $27 // Cache parity error control and status 68 | #define TagLo $28 // Low-order portion of cache tag interface 69 | #define TagHi $29 // High-order portion of cache tag interface 70 | #define ErrorPC $30 // Program counter at last error 71 | #define DEASVE $31 // EJTAG debug exception save register 72 | 73 | #endif // R5900_REGS_H 74 | -------------------------------------------------------------------------------- /ee/linkfile: -------------------------------------------------------------------------------- 1 | /* 2 | # _____ ___ ____ ___ ____ 3 | # ____| | ____| | | |____| 4 | # | ___| |____ ___| ____| | \ PS2DEV Open Source Project. 5 | #----------------------------------------------------------------------- 6 | # Copyright 2001-2004, 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 | # Linkfile script for ee-ld 11 | */ 12 | 13 | ENTRY(__start); 14 | 15 | MEMORY { 16 | bios : ORIGIN = 0x00000000, LENGTH = 592K /* 0x00000000 - 0x00094000: BIOS memory & patched area */ 17 | bram : ORIGIN = 0x00094000, LENGTH = 432K /* 0x00094000 - 0x00100000: BIOS unused memory */ 18 | gram : ORIGIN = 0x00100000, LENGTH = 31M /* 0x00100000 - 0x02000000: GAME memory */ 19 | 20 | high : ORIGIN = 0x01ee8000, LENGTH = 1120K /* 0x01ee8000 - 0x02000000: */ 21 | } 22 | 23 | REGION_ALIAS("MAIN_REGION", bram); 24 | 25 | END_MAIN_REGION = ORIGIN(MAIN_REGION) + LENGTH(MAIN_REGION); 26 | 27 | PHDRS { 28 | text PT_LOAD; 29 | } 30 | 31 | SECTIONS { 32 | .text : { 33 | _ftext = . ; 34 | *(.text) 35 | *(.text.*) 36 | *(.gnu.linkonce.t*) 37 | KEEP(*(.init)) 38 | KEEP(*(.fini)) 39 | QUAD(0) 40 | } >MAIN_REGION :text 41 | 42 | PROVIDE(_etext = .); 43 | PROVIDE(etext = .); 44 | 45 | /* Global/static constructors and deconstructors. */ 46 | .ctors ALIGN(16): { 47 | KEEP(*crtbegin*.o(.ctors)) 48 | KEEP(*(EXCLUDE_FILE(*crtend*.o) .ctors)) 49 | KEEP(*(SORT(.ctors.*))) 50 | KEEP(*(.ctors)) 51 | } >MAIN_REGION 52 | .dtors ALIGN(16): { 53 | KEEP(*crtbegin*.o(.dtors)) 54 | KEEP(*(EXCLUDE_FILE(*crtend*.o) .dtors)) 55 | KEEP(*(SORT(.dtors.*))) 56 | KEEP(*(.dtors)) 57 | } >MAIN_REGION 58 | 59 | .reginfo : { *(.reginfo) } >MAIN_REGION 60 | 61 | .data ALIGN(128): { 62 | _fdata = . ; 63 | *(.data) 64 | *(.data.*) 65 | *(.gnu.linkonce.d*) 66 | SORT(CONSTRUCTORS) 67 | } >MAIN_REGION 68 | 69 | /* Static data. */ 70 | .rodata ALIGN(128): { 71 | *(.rodata) 72 | *(.rodata.*) 73 | *(.gnu.linkonce.r*) 74 | } >MAIN_REGION 75 | 76 | .rdata ALIGN(128): { *(.rdata) } >MAIN_REGION 77 | .gcc_except_table ALIGN(128): { *(.gcc_except_table) } >MAIN_REGION 78 | 79 | _gp = ALIGN(128) + 0x7ff0; 80 | .lit4 ALIGN(128): { *(.lit4) } >MAIN_REGION 81 | .lit8 ALIGN(128): { *(.lit8) } >MAIN_REGION 82 | 83 | .sdata ALIGN(128): { 84 | *(.sdata) 85 | *(.sdata.*) 86 | *(.gnu.linkonce.s*) 87 | } >MAIN_REGION 88 | 89 | _edata = .; 90 | PROVIDE(edata = .); 91 | 92 | /* Uninitialized data. */ 93 | .sbss ALIGN(128) : { 94 | _fbss = . ; 95 | *(.sbss) 96 | *(.sbss.*) 97 | *(.gnu.linkonce.sb*) 98 | *(.scommon) 99 | } >MAIN_REGION 100 | 101 | .bss ALIGN(128) : { 102 | *(.bss) 103 | *(.bss.*) 104 | *(.gnu.linkonce.b*) 105 | *(COMMON) 106 | } >MAIN_REGION 107 | _end_bss = .; 108 | 109 | _end = . ; 110 | PROVIDE(end = .); 111 | 112 | .spad 0x70000000: { 113 | *(.spad) 114 | } >MAIN_REGION 115 | 116 | /* Symbols needed by crt0.c. */ 117 | /* We set a fixed stack size and the pointer for the stack, letting the remaining memory be the heap. */ 118 | PROVIDE(_stack_size = 32 * 1024); 119 | PROVIDE(_stack = END_MAIN_REGION - _stack_size); 120 | PROVIDE(_heap_size = -1); 121 | } 122 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | PS2Link (C) 2003 Tord Lindstrom (pukko@home.se) 2 | (C) 2003,2004 adresd (adresd_ps2dev@yahoo.com) 3 | (C) 2004 Lukasz Bruun (mail@lukasz.dk) 4 | (C) 2006 Drakonite (makeshift_ps2dev@123mail.org) 5 | (C) 2021 fjtrujy (fjtrujy@gmail.org) 6 | ------------------------------------------------------------------------ 7 | 8 | 2021-07-02 Version 1.80 9 | - Removed legacy function that is no longer used 10 | - Removed unused functions 11 | - Simplify logic in the startup process 12 | - Improve messages on the screen 13 | - Improve how it gets IP Config (file/default config) 14 | - Reduce the binary size 15 | - Create a specific header for IRX variables 16 | - Create global header 17 | - Create headers instead of making references with "extern ..." 18 | - Cleaning code in general 19 | 20 | 2006-02-18 Version 1.46 21 | - Added Cached Config support 22 | - Extra config disabled, at least while cached config is enabled 23 | - Some code cleanup and reordering 24 | - More consistant environment (no longer has sio2man and mcman 25 | loaded when booting from MC, assuming cached_cfg enabled) 26 | - Boots from essentially anywhere now 27 | - Some code uglyfications 28 | - Elf in bin/ is now packed using ps2-packer 29 | - Lots of version bumping from beta test versions 30 | - Other stuff 31 | 32 | 2006-01-25 Version 1.32 33 | - Cleaned up and repaired Makefiles 34 | - Disabled 'check' dependency of make dist as it seems to 35 | be broken, dist was broken anyways so it doesn't seem like 36 | check is being used 37 | - Builtin_irx made default out of svn 38 | - Bumped version for tag 39 | 40 | 2004-09-25 Version 1.30 41 | - Added IOP exception handling 42 | - Changed IPCONFIG.DAT & EXTRA.CNF a little and added better 43 | parsing code. 44 | 45 | 2004-05-24 Version 1.24 46 | - Made changes for compiling with ps2sdk, introduction of imports.lst/.h 47 | and many changes in IOP part to use ioman.h. 48 | - Set default values for irx_mod pointers and sizes for cached modules 49 | to ensure they were in .bss and not trashed on pko_reset. 50 | - Set default values for ip parameters for the same reason as above. 51 | - New command writemem 52 | - Can load irx files from a defined file in IPCONFIG.DAT 53 | - All-In-One elf (irx's embedded in the elf) build target. 54 | 55 | 2004-02-08 Version 1.23 56 | - Some new commands stop/start vu, dump mem, dump reg, gsexec 57 | 58 | 2004-02-06 Version 1.22 59 | - HOST: getdir support (so ps2 can get filelist from host:, using ioman calls) 60 | 61 | 2004-01-29 Version 1.21 62 | - Fixed Host loading (both IRX and ipconfig) - prob with reset (CLEARSPU), but runs fine. 63 | - Added sbv for prefix checking, to remove LMB for mc load. 64 | - Added screen/console exception dump selection. 65 | - Consistent IOP reset for both HOST and other FS load methods. 66 | - Removed DMS specific loading, module loading made more general. 67 | - Handles being run from ANY mc dir now. 68 | - Cleaned up highloading version. 69 | 70 | 2003-12-31 Version 1.2 71 | - Binary Release Version 72 | 73 | 2003-12-15 Version 1.1 74 | - Made compatible with ps2drv, for eth and HDD access together. 75 | 76 | 2003-05-12 Version 1.0 77 | - First release 78 | -------------------------------------------------------------------------------- /ee/linkfile.loadhigh: -------------------------------------------------------------------------------- 1 | /* 2 | # _____ ___ ____ ___ ____ 3 | # ____| | ____| | | |____| 4 | # | ___| |____ ___| ____| | \ PS2DEV Open Source Project. 5 | #----------------------------------------------------------------------- 6 | # Copyright 2001-2004, 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 | # Linkfile script for ee-ld 11 | */ 12 | 13 | ENTRY(__start); 14 | 15 | MEMORY { 16 | bios : ORIGIN = 0x00000000, LENGTH = 592K /* 0x00000000 - 0x00094000: BIOS memory & patched area */ 17 | bram : ORIGIN = 0x00094000, LENGTH = 432K /* 0x00094000 - 0x00100000: BIOS unused memory */ 18 | gram : ORIGIN = 0x00100000, LENGTH = 31M /* 0x00100000 - 0x02000000: GAME memory */ 19 | 20 | high : ORIGIN = 0x01ee8000, LENGTH = 1120K /* 0x01ee8000 - 0x02000000: */ 21 | } 22 | 23 | REGION_ALIAS("MAIN_REGION", high); 24 | 25 | END_MAIN_REGION = ORIGIN(MAIN_REGION) + LENGTH(MAIN_REGION); 26 | 27 | PHDRS { 28 | text PT_LOAD; 29 | } 30 | 31 | SECTIONS { 32 | .text : { 33 | _ftext = . ; 34 | *(.text) 35 | *(.text.*) 36 | *(.gnu.linkonce.t*) 37 | KEEP(*(.init)) 38 | KEEP(*(.fini)) 39 | QUAD(0) 40 | } >MAIN_REGION :text 41 | 42 | PROVIDE(_etext = .); 43 | PROVIDE(etext = .); 44 | 45 | /* Global/static constructors and deconstructors. */ 46 | .ctors ALIGN(16): { 47 | KEEP(*crtbegin*.o(.ctors)) 48 | KEEP(*(EXCLUDE_FILE(*crtend*.o) .ctors)) 49 | KEEP(*(SORT(.ctors.*))) 50 | KEEP(*(.ctors)) 51 | } >MAIN_REGION 52 | .dtors ALIGN(16): { 53 | KEEP(*crtbegin*.o(.dtors)) 54 | KEEP(*(EXCLUDE_FILE(*crtend*.o) .dtors)) 55 | KEEP(*(SORT(.dtors.*))) 56 | KEEP(*(.dtors)) 57 | } >MAIN_REGION 58 | 59 | .reginfo : { *(.reginfo) } >MAIN_REGION 60 | 61 | .data ALIGN(128): { 62 | _fdata = . ; 63 | *(.data) 64 | *(.data.*) 65 | *(.gnu.linkonce.d*) 66 | SORT(CONSTRUCTORS) 67 | } >MAIN_REGION 68 | 69 | /* Static data. */ 70 | .rodata ALIGN(128): { 71 | *(.rodata) 72 | *(.rodata.*) 73 | *(.gnu.linkonce.r*) 74 | } >MAIN_REGION 75 | 76 | .rdata ALIGN(128): { *(.rdata) } >MAIN_REGION 77 | .gcc_except_table ALIGN(128): { *(.gcc_except_table) } >MAIN_REGION 78 | 79 | _gp = ALIGN(128) + 0x7ff0; 80 | .lit4 ALIGN(128): { *(.lit4) } >MAIN_REGION 81 | .lit8 ALIGN(128): { *(.lit8) } >MAIN_REGION 82 | 83 | .sdata ALIGN(128): { 84 | *(.sdata) 85 | *(.sdata.*) 86 | *(.gnu.linkonce.s*) 87 | } >MAIN_REGION 88 | 89 | _edata = .; 90 | PROVIDE(edata = .); 91 | 92 | /* Uninitialized data. */ 93 | .sbss ALIGN(128) : { 94 | _fbss = . ; 95 | *(.sbss) 96 | *(.sbss.*) 97 | *(.gnu.linkonce.sb*) 98 | *(.scommon) 99 | } >MAIN_REGION 100 | 101 | .bss ALIGN(128) : { 102 | *(.bss) 103 | *(.bss.*) 104 | *(.gnu.linkonce.b*) 105 | *(COMMON) 106 | } >MAIN_REGION 107 | _end_bss = .; 108 | 109 | _end = . ; 110 | PROVIDE(end = .); 111 | 112 | .spad 0x70000000: { 113 | *(.spad) 114 | } >MAIN_REGION 115 | 116 | /* Symbols needed by crt0.c. */ 117 | /* We set a fixed stack size and the pointer for the stack, letting the remaining memory be the heap. */ 118 | PROVIDE(_stack_size = 32 * 1024); 119 | PROVIDE(_stack = END_MAIN_REGION - _stack_size); 120 | PROVIDE(_heap_size = -1); 121 | } 122 | -------------------------------------------------------------------------------- /iop/excepHandler.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2004 Lukasz Bruun (mail@lukasz.dk) 3 | * This file is subject to the terms and conditions of the PS2Link License. 4 | * See the file LICENSE in the main directory of this distribution for more 5 | * details. 6 | */ 7 | 8 | #include 9 | #include "irx_imports.h" 10 | #include "hostlink.h" 11 | #include "cmdHandler.h" 12 | 13 | #define BUFFER_SIZE sizeof(exception_frame_t) + 4 + 4 + 128 14 | 15 | u32 excep_buffer[BUFFER_SIZE / 4] __attribute__((aligned(16))); 16 | 17 | // taken from smod by mrbrown, only use one function, didn't wanna include another irx. 18 | 19 | /* Module info entry. */ 20 | typedef struct _smod_mod_info 21 | { 22 | struct _smod_mod_info *next; 23 | u8 *name; 24 | u16 version; 25 | u16 newflags; /* For modload shipped with games. */ 26 | u16 id; 27 | u16 flags; /* I believe this is where flags are kept for BIOS versions. */ 28 | u32 entry; /* _start */ 29 | u32 gp; 30 | u32 text_start; 31 | u32 text_size; 32 | u32 data_size; 33 | u32 bss_size; 34 | u32 unused1; 35 | u32 unused2; 36 | } smod_mod_info_t; 37 | 38 | 39 | smod_mod_info_t *smod_get_next_mod(smod_mod_info_t *cur_mod) 40 | { 41 | /* If cur_mod is 0, return the head of the list (IOP address 0x800). */ 42 | if (!cur_mod) { 43 | return (smod_mod_info_t *)0x800; 44 | } else { 45 | if (!cur_mod->next) 46 | return 0; 47 | else 48 | return cur_mod->next; 49 | } 50 | return 0; 51 | } 52 | 53 | char *ExceptionGetModuleName(u32 epc, u32 *r_epc) 54 | { 55 | smod_mod_info_t *mod_info = 0; 56 | 57 | while ((mod_info = smod_get_next_mod(mod_info)) != 0) { 58 | if ((epc >= mod_info->text_start) && (epc <= (mod_info->text_start + mod_info->text_size))) { 59 | if (r_epc) 60 | *r_epc = epc - mod_info->text_start; 61 | 62 | return (char *)mod_info->name; 63 | } 64 | } 65 | 66 | return 0; 67 | } 68 | 69 | static void excep_handler2(exception_frame_t *frame) 70 | { 71 | u32 r_epc; // relative epc 72 | char *module_name; 73 | u32 len; 74 | u32 *buffer = excep_buffer; 75 | 76 | module_name = ExceptionGetModuleName(frame->epc, &r_epc); 77 | 78 | len = strlen(module_name); 79 | 80 | 81 | buffer[0] = 0x0d02beba; // reverse engineering.. 82 | buffer++; 83 | 84 | memcpy(buffer, frame, BUFFER_SIZE); 85 | buffer += (sizeof(exception_frame_t) / 4); 86 | 87 | buffer[0] = r_epc; 88 | buffer[1] = len; 89 | buffer += 2; 90 | memcpy(buffer, module_name, len + 1); 91 | 92 | pkoSendSifCmd(PKO_RPC_IOPEXCEP, excep_buffer, BUFFER_SIZE); 93 | } 94 | 95 | 96 | static void excep_handler(exception_type_t type, exception_frame_t *frame) 97 | { 98 | excep_handler2(frame); // Don't know why this works, but keeps iop alive. 99 | } 100 | 101 | 102 | //////////////////////////////////////////////////////////////////////// 103 | // Installs iop exception handlers for the 'usual' exceptions.. 104 | void installExceptionHandlers(void) 105 | { 106 | s32 i; 107 | 108 | for (i = 1; i < 8; i++) 109 | set_exception_handler(i, excep_handler); 110 | 111 | for (i = 10; i < 13; i++) 112 | set_exception_handler(i, excep_handler); 113 | } 114 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | AccessModifierOffset: -4 4 | AlignAfterOpenBracket: Align 5 | AlignConsecutiveAssignments: false 6 | AlignConsecutiveBitFields: AcrossEmptyLinesAndComments 7 | AlignConsecutiveDeclarations: false 8 | AlignConsecutiveMacros: AcrossComments 9 | AlignEscapedNewlines: Left 10 | AlignOperands: Align 11 | AlignTrailingComments: true 12 | AllowAllArgumentsOnNextLine: false 13 | AllowAllConstructorInitializersOnNextLine: true 14 | AllowAllParametersOfDeclarationOnNextLine: true 15 | AllowShortBlocksOnASingleLine: Empty 16 | AllowShortCaseLabelsOnASingleLine: false 17 | AllowShortEnumsOnASingleLine: true 18 | AllowShortFunctionsOnASingleLine: All 19 | AllowShortIfStatementsOnASingleLine: Never 20 | AllowShortLambdasOnASingleLine: Empty 21 | AllowShortLoopsOnASingleLine: false 22 | AlwaysBreakAfterReturnType: None 23 | AlwaysBreakBeforeMultilineStrings: false 24 | AlwaysBreakTemplateDeclarations: true 25 | BinPackArguments: true 26 | BinPackParameters: true 27 | BitFieldColonSpacing : Both 28 | BreakBeforeBraces: Custom 29 | BraceWrapping: 30 | AfterCaseLabel: false 31 | AfterClass: true 32 | AfterControlStatement: false 33 | AfterEnum: false 34 | AfterFunction: true 35 | AfterNamespace: true 36 | AfterObjCDeclaration: false 37 | AfterStruct: true 38 | AfterUnion: true 39 | AfterExternBlock: false 40 | BeforeCatch: false 41 | BeforeElse: false 42 | BeforeLambdaBody: true 43 | BeforeWhile: false 44 | IndentBraces: false 45 | SplitEmptyFunction: true 46 | SplitEmptyRecord: true 47 | SplitEmptyNamespace: true 48 | BreakBeforeBinaryOperators: None 49 | BreakBeforeConceptDeclarations: true 50 | BreakBeforeTernaryOperators: false 51 | BreakConstructorInitializers: BeforeComma 52 | BreakStringLiterals: true 53 | ColumnLimit: 0 54 | CommentPragmas: '^ (IWYU pragma:|NOLINT)' 55 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 56 | ConstructorInitializerIndentWidth: 4 57 | ContinuationIndentWidth: 4 58 | Cpp11BracedListStyle: true 59 | DeriveLineEnding: true 60 | DerivePointerAlignment: false 61 | DisableFormat: false 62 | EmptyLineBeforeAccessModifier: LogicalBlock 63 | FixNamespaceComments: true 64 | ForEachMacros: [] 65 | IncludeBlocks: Preserve 66 | IndentExternBlock: NoIndent 67 | IndentCaseBlocks: false 68 | IndentCaseLabels: true 69 | IndentGotoLabels: true 70 | IndentWidth: 4 71 | IndentWrappedFunctionNames: false 72 | KeepEmptyLinesAtTheStartOfBlocks: true 73 | MacroBlockBegin: '' 74 | MacroBlockEnd: '' 75 | MaxEmptyLinesToKeep: 3 76 | NamespaceIndentation: None 77 | ObjCBlockIndentWidth: 2 78 | ObjCSpaceAfterProperty: false 79 | ObjCSpaceBeforeProtocolList: true 80 | PenaltyBreakAssignment: 80 81 | PenaltyBreakBeforeFirstCallParameter: 19 82 | PenaltyBreakComment: 300 83 | PenaltyBreakFirstLessLess: 120 84 | PenaltyBreakString: 1000 85 | PenaltyBreakTemplateDeclaration: 80 86 | PenaltyExcessCharacter: 1000000 87 | PenaltyIndentedWhitespace: 80 88 | PenaltyReturnTypeOnItsOwnLine: 60 89 | PointerAlignment: Right 90 | # uncomment below when clang >13 will be out 91 | # IndentPPDirectives: AfterHash 92 | # PPIndentWidth: 1 93 | ReflowComments: true 94 | SortIncludes: false 95 | SpaceAfterCStyleCast: false 96 | SpaceAfterLogicalNot: false 97 | SpaceAroundPointerQualifiers: Default 98 | SpaceBeforeAssignmentOperators: true 99 | SpaceBeforeCaseColon: false 100 | SpaceBeforeCpp11BracedList: true 101 | SpaceBeforeInheritanceColon: false 102 | SpaceBeforeParens: ControlStatements 103 | SpaceBeforeRangeBasedForLoopColon: true 104 | SpaceBeforeSquareBrackets: false 105 | SpaceInEmptyBlock: false 106 | SpaceInEmptyParentheses: false 107 | SpacesBeforeTrailingComments: 1 108 | SpacesInAngles: false 109 | SpacesInConditionalStatement: false 110 | SpacesInContainerLiterals: true 111 | SpacesInCStyleCastParentheses: false 112 | SpacesInParentheses: false 113 | SpacesInSquareBrackets: false 114 | Standard: Cpp11 115 | TabWidth: 4 116 | UseTab: Never 117 | -------------------------------------------------------------------------------- /ee/excepHandler.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com) 4 | * This file is subject to the terms and conditions of the PS2Link License. 5 | * See the file LICENSE in the main directory of this distribution for more 6 | * details. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "excepHandler.h" 15 | #include "cmdHandler.h" 16 | #include "exceptions.h" 17 | #include "globals.h" 18 | 19 | //////////////////////////////////////////////////////////////////////// 20 | typedef union __attribute__((packed)) 21 | { 22 | unsigned int uint128 __attribute__((mode(TI))); 23 | unsigned long uint64[2]; 24 | } eeReg; 25 | 26 | //////////////////////////////////////////////////////////////////////// 27 | static const unsigned char regName[32][5] = 28 | { 29 | "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 30 | "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 31 | "t8", "t9", "s0", "s1", "s2", "s3", "s4", "s5", 32 | "s6", "s7", "k0", "k1", "gp", "sp", "fp", "ra"}; 33 | 34 | static char codeTxt[14][24] = 35 | { 36 | "Interrupt", "TLB modification", "TLB load/inst fetch", "TLB store", 37 | "Address load/inst fetch", "Address store", "Bus error (instr)", 38 | "Bus error (data)", "Syscall", "Breakpoint", "Reserved instruction", 39 | "Coprocessor unusable", "Arithmetic overflow", "Trap"}; 40 | 41 | char _exceptionStack[8 * 1024] __attribute__((aligned(16))); 42 | eeReg _savedRegs[32 + 4] __attribute__((aligned(16))); 43 | 44 | //////////////////////////////////////////////////////////////////////// 45 | // The 'ee exception handler', only dumps registers to console or screen atm 46 | void pkoDebug(int cause, int badvaddr, int status, int epc, eeReg *regs) 47 | { 48 | int i; 49 | int code; 50 | static void (*excpPrintf)(const char *, ...); 51 | 52 | FlushCache(0); 53 | FlushCache(2); 54 | 55 | if (userThreadID) { 56 | TerminateThread(userThreadID); 57 | DeleteThread(userThreadID); 58 | } 59 | 60 | code = cause & 0x7c; 61 | 62 | if (excepscrdump) { 63 | init_scr(); 64 | excpPrintf = scr_printf; 65 | } else 66 | excpPrintf = (void *)printf; 67 | 68 | excpPrintf("\n\n EE Exception handler: %s exception\n\n", 69 | codeTxt[code >> 2]); 70 | 71 | excpPrintf(" Cause %08X BadVAddr %08X Status %08X EPC %08X\n\n", 72 | cause, badvaddr, status, epc); 73 | 74 | for (i = 0; i < 32 / 2; i++) { 75 | excpPrintf("%4s: %016lX%016lX %4s: %016lX%016lX\n", 76 | regName[i], regs[i].uint64[1], regs[i].uint64[0], 77 | regName[i + 16], regs[i + 16].uint64[1], regs[i + 16].uint64[0]); 78 | } 79 | excpPrintf("\n"); 80 | SleepThread(); 81 | } 82 | 83 | //////////////////////////////////////////////////////////////////////// 84 | // The 'iop exception handler', only dumps registers to console or screen atm 85 | 86 | void iopException(int cause, int badvaddr, int status, int epc, u32 *regs, int repc, char *name) 87 | { 88 | int i; 89 | int code; 90 | static void (*excpPrintf)(const char *, ...); 91 | 92 | FlushCache(0); 93 | FlushCache(2); 94 | 95 | if (userThreadID) { 96 | TerminateThread(userThreadID); 97 | DeleteThread(userThreadID); 98 | } 99 | 100 | code = cause & 0x7c; 101 | 102 | if (excepscrdump) { 103 | init_scr(); 104 | excpPrintf = scr_printf; 105 | } else 106 | excpPrintf = (void *)printf; 107 | 108 | excpPrintf("\n\n IOP Exception handler: %s exception\n\n", 109 | codeTxt[code >> 2]); 110 | 111 | excpPrintf(" Module Name \"%s\" Relative EPC %08X\n\n", 112 | name, repc); 113 | 114 | 115 | excpPrintf(" Cause %08X BadVAddr %08X Status %08X EPC %08X\n\n", 116 | cause, badvaddr, status, epc); 117 | 118 | for (i = 0; i < 32 / 4; i++) { 119 | excpPrintf(" %4s: %08X %4s: %08X %4s: %08X %4s: %08X\n", 120 | regName[i], regs[i], regName[i + 8], regs[i + 8], 121 | regName[i + 16], regs[i + 16], regName[i + 24], regs[i + 24]); 122 | } 123 | 124 | excpPrintf("\n"); 125 | 126 | 127 | 128 | SleepThread(); 129 | } 130 | 131 | 132 | //////////////////////////////////////////////////////////////////////// 133 | // Installs ee exception handlers for the 'usual' exceptions and iop 134 | // exception callback 135 | void installExceptionHandlers(void) 136 | { 137 | int i; 138 | 139 | // Skip exception #8 (syscall) & 9 (breakpoint) 140 | for (i = 1; i < 4; i++) { 141 | SetVTLBRefillHandler(i, pkoExceptionHandler); 142 | } 143 | for (i = 4; i < 8; i++) { 144 | SetVCommonHandler(i, pkoExceptionHandler); 145 | } 146 | for (i = 10; i < 14; i++) { 147 | SetVCommonHandler(i, pkoExceptionHandler); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /ee/exceptions.S: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * This file is subject to the terms and conditions of the PS2Link License. 4 | * See the file LICENSE in the main directory of this distribution for more 5 | * details. 6 | */ 7 | 8 | # ASM exception handlers 9 | 10 | #include "r5900_regs.h" 11 | 12 | .set noat 13 | .set noreorder 14 | 15 | 16 | .text 17 | .p2align 4 18 | 19 | .global _savedRegs 20 | 21 | .global pkoStepBP 22 | .ent pkoStepBP 23 | pkoStepBP: 24 | # Should check for cause in cop0 Cause reg 25 | # If Bp, increase EPC (DO NOT PUT 'break' in a branch delay slot!!!) 26 | mfc0 k0, EPC # cop0 EPC 27 | addiu k0, k0, 4 # Step over breakpoint 28 | mtc0 k0, EPC 29 | sync.p 30 | eret 31 | .end pkoStepBP 32 | 33 | 34 | # Save all user regs 35 | # Save HI/LO, SR, BadVAddr, Cause, EPC, ErrorEPC, 36 | # ShiftAmount, cop0: $24, $25 37 | # Save float regs?? 38 | # Set EPC to debugger 39 | # Set stack to 'exception stack' 40 | # eret 41 | .global pkoExceptionHandler 42 | .ent pkoExceptionHandler 43 | pkoExceptionHandler: 44 | la k0, _savedRegs 45 | sq $0, 0x00(k0) 46 | sq at, 0x10(k0) 47 | sq v0, 0x20(k0) 48 | sq v1, 0x30(k0) 49 | sq a0, 0x40(k0) 50 | sq a1, 0x50(k0) 51 | sq a2, 0x60(k0) 52 | sq a3, 0x70(k0) 53 | sq t0, 0x80(k0) 54 | sq t1, 0x90(k0) 55 | sq t2, 0xa0(k0) 56 | sq t3, 0xb0(k0) 57 | sq t4, 0xc0(k0) 58 | sq t5, 0xd0(k0) 59 | sq t6, 0xe0(k0) 60 | sq t7, 0xf0(k0) 61 | sq t8, 0x100(k0) 62 | sq t9, 0x110(k0) 63 | sq s0, 0x120(k0) 64 | sq s1, 0x130(k0) 65 | sq s2, 0x140(k0) 66 | sq s3, 0x150(k0) 67 | sq s4, 0x160(k0) 68 | sq s5, 0x170(k0) 69 | sq s6, 0x180(k0) 70 | sq s7, 0x190(k0) 71 | # sq k0, 0x1a0(k0) # $k0 72 | sq zero, 0x1a0(k0) # zero instead 73 | sq k1, 0x1b0(k0) # $k1 74 | sq gp, 0x1c0(k0) 75 | sq sp, 0x1d0(k0) # sp 76 | sq fp, 0x1e0(k0) 77 | sq ra, 0x1f0(k0) # $ra 78 | 79 | pmfhi t0 # HI 80 | pmflo t1 # LO 81 | sq t0, 0x200(k0) 82 | sq t1, 0x210(k0) 83 | 84 | mfc0 t0, BadVAddr # Cop0 state regs 85 | mfc0 t1, Status 86 | sw t0, 0x220(k0) 87 | sw t1, 0x224(k0) 88 | 89 | mfc0 t0, Cause 90 | mfc0 t1, EPC 91 | sw t0, 0x228(k0) 92 | sw t1, 0x22c(k0) 93 | 94 | # Kernel saves these two also.. 95 | mfc0 t0, DEPC 96 | mfc0 t1, PerfCnt 97 | sw t0, 0x230(k0) 98 | sw t1, 0x234(k0) 99 | 100 | mfsa t0 101 | sw t0, 0x238(k0) 102 | 103 | # Use our own stack.. 104 | la sp, _exceptionStack+0x2000-16 105 | la gp, _gp # Use exception handlers _gp 106 | 107 | # Return from exception and start 'debugger' 108 | mfc0 a0, Cause # arg0 109 | mfc0 a1, BadVAddr 110 | mfc0 a2, Status 111 | mfc0 a3, EPC 112 | addu t0, zero, k0 # arg4 = registers 113 | move t1, sp 114 | la k0, pkoDebug 115 | mtc0 k0, EPC # eret return address 116 | sync.p 117 | mfc0 k0, Status # check this out.. 118 | li v0, 0xfffffffe 119 | and k0, v0 120 | mtc0 k0, Status 121 | sync.p 122 | nop 123 | nop 124 | nop 125 | nop 126 | eret 127 | nop 128 | .end pkoExceptionHandler 129 | 130 | 131 | 132 | # Put EE in kernel mode 133 | # Restore all user regs etc 134 | # Restore PC? & Stack ptr 135 | # Restore interrupt sources 136 | # Jump to EPC 137 | .ent pkoReturnFromDebug 138 | .global pkoReturnFromDebug 139 | pkoReturnFromDebug: 140 | 141 | lui t1, 0x1 142 | _disable: 143 | di 144 | sync 145 | mfc0 t0, Status 146 | and t0, t1 147 | beqz t0, _disable 148 | nop 149 | 150 | la k0, _savedRegs 151 | 152 | lq t0, 0x200(k0) 153 | lq t1, 0x210(k0) 154 | pmthi t0 # HI 155 | pmtlo t1 # LO 156 | 157 | lw t0, 0x220(k0) 158 | lw t1, 0x224(k0) 159 | mtc0 t0, BadVAddr 160 | mtc0 t1, Status 161 | 162 | lw t0, 0x228(k0) 163 | lw t1, 0x22c(k0) 164 | mtc0 t0, Cause 165 | mtc0 t1, EPC 166 | 167 | # Kernel saves these two also.. 168 | lw t0, 0x230(k0) 169 | lw t1, 0x234(k0) 170 | mtc0 t0, DEPC 171 | mtc0 t1, PerfCnt 172 | 173 | # Shift Amount reg 174 | lw t0, 0x238(k0) 175 | mtsa t0 176 | 177 | 178 | # ori t2, 0xff 179 | # sw t2, 0(k1) 180 | 181 | # lq $0, 0x00(k0) 182 | lq $1, 0x10(k0) 183 | lq $2, 0x20(k0) 184 | lq $3, 0x30(k0) 185 | lq $4, 0x40(k0) 186 | lq $5, 0x50(k0) 187 | lq $6, 0x60(k0) 188 | lq $7, 0x70(k0) 189 | lq $8, 0x80(k0) 190 | lq $9, 0x90(k0) 191 | lq $10, 0xa0(k0) 192 | lq $11, 0xb0(k0) 193 | lq $12, 0xc0(k0) 194 | lq $13, 0xd0(k0) 195 | lq $14, 0xe0(k0) 196 | lq $15, 0xf0(k0) 197 | lq $16, 0x100(k0) 198 | lq $17, 0x110(k0) 199 | lq $18, 0x120(k0) 200 | lq $19, 0x130(k0) 201 | lq $10, 0x140(k0) 202 | lq $21, 0x150(k0) 203 | lq $22, 0x160(k0) 204 | lq $23, 0x170(k0) 205 | lq $24, 0x180(k0) 206 | lq $25, 0x190(k0) 207 | # lq $26, 0x1a0(k0) # $k0 208 | lq $27, 0x1b0(k0) # $k1 209 | lq $28, 0x1c0(k0) 210 | lq $29, 0x1d0(k0) # $sp 211 | lq $30, 0x1e0(k0) 212 | # lq $31, 0x1f0(k0) # $ra 213 | 214 | lw ra, 0x22c(k0) 215 | # Guess one should have some check here, and only advance PC if 216 | # we are going to step over a Breakpoint or something 217 | # (i.e. do stuff depending on Cause) 218 | addiu ra, 4 219 | sync.p 220 | ei 221 | sync.p 222 | 223 | jr ra 224 | nop 225 | .end pkoReturnFromDebug 226 | -------------------------------------------------------------------------------- /include/hostlink.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * This file is subject to the terms and conditions of the PS2Link License. 4 | * See the file LICENSE in the main directory of this distribution for more 5 | * details. 6 | */ 7 | 8 | #define PKO_PORT 0x4711 9 | #define PKO_CMD_PORT 0x4712 10 | #define PKO_PRINTF_PORT 0x4712 11 | 12 | #define PKO_OPEN_CMD 0xbabe0111 13 | #define PKO_OPEN_RLY 0xbabe0112 14 | #define PKO_CLOSE_CMD 0xbabe0121 15 | #define PKO_CLOSE_RLY 0xbabe0122 16 | #define PKO_READ_CMD 0xbabe0131 17 | #define PKO_READ_RLY 0xbabe0132 18 | #define PKO_WRITE_CMD 0xbabe0141 19 | #define PKO_WRITE_RLY 0xbabe0142 20 | #define PKO_LSEEK_CMD 0xbabe0151 21 | #define PKO_LSEEK_RLY 0xbabe0152 22 | #define PKO_OPENDIR_CMD 0xbabe0161 23 | #define PKO_OPENDIR_RLY 0xbabe0162 24 | #define PKO_CLOSEDIR_CMD 0xbabe0171 25 | #define PKO_CLOSEDIR_RLY 0xbabe0172 26 | #define PKO_READDIR_CMD 0xbabe0181 27 | #define PKO_READDIR_RLY 0xbabe0182 28 | #define PKO_REMOVE_CMD 0xbabe0191 29 | #define PKO_REMOVE_RLY 0xbabe0192 30 | #define PKO_MKDIR_CMD 0xbabe01a1 31 | #define PKO_MKDIR_RLY 0xbabe01a2 32 | #define PKO_RMDIR_CMD 0xbabe01b1 33 | #define PKO_RMDIR_RLY 0xbabe01b2 34 | #define PKO_GETSTAT_CMD 0xbabe01c1 35 | #define PKO_GETSTAT_RLY 0xbabe01c2 36 | 37 | #define PKO_RESET_CMD 0xbabe0201 38 | #define PKO_EXECIOP_CMD 0xbabe0202 39 | #define PKO_EXECEE_CMD 0xbabe0203 40 | #define PKO_POWEROFF_CMD 0xbabe0204 41 | #define PKO_SCRDUMP_CMD 0xbabe0205 42 | #define PKO_NETDUMP_CMD 0xbabe0206 43 | 44 | #define PKO_DUMP_MEM 0xbabe0207 45 | #define PKO_START_VU 0xbabe0208 46 | #define PKO_STOP_VU 0xbabe0209 47 | #define PKO_DUMP_REG 0xbabe020a 48 | #define PKO_GSEXEC_CMD 0xbabe020b 49 | #define PKO_WRITE_MEM 0xbabe020c 50 | #define PKO_IOPEXCEP_CMD 0xbabe020d 51 | 52 | #define PKO_RPC_RESET 1 53 | #define PKO_RPC_EXECEE 2 54 | #define PKO_RPC_DUMMY 3 55 | #define PKO_RPC_SCRDUMP 4 56 | #define PKO_RPC_NETDUMP 5 57 | #define PKO_RPC_STARTVU 6 58 | #define PKO_RPC_STOPVU 7 59 | #define PKO_RPC_DUMPMEM 8 60 | #define PKO_RPC_DUMPREG 9 61 | #define PKO_RPC_GSEXEC 10 62 | #define PKO_RPC_WRITEMEM 11 63 | #define PKO_RPC_IOPEXCEP 12 64 | 65 | #define PKO_MAX_PATH 256 66 | 67 | #define REGDMA 0 68 | #define REGINTC 1 69 | #define REGTIMER 2 70 | #define REGGS 3 71 | #define REGSIF 4 72 | #define REGFIFO 5 73 | #define REGGIF 6 74 | #define REGVIF0 7 75 | #define REGVIF1 8 76 | #define REGIPU 9 77 | #define REGALL 10 78 | #define REGVU0 11 79 | #define REGVU1 12 80 | 81 | typedef struct 82 | { 83 | unsigned int cmd; 84 | unsigned short len; 85 | } __attribute__((packed)) pko_pkt_hdr; 86 | 87 | typedef struct 88 | { 89 | unsigned int cmd; 90 | unsigned short len; 91 | unsigned int retval; 92 | } __attribute__((packed)) pko_pkt_file_rly; 93 | 94 | typedef struct 95 | { 96 | unsigned int cmd; 97 | unsigned short len; 98 | int flags; 99 | char path[PKO_MAX_PATH]; 100 | } __attribute__((packed)) pko_pkt_open_req; 101 | 102 | typedef struct 103 | { 104 | unsigned int cmd; 105 | unsigned short len; 106 | int fd; 107 | } __attribute__((packed)) pko_pkt_close_req; 108 | 109 | typedef struct 110 | { 111 | unsigned int cmd; 112 | unsigned short len; 113 | int fd; 114 | int nbytes; 115 | } __attribute__((packed)) pko_pkt_read_req; 116 | 117 | typedef struct 118 | { 119 | unsigned int cmd; 120 | unsigned short len; 121 | int retval; 122 | int nbytes; 123 | } __attribute__((packed)) pko_pkt_read_rly; 124 | 125 | typedef struct 126 | { 127 | unsigned int cmd; 128 | unsigned short len; 129 | int fd; 130 | int nbytes; 131 | } __attribute__((packed)) pko_pkt_write_req; 132 | 133 | typedef struct 134 | { 135 | unsigned int cmd; 136 | unsigned short len; 137 | int fd; 138 | int offset; 139 | int whence; 140 | } __attribute__((packed)) pko_pkt_lseek_req; 141 | 142 | typedef struct 143 | { 144 | unsigned int cmd; 145 | unsigned short len; 146 | char name[PKO_MAX_PATH]; 147 | } __attribute__((packed)) pko_pkt_remove_req; 148 | 149 | typedef struct 150 | { 151 | unsigned int cmd; 152 | unsigned short len; 153 | int mode; 154 | char name[PKO_MAX_PATH]; 155 | } __attribute__((packed)) pko_pkt_mkdir_req; 156 | 157 | typedef struct 158 | { 159 | unsigned int cmd; 160 | unsigned short len; 161 | char name[PKO_MAX_PATH]; 162 | } __attribute__((packed)) pko_pkt_rmdir_req; 163 | 164 | typedef struct 165 | { 166 | unsigned int cmd; 167 | unsigned short len; 168 | int fd; 169 | } __attribute__((packed)) pko_pkt_dread_req; 170 | 171 | typedef struct 172 | { 173 | unsigned int cmd; 174 | unsigned short len; 175 | int retval; 176 | /* from io_common.h (fio_dirent_t) in ps2lib */ 177 | unsigned int mode; 178 | unsigned int attr; 179 | unsigned int size; 180 | unsigned char ctime[8]; 181 | unsigned char atime[8]; 182 | unsigned char mtime[8]; 183 | unsigned int hisize; 184 | char name[256]; 185 | } __attribute__((packed)) pko_pkt_dread_rly; 186 | 187 | typedef struct 188 | { 189 | unsigned int cmd; 190 | unsigned short len; 191 | char name[PKO_MAX_PATH]; 192 | } __attribute__((packed)) pko_pkt_getstat_req; 193 | 194 | typedef struct 195 | { 196 | unsigned int cmd; 197 | unsigned short len; 198 | int retval; 199 | /* from io_common.h (fio_dirent_t) in ps2lib */ 200 | unsigned int mode; 201 | unsigned int attr; 202 | unsigned int size; 203 | unsigned char ctime[8]; 204 | unsigned char atime[8]; 205 | unsigned char mtime[8]; 206 | unsigned int hisize; 207 | } __attribute__((packed)) pko_pkt_getstat_rly; 208 | 209 | //// 210 | 211 | typedef struct 212 | { 213 | unsigned int cmd; 214 | unsigned short len; 215 | } __attribute__((packed)) pko_pkt_reset_req; 216 | 217 | typedef struct 218 | { 219 | unsigned int cmd; 220 | unsigned short len; 221 | int argc; 222 | char argv[PKO_MAX_PATH]; 223 | } __attribute__((packed)) pko_pkt_execee_req; 224 | 225 | typedef struct 226 | { 227 | unsigned int cmd; 228 | unsigned short len; 229 | int argc; 230 | char argv[PKO_MAX_PATH]; 231 | } __attribute__((packed)) pko_pkt_execiop_req; 232 | 233 | typedef struct 234 | { 235 | unsigned int cmd; 236 | unsigned short len; 237 | unsigned short size; 238 | unsigned char file[PKO_MAX_PATH]; 239 | } __attribute__((packed)) pko_pkt_gsexec_req; 240 | 241 | typedef struct 242 | { 243 | unsigned int cmd; 244 | unsigned short len; 245 | } __attribute__((packed)) pko_pkt_poweroff_req; 246 | 247 | typedef struct 248 | { 249 | unsigned int cmd; 250 | unsigned short len; 251 | int vpu; 252 | } __attribute__((packed)) pko_pkt_start_vu; 253 | 254 | typedef struct 255 | { 256 | unsigned int cmd; 257 | unsigned short len; 258 | int vpu; 259 | } __attribute__((packed)) pko_pkt_stop_vu; 260 | 261 | typedef struct 262 | { 263 | unsigned int cmd; 264 | unsigned short len; 265 | unsigned int offset; 266 | unsigned int size; 267 | char argv[PKO_MAX_PATH]; 268 | } __attribute__((packed)) pko_pkt_mem_io; 269 | 270 | typedef struct 271 | { 272 | unsigned int cmd; 273 | unsigned short len; 274 | int regs; 275 | char argv[PKO_MAX_PATH]; 276 | } __attribute__((packed)) pko_pkt_dump_regs; 277 | 278 | typedef struct 279 | { 280 | unsigned int cmd; 281 | unsigned short len; 282 | unsigned int regs[79]; 283 | } __attribute__((packed)) pko_pkt_send_regs; 284 | 285 | #define PKO_MAX_WRITE_SEGMENT (1460 - sizeof(pko_pkt_write_req)) 286 | #define PKO_MAX_READ_SEGMENT (1460 - sizeof(pko_pkt_read_rly)) 287 | -------------------------------------------------------------------------------- /ee/ps2link.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * Copyright (C) 2003,2004 adresd (adresd_ps2dev@yahoo.com) 4 | * This file is subject to the terms and conditions of the PS2Link License. 5 | * See the file LICENSE in the main directory of this distribution for more 6 | * details. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | 25 | #include "irx_variables.h" 26 | #include "hostlink.h" 27 | #include "excepHandler.h" 28 | #include "cmdHandler.h" 29 | #include "globals.h" 30 | 31 | //////////////////////////////////////////////////////////////////////// 32 | 33 | // Argv name+path & just path 34 | char elfName[MAXNAMLEN] __attribute__((aligned(16))); 35 | //////////////////////////////////////////////////////////////////////// 36 | #define IPCONF_MAX_LEN 64 // Don't reduce even more this value 37 | 38 | // Make sure the "cached config" is in the data section 39 | // To prevent it from being "zeroed" on a restart of ps2link 40 | char if_conf[IPCONF_MAX_LEN] __attribute__((section(".data"))) = ""; 41 | int if_conf_len __attribute__((section(".data"))) = 0; 42 | 43 | //////////////////////////////////////////////////////////////////////// 44 | 45 | static void printIpConfig(void) 46 | { 47 | int i; 48 | int t; 49 | 50 | scr_printf("Net config: "); 51 | for (t = 0, i = 0; t < 3; t++) { 52 | scr_printf("%s ", &if_conf[i]); 53 | i += strlen(&if_conf[i]) + 1; 54 | } 55 | scr_printf("\n"); 56 | } 57 | 58 | // Parse network configuration from IPCONFIG.DAT 59 | // Note: parsing really should be made more robust... 60 | static int readIpConfigFromFile(char *buf) 61 | { 62 | int fd; 63 | int len; 64 | 65 | fd = open("IPCONFIG.DAT", O_RDONLY); 66 | 67 | if (fd < 0) { 68 | dbgprintf("Error reading ipconfig.dat\n"); 69 | return -1; 70 | } 71 | 72 | len = read(fd, buf, IPCONF_MAX_LEN - 1); // Let the last byte be '\0' 73 | close(fd); 74 | 75 | if (len < 0) { 76 | dbgprintf("Error reading ipconfig.dat\n"); 77 | return -1; 78 | } 79 | 80 | dbgscr_printf("ipconfig: Read %d bytes\n", len); 81 | return 0; 82 | } 83 | 84 | static int readDefaultIpConfig(char *buf) 85 | { 86 | int i = 0; 87 | 88 | strncpy(&buf[i], DEFAULT_IP, 15); 89 | i += strlen(&buf[i]) + 1; 90 | strncpy(&buf[i], DEFAULT_NETMASK, 15); 91 | i += strlen(&buf[i]) + 1; 92 | strncpy(&buf[i], DEFAULT_GW, 15); 93 | 94 | return 0; 95 | } 96 | 97 | static void getIpConfig(void) 98 | { 99 | int i; 100 | int t; 101 | char c; 102 | char buf[IPCONF_MAX_LEN]; 103 | 104 | // Clean buffers 105 | memset(buf, 0x00, IPCONF_MAX_LEN); 106 | memset(buf, 0x00, IPCONF_MAX_LEN); 107 | 108 | if (readIpConfigFromFile(buf)) 109 | readDefaultIpConfig(buf); 110 | 111 | i = 0; 112 | // Clear out spaces (and potential ending CR/LF) 113 | while ((c = buf[i]) != '\0') { 114 | if ((c == ' ') || (c == '\r') || (c == '\n')) 115 | buf[i] = '\0'; 116 | i++; 117 | } 118 | 119 | scr_printf("Saving IP config...\n"); 120 | for (t = 0, i = 0; t < 3; t++) { 121 | strncpy(&if_conf[i], &buf[i], 15); 122 | i += strlen(&if_conf[i]) + 1; 123 | } 124 | 125 | if_conf_len = i; 126 | } 127 | 128 | //////////////////////////////////////////////////////////////////////// 129 | // Wrapper to load irx module from disc/rom 130 | static void pkoLoadModule(char *path, int argc, char *argv) 131 | { 132 | int ret; 133 | 134 | ret = SifLoadModule(path, argc, argv); 135 | if (ret < 0) { 136 | scr_printf("Could not load module %s: %d\n", path, ret); 137 | SleepThread(); 138 | } 139 | dbgscr_printf("Load %s, returned [%d]\n", path, ret); 140 | } 141 | 142 | //////////////////////////////////////////////////////////////////////// 143 | // Load all the irx modules we need 144 | static void loadModules(void) 145 | { 146 | int ret; 147 | 148 | if (if_conf_len == 0) { 149 | pkoLoadModule("rom0:SIO2MAN", 0, NULL); 150 | pkoLoadModule("rom0:MCMAN", 0, NULL); 151 | pkoLoadModule("rom0:MCSERV", 0, NULL); 152 | return; 153 | } 154 | 155 | dbgscr_printf("Exec poweroff module. (%x,%d) ", (unsigned int)poweroff_irx, size_poweroff_irx); 156 | SifExecModuleBuffer(poweroff_irx, size_poweroff_irx, 0, NULL, &ret); 157 | dbgscr_printf("[%d] returned\n", ret); 158 | dbgscr_printf("Exec ps2dev9 module. (%x,%d) ", (unsigned int)ps2dev9_irx, size_ps2dev9_irx); 159 | SifExecModuleBuffer(ps2dev9_irx, size_ps2dev9_irx, 0, NULL, &ret); 160 | dbgscr_printf("[%d] returned\n", ret); 161 | dbgscr_printf("Exec netman module. (%x,%d) ", (unsigned int)netman_irx, size_netman_irx); 162 | SifExecModuleBuffer(netman_irx, size_netman_irx, 0, NULL, &ret); 163 | dbgscr_printf("[%d] returned\n", ret); 164 | dbgscr_printf("Exec smap module. (%x,%d) ", (unsigned int)smap_irx, size_smap_irx); 165 | SifExecModuleBuffer(smap_irx, size_smap_irx, 0, NULL, &ret); 166 | dbgscr_printf("[%d] returned\n", ret); 167 | dbgscr_printf("Exec ps2ip module. (%x,%d) ", (unsigned int)ps2ip_nm_irx, size_ps2ip_nm_irx); 168 | SifExecModuleBuffer(ps2ip_nm_irx, size_ps2ip_nm_irx, if_conf_len, &if_conf[0], &ret); 169 | dbgscr_printf("[%d] returned\n", ret); 170 | dbgscr_printf("Exec udptty module. (%x,%d) ", (unsigned int)udptty_irx, size_udptty_irx); 171 | SifExecModuleBuffer(&udptty_irx, size_udptty_irx, 0, NULL, &ret); 172 | dbgscr_printf("[%d] returned\n", ret); 173 | dbgscr_printf("Exec ioptrap module. (%x,%d) ", (unsigned int)ioptrap_irx, size_ioptrap_irx); 174 | SifExecModuleBuffer(ioptrap_irx, size_ioptrap_irx, 0, NULL, &ret); 175 | dbgscr_printf("[%d] returned\n", ret); 176 | dbgscr_printf("Exec ps2link module. (%x,%d) ", (unsigned int)ps2link_irx, size_ps2link_irx); 177 | SifExecModuleBuffer(ps2link_irx, size_ps2link_irx, 0, NULL, &ret); 178 | dbgscr_printf("[%d] returned\n", ret); 179 | dbgscr_printf("All modules loaded on IOP.\n"); 180 | } 181 | 182 | static void printWelcomeInfo() 183 | { 184 | scr_printf("\n\n\n\n"); 185 | scr_printf("Welcome to ps2link %s\n", APP_VERSION); 186 | scr_printf("ps2link loaded at 0x%08X-0x%08X, size: 0x%08X\n", (unsigned int)&__start, (unsigned int)&_end, (unsigned int)&_end - (unsigned int)&__start); 187 | scr_printf("Initializing...\n"); 188 | } 189 | 190 | static void restartIOP() 191 | { 192 | dbgscr_printf("reset iop\n"); 193 | 194 | SifInitRpc(0); 195 | while(!SifIopReset(NULL, 0)){}; 196 | while(!SifIopSync()){}; 197 | 198 | SifInitRpc(0); 199 | sbv_patch_enable_lmb(); 200 | sbv_patch_disable_prefix_check(); 201 | 202 | dbgscr_printf("reseted iop\n"); 203 | } 204 | 205 | //////////////////////////////////////////////////////////////////////// 206 | 207 | // This function is defined as weak in ps2sdkc, so how 208 | // we are not using time zone, so we can safe some KB 209 | void _ps2sdk_timezone_update() {} 210 | void _libcglue_rtc_update() {} 211 | 212 | DISABLE_PATCHED_FUNCTIONS(); // Disable the patched functionalities 213 | DISABLE_EXTRA_TIMERS_FUNCTIONS(); // Disable the extra functionalities for timers 214 | PS2_DISABLE_AUTOSTART_PTHREAD(); // Disable pthread functionality 215 | 216 | int main(int argc, char *argv[]) 217 | { 218 | SifInitRpc(0); 219 | init_scr(); 220 | 221 | printWelcomeInfo(); 222 | if (if_conf_len == 0) { 223 | scr_printf("Initial boot, will load config then reset\n"); 224 | getIpConfig(); 225 | pkoReset(); // Will restart execution 226 | } 227 | 228 | installExceptionHandlers(); 229 | restartIOP(); 230 | 231 | strcpy(elfName, argv[0]); 232 | dbgscr_printf("argv[0] is %s\n", elfName); 233 | 234 | dbgscr_printf("loading modules\n"); 235 | loadModules(); 236 | 237 | scr_printf("Using cached config\n"); 238 | printIpConfig(); 239 | 240 | dbgscr_printf("init cmdrpc\n"); 241 | initCmdRpc(); 242 | scr_printf("Ready with %i memory bytes\n", GetMemorySize()); 243 | 244 | ExitDeleteThread(); 245 | return 0; 246 | } 247 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | COPYRIGHT FOR PS2LINK 3 | ---------------------------------------------------------------------------- 4 | 5 | Copyright (c) 2003 Tord Lindstrom (pukko@home.se) 6 | (c) 2003 adresd (adresd_ps2dev@yahoo.com) 7 | (c) 2004 Khaled Daham 8 | (c) 2004 Nicolas 'Pixel' Noble 9 | 10 | The Academic Free License 11 | v. 2.0 12 | 13 | This Academic Free License (the "License") applies to any original work 14 | of authorship (the "Original Work") whose owner (the "Licensor") has 15 | placed the following notice immediately following the copyright notice 16 | for the Original Work: 17 | 18 | *Licensed under the Academic Free License version 2.0* 19 | 20 | 1) *Grant of Copyright License.* Licensor hereby grants You a 21 | world-wide, royalty-free, non-exclusive, perpetual, sublicenseable 22 | license to do the following: 23 | 24 | a) to reproduce the Original Work in copies; 25 | 26 | b) to prepare derivative works ("Derivative Works") based upon the 27 | Original Work; 28 | 29 | c) to distribute copies of the Original Work and Derivative Works to 30 | the public; 31 | 32 | d) to perform the Original Work publicly; and 33 | 34 | e) to display the Original Work publicly. 35 | 36 | 2) *Grant of Patent License.* Licensor hereby grants You a world-wide, 37 | royalty-free, non-exclusive, perpetual, sublicenseable license, under 38 | patent claims owned or controlled by the Licensor that are embodied in 39 | the Original Work as furnished by the Licensor, to make, use, sell and 40 | offer for sale the Original Work and Derivative Works. 41 | 42 | 3) *Grant of Source Code License.* The term "Source Code" means the 43 | preferred form of the Original Work for making modifications to it and 44 | all available documentation describing how to modify the Original Work. 45 | Licensor hereby agrees to provide a machine-readable copy of the Source 46 | Code of the Original Work along with each copy of the Original Work that 47 | Licensor distributes. Licensor reserves the right to satisfy this 48 | obligation by placing a machine-readable copy of the Source Code in an 49 | information repository reasonably calculated to permit inexpensive and 50 | convenient access by You for as long as Licensor continues to distribute 51 | the Original Work, and by publishing the address of that information 52 | repository in a notice immediately following the copyright notice that 53 | applies to the Original Work. 54 | 55 | 4) *Exclusions From License Grant. *Neither the names of Licensor, nor 56 | the names of any contributors to the Original Work, nor any of their 57 | trademarks or service marks, may be used to endorse or promote products 58 | derived from this Original Work without express prior written permission 59 | of the Licensor. Nothing in this License shall be deemed to grant any 60 | rights to trademarks, copyrights, patents, trade secrets or any other 61 | intellectual property of Licensor except as expressly stated herein. No 62 | patent license is granted to make, use, sell or offer to sell 63 | embodiments of any patent claims other than the licensed claims defined 64 | in Section 2. No right is granted to the trademarks of Licensor even if 65 | such marks are included in the Original Work. Nothing in this License 66 | shall be interpreted to prohibit Licensor from licensing under different 67 | terms from this License any Original Work that Licensor otherwise would 68 | have a right to license. 69 | 70 | 5) This section intentionally omitted. 71 | 72 | 6) *Attribution Rights.* You must retain, in the Source Code of any 73 | Derivative Works that You create, all copyright, patent or trademark 74 | notices from the Source Code of the Original Work, as well as any 75 | notices of licensing and any descriptive text identified therein as an 76 | "Attribution Notice." You must cause the Source Code for any Derivative 77 | Works that You create to carry a prominent Attribution Notice reasonably 78 | calculated to inform recipients that You have modified the Original Work. 79 | 80 | 7) *Warranty of Provenance and Disclaimer of Warranty.* Licensor 81 | warrants that the copyright in and to the Original Work and the patent 82 | rights granted herein by Licensor are owned by the Licensor or are 83 | sublicensed to You under the terms of this License with the permission 84 | of the contributor(s) of those copyrights and patent rights. Except as 85 | expressly stated in the immediately proceeding sentence, the Original 86 | Work is provided under this License on an "AS IS" BASIS and WITHOUT 87 | WARRANTY, either express or implied, including, without limitation, the 88 | warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A 89 | PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL 90 | WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential 91 | part of this License. No license to Original Work is granted hereunder 92 | except under this disclaimer. 93 | 94 | 8) *Limitation of Liability.* Under no circumstances and under no legal 95 | theory, whether in tort (including negligence), contract, or otherwise, 96 | shall the Licensor be liable to any person for any direct, indirect, 97 | special, incidental, or consequential damages of any character arising 98 | as a result of this License or the use of the Original Work including, 99 | without limitation, damages for loss of goodwill, work stoppage, 100 | computer failure or malfunction, or any and all other commercial damages 101 | or losses. This limitation of liability shall not apply to liability for 102 | death or personal injury resulting from Licensor's negligence to the 103 | extent applicable law prohibits such limitation. Some jurisdictions do 104 | not allow the exclusion or limitation of incidental or consequential 105 | damages, so this exclusion and limitation may not apply to You. 106 | 107 | 9) *Acceptance and Termination.* If You distribute copies of the 108 | Original Work or a Derivative Work, You must make a reasonable effort 109 | under the circumstances to obtain the express assent of recipients to 110 | the terms of this License. Nothing else but this License (or another 111 | written agreement between Licensor and You) grants You permission to 112 | create Derivative Works based upon the Original Work or to exercise any 113 | of the rights granted in Section 1 herein, and any attempt to do so 114 | except under the terms of this License (or another written agreement 115 | between Licensor and You) is expressly prohibited by U.S. copyright law, 116 | the equivalent laws of other countries, and by international treaty. 117 | Therefore, by exercising any of the rights granted to You in Section 1 118 | herein, You indicate Your acceptance of this License and all of its 119 | terms and conditions. 120 | 121 | 10) *Termination for Patent Action.* This License shall terminate 122 | automatically and You may no longer exercise any of the rights granted 123 | to You by this License as of the date You commence an action, including 124 | a cross-claim or counterclaim, for patent infringement (i) against 125 | Licensor with respect to a patent applicable to software or (ii) against 126 | any entity with respect to a patent applicable to the Original Work (but 127 | excluding combinations of the Original Work with other software or 128 | hardware). 129 | 130 | 11) *Jurisdiction, Venue and Governing Law.* Any action or suit relating 131 | to this License may be brought only in the courts of a jurisdiction 132 | wherein the Licensor resides or in which Licensor conducts its primary 133 | business, and under the laws of that jurisdiction excluding its 134 | conflict-of-law provisions. The application of the United Nations 135 | Convention on Contracts for the International Sale of Goods is expressly 136 | excluded. Any use of the Original Work outside the scope of this License 137 | or after its termination shall be subject to the requirements and 138 | penalties of the U.S. Copyright Act, 17 U.S.C. � 101 et seq., the 139 | equivalent laws of other countries, and international treaty. This 140 | section shall survive the termination of this License. 141 | 142 | 12) *Attorneys Fees.* In any action to enforce the terms of this License 143 | or seeking damages relating thereto, the prevailing party shall be 144 | entitled to recover its costs and expenses, including, without 145 | limitation, reasonable attorneys' fees and costs incurred in connection 146 | with such action, including any appeal of such action. This section 147 | shall survive the termination of this License. 148 | 149 | 13) *Miscellaneous.* This License represents the complete agreement 150 | concerning the subject matter hereof. If any provision of this License 151 | is held to be unenforceable, such provision shall be reformed only to 152 | the extent necessary to make it enforceable. 153 | 154 | 14) *Definition of "You" in This License.* "You" throughout this 155 | License, whether in upper or lower case, means an individual or a legal 156 | entity exercising rights under, and complying with all of the terms of, 157 | this License. For legal entities, "You" includes any entity that 158 | controls, is controlled by, or is under common control with you. For 159 | purposes of this definition, "control" means (i) the power, direct or 160 | indirect, to cause the direction or management of such entity, whether 161 | by contract or otherwise, or (ii) ownership of fifty percent (50%) or 162 | more of the outstanding shares, or (iii) beneficial ownership of such 163 | entity. 164 | 165 | 15) *Right to Use.* You may use the Original Work in all ways not 166 | otherwise restricted or conditioned by this License or by law, and 167 | Licensor promises not to interfere with or be responsible for such uses 168 | by You. 169 | 170 | This license is Copyright (C) 2003 Lawrence E. Rosen. All rights 171 | reserved. Permission is hereby granted to copy and distribute this 172 | license without modification. This license may not be modified without 173 | the express written permission of its copyright owner. 174 | 175 | -------------------------------------------------------------------------------- /iop/net_fsys.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com) 4 | * This file is subject to the terms and conditions of the PS2Link License. 5 | * See the file LICENSE in the main directory of this distribution for more 6 | * details. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "net_fio.h" 20 | #include "globals.h" 21 | 22 | static char fsname[] = "host"; 23 | 24 | //////////////////////////////////////////////////////////////////////// 25 | //static iop_device_t fsys_driver; 26 | 27 | /* File desc struct is probably larger than this, but we only 28 | * need to access the word @ offset 0x0C (in which we put our identifier) 29 | */ 30 | struct filedesc_info 31 | { 32 | int unkn0; 33 | int unkn4; 34 | int device_id; // the X in hostX 35 | int own_fd; 36 | }; 37 | 38 | //////////////////////////////////////////////////////////////////////// 39 | /* We need(?) to protect the net access, so the server doesn't get 40 | * confused if two processes calls a fsys func at the same time 41 | */ 42 | static int fsys_sema; 43 | static int fsys_pid = 0; 44 | //static iop_device_t fsys_driver; 45 | 46 | //////////////////////////////////////////////////////////////////////// 47 | static int dummy5() 48 | { 49 | printf("ps2link: dummy function called\n"); 50 | return -5; 51 | } 52 | 53 | //////////////////////////////////////////////////////////////////////// 54 | static void fsysInit(iop_device_t *driver) 55 | { 56 | struct _iop_thread mythread; 57 | int pid; 58 | 59 | dbgprintf("initializing %s\n", driver->name); 60 | 61 | // Start socket server thread 62 | 63 | mythread.attr = 0x02000000; // attr 64 | mythread.option = 0; // option 65 | mythread.thread = (void *)pko_file_serv; // entry 66 | mythread.stacksize = 0x800; 67 | mythread.priority = 9; // We really should choose prio w more effort 68 | 69 | pid = CreateThread(&mythread); 70 | 71 | if (pid > 0) { 72 | int i; 73 | if ((i = StartThread(pid, NULL)) < 0) { 74 | printf("StartThread failed (%d)\n", i); 75 | } 76 | } else { 77 | printf("CreateThread failed (%d)\n", pid); 78 | } 79 | 80 | fsys_pid = pid; 81 | dbgprintf("Thread id: %x\n", pid); 82 | } 83 | 84 | //////////////////////////////////////////////////////////////////////// 85 | static int fsysDestroy(void) 86 | { 87 | WaitSema(fsys_sema); 88 | pko_close_fsys(); 89 | // ExitDeleteThread(fsys_pid); 90 | SignalSema(fsys_sema); 91 | DeleteSema(fsys_sema); 92 | return 0; 93 | } 94 | 95 | 96 | //////////////////////////////////////////////////////////////////////// 97 | static int fsysOpen(int fd, char *name, int mode) 98 | { 99 | struct filedesc_info *fd_info; 100 | int fsys_fd; 101 | 102 | dbgprintf("fsysOpen..\n"); 103 | dbgprintf(" fd: %x, name: %s, mode: %d\n\n", fd, name, mode); 104 | 105 | fd_info = (struct filedesc_info *)fd; 106 | 107 | WaitSema(fsys_sema); 108 | fsys_fd = pko_open_file(name, mode); 109 | SignalSema(fsys_sema); 110 | fd_info->own_fd = fsys_fd; 111 | 112 | return fsys_fd; 113 | } 114 | 115 | 116 | 117 | //////////////////////////////////////////////////////////////////////// 118 | static int fsysClose(int fd) 119 | { 120 | struct filedesc_info *fd_info; 121 | int ret; 122 | 123 | dbgprintf("fsys_close..\n" 124 | " fd: %x\n\n", 125 | fd); 126 | 127 | fd_info = (struct filedesc_info *)fd; 128 | WaitSema(fsys_sema); 129 | ret = pko_close_file(fd_info->own_fd); 130 | SignalSema(fsys_sema); 131 | 132 | return ret; 133 | } 134 | 135 | 136 | 137 | //////////////////////////////////////////////////////////////////////// 138 | static int fsysRead(int fd, char *buf, int size) 139 | { 140 | struct filedesc_info *fd_info; 141 | int ret; 142 | 143 | fd_info = (struct filedesc_info *)fd; 144 | 145 | dbgprintf("fsysRead..." 146 | " fd: %x\n" 147 | " bf: %x\n" 148 | " sz: %d\n" 149 | " ow: %d\n\n", 150 | fd, (int)buf, size, fd_info->own_fd); 151 | 152 | WaitSema(fsys_sema); 153 | ret = pko_read_file(fd_info->own_fd, buf, size); 154 | SignalSema(fsys_sema); 155 | 156 | return ret; 157 | } 158 | 159 | 160 | 161 | //////////////////////////////////////////////////////////////////////// 162 | static int fsysWrite(int fd, char *buf, int size) 163 | { 164 | struct filedesc_info *fd_info; 165 | int ret; 166 | 167 | dbgprintf("fsysWrite..." 168 | " fd: %x\n", 169 | fd); 170 | 171 | fd_info = (struct filedesc_info *)fd; 172 | WaitSema(fsys_sema); 173 | ret = pko_write_file(fd_info->own_fd, buf, size); 174 | SignalSema(fsys_sema); 175 | return ret; 176 | } 177 | 178 | 179 | 180 | //////////////////////////////////////////////////////////////////////// 181 | static int fsysLseek(int fd, unsigned int offset, int whence) 182 | { 183 | struct filedesc_info *fd_info; 184 | int ret; 185 | 186 | dbgprintf("fsysLseek..\n" 187 | " fd: %x\n" 188 | " of: %x\n" 189 | " wh: %x\n\n", 190 | fd, offset, whence); 191 | 192 | fd_info = (struct filedesc_info *)fd; 193 | WaitSema(fsys_sema); 194 | ret = pko_lseek_file(fd_info->own_fd, offset, whence); 195 | SignalSema(fsys_sema); 196 | return ret; 197 | } 198 | 199 | //////////////////////////////////////////////////////////////////////// 200 | static int fsysRemove(iop_file_t *file, char *name) 201 | { 202 | int ret; 203 | dbgprintf("fsysRemove..\n"); 204 | dbgprintf(" name: %s\n\n", name); 205 | 206 | WaitSema(fsys_sema); 207 | ret = pko_remove(name); 208 | SignalSema(fsys_sema); 209 | 210 | return ret; 211 | } 212 | 213 | //////////////////////////////////////////////////////////////////////// 214 | static int fsysMkdir(iop_file_t *file, char *name, int mode) 215 | { 216 | int ret; 217 | dbgprintf("fsysMkdir..\n"); 218 | dbgprintf(" name: '%s', mode: '%i'\n\n", name, mode); 219 | 220 | if (mode == 0) { 221 | mode = (FIO_S_IRWXU | FIO_S_IRGRP | FIO_S_IXGRP | FIO_S_IROTH | FIO_S_IXOTH); 222 | printf("mkdir wrong mode, using fallback value %i\n", mode); 223 | } 224 | 225 | WaitSema(fsys_sema); 226 | ret = pko_mkdir(name, mode); 227 | SignalSema(fsys_sema); 228 | 229 | return ret; 230 | } 231 | 232 | //////////////////////////////////////////////////////////////////////// 233 | static int fsysRmdir(iop_file_t *file, char *name) 234 | { 235 | int ret; 236 | dbgprintf("fsysRmdir..\n"); 237 | dbgprintf(" name: %s\n\n", name); 238 | 239 | WaitSema(fsys_sema); 240 | ret = pko_rmdir(name); 241 | SignalSema(fsys_sema); 242 | 243 | return ret; 244 | } 245 | 246 | 247 | //////////////////////////////////////////////////////////////////////// 248 | static int fsysDopen(int fd, char *name) 249 | { 250 | struct filedesc_info *fd_info; 251 | int fsys_fd; 252 | 253 | dbgprintf("fsysDopen..\n"); 254 | dbgprintf(" fd: %x, name: %s\n\n", fd, name); 255 | 256 | fd_info = (struct filedesc_info *)fd; 257 | 258 | WaitSema(fsys_sema); 259 | fsys_fd = pko_open_dir(name); 260 | SignalSema(fsys_sema); 261 | fd_info->own_fd = fsys_fd; 262 | 263 | return fsys_fd; 264 | } 265 | 266 | //////////////////////////////////////////////////////////////////////// 267 | static int fsysDread(int fd, void *buf) 268 | { 269 | struct filedesc_info *fd_info; 270 | int ret; 271 | 272 | fd_info = (struct filedesc_info *)fd; 273 | 274 | dbgprintf("fsysDread..." 275 | " fd: %x\n" 276 | " bf: %x\n" 277 | " ow: %d\n\n", 278 | fd, (int)buf, fd_info->own_fd); 279 | 280 | WaitSema(fsys_sema); 281 | ret = pko_read_dir(fd_info->own_fd, buf); 282 | SignalSema(fsys_sema); 283 | 284 | return ret; 285 | } 286 | 287 | //////////////////////////////////////////////////////////////////////// 288 | static int fsysDclose(int fd) 289 | { 290 | struct filedesc_info *fd_info; 291 | int ret; 292 | 293 | dbgprintf("fsys_dclose..\n" 294 | " fd: %x\n\n", 295 | fd); 296 | 297 | fd_info = (struct filedesc_info *)fd; 298 | WaitSema(fsys_sema); 299 | ret = pko_close_dir(fd_info->own_fd); 300 | SignalSema(fsys_sema); 301 | 302 | return ret; 303 | } 304 | 305 | //////////////////////////////////////////////////////////////////////// 306 | static int fsysGetstat(iop_file_t *file, const char *name, io_stat_t *stat) 307 | { 308 | int ret; 309 | dbgprintf("fsysGetstat..\n"); 310 | dbgprintf(" name: '%s'\n\n", name); 311 | 312 | WaitSema(fsys_sema); 313 | ret = pko_get_stat(name, stat); 314 | SignalSema(fsys_sema); 315 | 316 | return ret; 317 | } 318 | 319 | iop_device_ops_t fsys_functarray = {(void *)fsysInit, (void *)fsysDestroy, (void *)dummy5, 320 | (void *)fsysOpen, (void *)fsysClose, (void *)fsysRead, 321 | (void *)fsysWrite, (void *)fsysLseek, (void *)dummy5, 322 | (void *)fsysRemove, (void *)fsysMkdir, (void *)fsysRmdir, 323 | (void *)fsysDopen, (void *)fsysDclose, (void *)fsysDread, 324 | (void *)fsysGetstat, (void *)dummy5}; 325 | 326 | iop_device_t fsys_driver = {fsname, 16, 1, "fsys driver", 327 | &fsys_functarray}; 328 | //////////////////////////////////////////////////////////////////////// 329 | // Entry point for mounting the file system 330 | int fsysMount(void) 331 | { 332 | iop_sema_t sema_info; 333 | 334 | sema_info.attr = 1; 335 | sema_info.option = 0; 336 | sema_info.initial = 1; 337 | sema_info.max = 1; 338 | fsys_sema = CreateSema(&sema_info); 339 | 340 | DelDrv(fsname); 341 | AddDrv(&fsys_driver); 342 | 343 | return 0; 344 | } 345 | 346 | int fsysUnmount(void) 347 | { 348 | DelDrv(fsname); 349 | return 0; 350 | } 351 | -------------------------------------------------------------------------------- /iop/cmdHandler.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * Copyright (C) 2003,2004 adresd (adresd_ps2dev@yahoo.com) 4 | * This file is subject to the terms and conditions of the PS2Link License. 5 | * See the file LICENSE in the main directory of this distribution for more 6 | * details. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "ps2ip.h" 23 | #include "hostlink.h" 24 | #include "net_fsys.h" 25 | #include "globals.h" 26 | 27 | #define BUF_SIZE 1024 28 | static char recvbuf[BUF_SIZE] __attribute__((aligned(16))); 29 | static unsigned int rpc_data[1024 / 4] __attribute__((aligned(16))); 30 | 31 | int excepscrdump = 1; 32 | 33 | #define PKO_DMA_DEST ((void *)0x200ff800) 34 | //unsigned int *dma_ptr =(unsigned int*)(0x20100000-2048); 35 | 36 | ////////////////////////////////////////////////////////////////////////// 37 | static void 38 | pkoExecIop(char *buf, int len) 39 | { 40 | pko_pkt_execiop_req *cmd; 41 | int retval; 42 | int arglen; 43 | char *path; 44 | char *args; 45 | unsigned int argc; 46 | int id; 47 | int i; 48 | 49 | cmd = (pko_pkt_execiop_req *)buf; 50 | 51 | dbgprintf("IOP cmd: EXECIOP\n"); 52 | 53 | if (len != sizeof(pko_pkt_execiop_req)) { 54 | dbgprintf("IOP cmd: exec_iop got a broken packet (%d)!\n", len); 55 | return; 56 | } 57 | 58 | // Make sure arg vector is null-terminated 59 | cmd->argv[PKO_MAX_PATH - 1] = '\0'; 60 | 61 | printf("IOP cmd: %ld args\n", ntohl(cmd->argc)); 62 | 63 | path = &cmd->argv[0]; 64 | args = &cmd->argv[strlen(cmd->argv) + 1]; 65 | argc = ntohl(cmd->argc); 66 | 67 | printf("IOP binary path: %s\n", path); 68 | 69 | arglen = 0; 70 | for (i = 0; i < (argc - 1); i++) { 71 | printf("arg %d: %s (%d)\n", i, &args[arglen], arglen); 72 | arglen += strlen(&args[arglen]) + 1; 73 | } 74 | 75 | id = LoadStartModule(cmd->argv, arglen, args, &retval); 76 | 77 | if (id < 0) { 78 | printf("Error loading module: "); 79 | switch (-id) { 80 | case E_IOP_INTR_CONTEXT: 81 | printf("IOP is in exception context.\n"); 82 | break; 83 | case E_IOP_DEPENDANCY: 84 | printf("Inter IRX dependancy error.\n"); 85 | break; 86 | case E_LF_NOT_IRX: 87 | printf("Invalid IRX module.\n"); 88 | break; 89 | case E_LF_FILE_NOT_FOUND: 90 | printf("Unable to open executable file.\n"); 91 | break; 92 | case E_LF_FILE_IO_ERROR: 93 | printf("Error while accessing file.\n"); 94 | break; 95 | case E_IOP_NO_MEMORY: 96 | printf("IOP is out of memory.\n"); 97 | break; 98 | default: 99 | printf("Unknow error code: %d\n", -retval); 100 | break; 101 | } 102 | } else { 103 | printf("loadmodule: id %d, ret %d\n", id, retval); 104 | } 105 | } 106 | 107 | ////////////////////////////////////////////////////////////////////////// 108 | unsigned int 109 | pkoSetSifDma(void *dest, void *src, unsigned int length, unsigned int mode) 110 | { 111 | struct t_SifDmaTransfer sendData; 112 | int oldIrq; 113 | int id; 114 | 115 | sendData.src = (unsigned int *)src; 116 | sendData.dest = (unsigned int *)dest; 117 | sendData.size = length; 118 | sendData.attr = mode; 119 | 120 | CpuSuspendIntr(&oldIrq); 121 | id = sceSifSetDma(&sendData, 1); 122 | CpuResumeIntr(oldIrq); 123 | 124 | return id; 125 | } 126 | 127 | ////////////////////////////////////////////////////////////////////////// 128 | unsigned int 129 | pkoSendSifCmd(unsigned int cmd, void *src, unsigned int len) 130 | { 131 | unsigned int dmaId; 132 | 133 | rpc_data[0] = cmd; 134 | 135 | memcpy(&rpc_data[1], src, 136 | (len > sizeof(rpc_data) ? sizeof(rpc_data) : len)); 137 | 138 | len = len > sizeof(rpc_data) ? sizeof(rpc_data) : len; 139 | 140 | dmaId = pkoSetSifDma(PKO_DMA_DEST, rpc_data, len, 4); 141 | 142 | if (dmaId == 0) { 143 | printf("IOP: sifSendCmd %x failed\n", cmd); 144 | return -1; 145 | } 146 | return 0; 147 | } 148 | 149 | 150 | ////////////////////////////////////////////////////////////////////////// 151 | static void 152 | pkoExecEE(char *buf, int len) 153 | { 154 | pkoSendSifCmd(PKO_RPC_EXECEE, buf, len); 155 | }; 156 | ////////////////////////////////////////////////////////////////////////// 157 | static void 158 | pkoGSExec(char *buf, int len) 159 | { 160 | pkoSendSifCmd(PKO_RPC_GSEXEC, buf, len); 161 | }; 162 | ////////////////////////////////////////////////////////////////////////// 163 | static void 164 | pkoNetDump(char *buf, int len) 165 | { 166 | pkoSendSifCmd(PKO_RPC_NETDUMP, buf, len); 167 | }; 168 | ////////////////////////////////////////////////////////////////////////// 169 | static void 170 | pkoScrDump(char *buf, int len) 171 | { 172 | pkoSendSifCmd(PKO_RPC_SCRDUMP, buf, len); 173 | }; 174 | 175 | ////////////////////////////////////////////////////////////////////////// 176 | static void 177 | pkoPowerOff() 178 | { 179 | PoweroffShutdown(); 180 | } 181 | 182 | ////////////////////////////////////////////////////////////////////////// 183 | static void 184 | pkoReset(char *buf, int len) 185 | { 186 | dbgprintf("IOP cmd: RESET\n"); 187 | 188 | if (len != sizeof(pko_pkt_reset_req)) { 189 | dbgprintf("IOP cmd: exec_ee got a broken packet (%d)!\n", len); 190 | return; 191 | } 192 | 193 | printf("unmounting\n"); 194 | fsysUnmount(); 195 | printf("unmounted\n"); 196 | DelDrv("tty"); 197 | 198 | pkoSendSifCmd(PKO_RPC_RESET, buf, len); 199 | }; 200 | 201 | static void 202 | pkoStopVU(char *buf, int len) 203 | { 204 | pkoSendSifCmd(PKO_RPC_STOPVU, buf, len); 205 | }; 206 | 207 | static void 208 | pkoStartVU(char *buf, int len) 209 | { 210 | pkoSendSifCmd(PKO_RPC_STARTVU, buf, len); 211 | }; 212 | 213 | static void 214 | pkoDumpMem(char *buf, int len) 215 | { 216 | pkoSendSifCmd(PKO_RPC_DUMPMEM, buf, len); 217 | }; 218 | 219 | static void 220 | pkoDumpReg(char *buf, int len) 221 | { 222 | pkoSendSifCmd(PKO_RPC_DUMPREG, buf, len); 223 | }; 224 | 225 | static void 226 | pkoWriteMem(char *buf, int len) 227 | { 228 | pkoSendSifCmd(PKO_RPC_WRITEMEM, buf, len); 229 | }; 230 | 231 | ////////////////////////////////////////////////////////////////////////// 232 | static void 233 | cmdListener(int sock) 234 | { 235 | while (1) { 236 | struct sockaddr_in remote_addr; 237 | int len; 238 | int addrlen; 239 | pko_pkt_hdr *header; 240 | unsigned int cmd; 241 | 242 | addrlen = sizeof(remote_addr); 243 | len = recvfrom(sock, &recvbuf[0], BUF_SIZE, 0, 244 | (struct sockaddr *)&remote_addr, 245 | &addrlen); 246 | dbgprintf("IOP cmd: received packet (%d)\n", len); 247 | 248 | if (len < 0) { 249 | dbgprintf("IOP: cmdListener: recvfrom error (%d)\n", len); 250 | continue; 251 | } 252 | if (len < sizeof(pko_pkt_hdr)) { 253 | continue; 254 | } 255 | 256 | header = (pko_pkt_hdr *)recvbuf; 257 | cmd = ntohl(header->cmd); 258 | switch (cmd) { 259 | 260 | case PKO_EXECIOP_CMD: 261 | pkoExecIop(recvbuf, len); 262 | break; 263 | case PKO_EXECEE_CMD: 264 | pkoExecEE(recvbuf, len); 265 | break; 266 | case PKO_POWEROFF_CMD: 267 | pkoPowerOff(); 268 | break; 269 | case PKO_RESET_CMD: 270 | pkoReset(recvbuf, len); 271 | break; 272 | case PKO_SCRDUMP_CMD: 273 | excepscrdump = 1; 274 | pkoScrDump(recvbuf, len); 275 | break; 276 | case PKO_NETDUMP_CMD: 277 | excepscrdump = 0; 278 | pkoNetDump(recvbuf, len); 279 | break; 280 | case PKO_START_VU: 281 | pkoStartVU(recvbuf, len); 282 | break; 283 | case PKO_STOP_VU: 284 | pkoStopVU(recvbuf, len); 285 | break; 286 | case PKO_DUMP_MEM: 287 | pkoDumpMem(recvbuf, len); 288 | break; 289 | case PKO_DUMP_REG: 290 | pkoDumpReg(recvbuf, len); 291 | break; 292 | case PKO_GSEXEC_CMD: 293 | pkoGSExec(recvbuf, len); 294 | break; 295 | case PKO_WRITE_MEM: 296 | pkoWriteMem(recvbuf, len); 297 | break; 298 | default: 299 | dbgprintf("IOP cmd: Uknown cmd received\n"); 300 | break; 301 | } 302 | dbgprintf("IOP cmd: waiting for next pkt\n"); 303 | } 304 | } 305 | 306 | static void 307 | cmdPowerOff(void *arg) 308 | { 309 | #ifdef PWOFFONRESET 310 | pkoPowerOff(); 311 | #else 312 | pko_pkt_reset_req reset; 313 | 314 | reset.cmd = htonl(PKO_RESET_CMD); 315 | reset.len = 0; 316 | 317 | pkoReset((char *)&reset, sizeof(reset)); 318 | #endif 319 | } 320 | 321 | ////////////////////////////////////////////////////////////////////////// 322 | static void 323 | cmdThread(void *arg) 324 | { 325 | struct sockaddr_in serv_addr; 326 | // struct sockaddr_in remote_addr; 327 | int sock; 328 | int ret; 329 | 330 | dbgprintf("IOP cmd: Server Thread Started.\n"); 331 | 332 | sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 333 | if (sock < 0) { 334 | dbgprintf("IOP cmd: Socket error %d\n", sock); 335 | ExitDeleteThread(); 336 | } 337 | 338 | memset((void *)&serv_addr, 0, sizeof(serv_addr)); 339 | serv_addr.sin_family = AF_INET; 340 | serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 341 | serv_addr.sin_port = htons(PKO_CMD_PORT); 342 | 343 | ret = bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); 344 | if (ret < 0) { 345 | dbgprintf("IOP cmd: Udp bind error (%d)\n", sock); 346 | ExitDeleteThread(); 347 | } 348 | 349 | // Do tha thing 350 | dbgprintf("IOP cmd: Listening\n"); 351 | 352 | cmdListener(sock); 353 | 354 | ExitDeleteThread(); 355 | } 356 | 357 | 358 | ////////////////////////////////////////////////////////////////////////// 359 | int cmdHandlerInit(void) 360 | { 361 | iop_thread_t thread; 362 | int pid; 363 | 364 | dbgprintf("IOP cmd: Starting thread\n"); 365 | 366 | SifInitRpc(0); 367 | SetPowerButtonHandler(cmdPowerOff, NULL); 368 | 369 | thread.attr = 0x02000000; 370 | thread.option = 0; 371 | thread.thread = (void *)cmdThread; 372 | thread.stacksize = 0x800; 373 | thread.priority = 60; //0x1e; 374 | 375 | pid = CreateThread(&thread); 376 | if (pid >= 0) { 377 | int ret; 378 | ret = StartThread(pid, 0); 379 | if (ret < 0) { 380 | dbgprintf("IOP cmd: Could not start thread\n"); 381 | } 382 | } else { 383 | dbgprintf("IOP cmd: Could not create thread\n"); 384 | } 385 | return 0; 386 | } 387 | -------------------------------------------------------------------------------- /ee/ps2regs.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * This file is subject to the terms and conditions of the PS2Link License. 4 | * See the file LICENSE in the main directory of this distribution for more 5 | * details. 6 | */ 7 | 8 | #ifndef PS2REGS_H 9 | #define PS2REGS_H 10 | 11 | /* TIMERS */ 12 | #define T0_COUNT *((volatile unsigned int *)0x10000000) 13 | #define T0_MODE *((volatile unsigned short *)0x10000010) 14 | #define T0_COMP *((volatile unsigned short *)0x10000020) 15 | #define T0_HOLD *((volatile unsigned short *)0x10000030) 16 | 17 | #define T1_COUNT *((volatile unsigned int *)0x10000800) 18 | #define T1_MODE *((volatile unsigned short *)0x10000810) 19 | #define T1_COMP *((volatile unsigned short *)0x10000820) 20 | #define T1_HOLD *((volatile unsigned short *)0x10000830) 21 | 22 | #define T2_COUNT *((volatile unsigned int *)0x10001000) 23 | #define T2_MODE *((volatile unsigned short *)0x10001010) 24 | #define T2_COMP *((volatile unsigned short *)0x10001020) 25 | 26 | #define T3_COUNT *((volatile unsigned int *)0x10001800) 27 | #define T3_MODE *((volatile unsigned short *)0x10001810) 28 | #define T3_COMP *((volatile unsigned short *)0x10001820) 29 | 30 | /* IPU */ 31 | #define IPU_CMD *((volatile unsigned long *)0x10002000) 32 | #define IPU_CTRL *((volatile unsigned int *)0x10002010) 33 | #define IPU_BP *((volatile unsigned int *)0x10002020) 34 | #define IPU_TOP *((volatile unsigned long *)0x10002030) 35 | 36 | /* GIF */ 37 | #define GIF_CTRL *((volatile unsigned int *)0x10003000) 38 | #define GIF_MODE *((volatile unsigned int *)0x10003010) 39 | #define GIF_STAT *((volatile unsigned int *)0x10003020) 40 | 41 | #define GIF_TAG0 *((volatile unsigned int *)0x10003040) 42 | #define GIF_TAG1 *((volatile unsigned int *)0x10003050) 43 | #define GIF_TAG2 *((volatile unsigned int *)0x10003060) 44 | #define GIF_TAG3 *((volatile unsigned int *)0x10003070) 45 | #define GIF_CNT *((volatile unsigned int *)0x10003080) 46 | #define GIF_P3CNT *((volatile unsigned int *)0x10003090) 47 | #define GIF_P3TAG *((volatile unsigned int *)0x100030a0) 48 | 49 | /* VIF */ 50 | #define VIF0_STAT *((volatile unsigned int *)0x10003800) 51 | #define VIF0_FBRST *((volatile unsigned int *)0x10003810) 52 | #define VIF0_ERR *((volatile unsigned int *)0x10003820) 53 | #define VIF0_MARK *((volatile unsigned int *)0x10003830) 54 | #define VIF0_CYCLE *((volatile unsigned int *)0x10003840) 55 | #define VIF0_MODE *((volatile unsigned int *)0x10003850) 56 | #define VIF0_NUM *((volatile unsigned int *)0x10003860) 57 | #define VIF0_MASK *((volatile unsigned int *)0x10003870) 58 | #define VIF0_CODE *((volatile unsigned int *)0x10003880) 59 | #define VIF0_ITOPS *((volatile unsigned int *)0x10003890) 60 | 61 | #define VIF0_ITOP *((volatile unsigned int *)0x100038d0) 62 | 63 | #define VIF0_R0 *((volatile unsigned int *)0x10003900) 64 | #define VIF0_R1 *((volatile unsigned int *)0x10003910) 65 | #define VIF0_R2 *((volatile unsigned int *)0x10003920) 66 | #define VIF0_R3 *((volatile unsigned int *)0x10003930) 67 | #define VIF0_C0 *((volatile unsigned int *)0x10003940) 68 | #define VIF0_C1 *((volatile unsigned int *)0x10003950) 69 | #define VIF0_C2 *((volatile unsigned int *)0x10003960) 70 | #define VIF0_C3 *((volatile unsigned int *)0x10003970) 71 | 72 | #define VIF1_STAT *((volatile unsigned int *)0x10003c00) 73 | #define VIF1_FBRST *((volatile unsigned int *)0x10003c10) 74 | #define VIF1_ERR *((volatile unsigned int *)0x10003c20) 75 | #define VIF1_MARK *((volatile unsigned int *)0x10003c30) 76 | #define VIF1_CYCLE *((volatile unsigned int *)0x10003c40) 77 | #define VIF1_MODE *((volatile unsigned int *)0x10003c50) 78 | #define VIF1_NUM *((volatile unsigned int *)0x10003c60) 79 | #define VIF1_MASK *((volatile unsigned int *)0x10003c70) 80 | #define VIF1_CODE *((volatile unsigned int *)0x10003c80) 81 | #define VIF1_ITOPS *((volatile unsigned int *)0x10003c90) 82 | #define VIF1_BASE *((volatile unsigned int *)0x10003ca0) 83 | #define VIF1_OFST *((volatile unsigned int *)0x10003cb0) 84 | #define VIF1_TOPS *((volatile unsigned int *)0x10003cc0) 85 | #define VIF1_ITOP *((volatile unsigned int *)0x10003cd0) 86 | #define VIF1_TOP *((volatile unsigned int *)0x10003ce0) 87 | 88 | #define VIF1_R0 *((volatile unsigned int *)0x10003d00) 89 | #define VIF1_R1 *((volatile unsigned int *)0x10003d10) 90 | #define VIF1_R2 *((volatile unsigned int *)0x10003d20) 91 | #define VIF1_R3 *((volatile unsigned int *)0x10003d30) 92 | #define VIF1_C0 *((volatile unsigned int *)0x10003d40) 93 | #define VIF1_C1 *((volatile unsigned int *)0x10003d50) 94 | #define VIF1_C2 *((volatile unsigned int *)0x10003d60) 95 | #define VIF1_C3 *((volatile unsigned int *)0x10003d70) 96 | 97 | /* FIFO */ 98 | // #define VIF0_FIFO(write) *((volatile unsigned int128 *)0x10004000) 99 | // #define VIF1_FIFO(read / write) *((volatile unsigned int128 *)0x10005000) 100 | // #define GIF_FIFO(write) *((volatile unsigned int128 *)0x10006000) 101 | // #define IPU_out_FIFO(read) *((volatile unsigned int128 *)0x10007000) 102 | // #define IPU_in_FIFO(write) *((volatile unsigned int128 *)0x10007010) 103 | 104 | /* DMAC */ 105 | #define CHCR 0x00 106 | #define MADR 0x04 107 | #define QWC 0x08 108 | #define TADR 0x0C 109 | #define ASR0 0x10 110 | #define ASR1 0x14 111 | 112 | #define DMA0 ((volatile unsigned int *)0x10008000) 113 | #define DMA1 ((volatile unsigned int *)0x10009000) 114 | #define DMA2 ((volatile unsigned int *)0x1000a000) 115 | #define DMA3 ((volatile unsigned int *)0x1000b000) 116 | #define DMA4 ((volatile unsigned int *)0x1000b400) 117 | #define DMA5 ((volatile unsigned int *)0x1000c000) 118 | #define DMA6 ((volatile unsigned int *)0x1000c400) 119 | #define DMA7 ((volatile unsigned int *)0x1000c800) 120 | #define DMA8 ((volatile unsigned int *)0x1000d000) 121 | #define DMA9 ((volatile unsigned int *)0x1000d400) 122 | 123 | #define D0_CHCR *((volatile unsigned int *)0x10008000) 124 | #define D0_MADR *((volatile unsigned int *)0x10008010) 125 | #define D0_QWC *((volatile unsigned int *)0x10008020) 126 | #define D0_TADR *((volatile unsigned int *)0x10008030) 127 | #define D0_ASR0 *((volatile unsigned int *)0x10008040) 128 | #define D0_ASR1 *((volatile unsigned int *)0x10008050) 129 | 130 | #define D1_CHCR *((volatile unsigned int *)0x10009000) 131 | #define D1_MADR *((volatile unsigned int *)0x10009010) 132 | #define D1_QWC *((volatile unsigned int *)0x10009020) 133 | #define D1_TADR *((volatile unsigned int *)0x10009030) 134 | #define D1_ASR0 *((volatile unsigned int *)0x10009040) 135 | #define D1_ASR1 *((volatile unsigned int *)0x10009050) 136 | 137 | #define D2_CHCR *((volatile unsigned int *)0x1000a000) 138 | #define D2_MADR *((volatile unsigned int *)0x1000a010) 139 | #define D2_QWC *((volatile unsigned int *)0x1000a020) 140 | #define D2_TADR *((volatile unsigned int *)0x1000a030) 141 | #define D2_ASR0 *((volatile unsigned int *)0x1000a040) 142 | #define D2_ASR1 *((volatile unsigned int *)0x1000a050) 143 | 144 | #define D3_CHCR *((volatile unsigned int *)0x1000b000) 145 | #define D3_MADR *((volatile unsigned int *)0x1000b010) 146 | #define D3_QWC *((volatile unsigned int *)0x1000b020) 147 | 148 | #define D4_CHCR *((volatile unsigned int *)0x1000b400) 149 | #define D4_MADR *((volatile unsigned int *)0x1000b410) 150 | #define D4_QWC *((volatile unsigned int *)0x1000b420) 151 | #define D4_TADR *((volatile unsigned int *)0x1000b430) 152 | 153 | #define D5_CHCR *((volatile unsigned int *)0x1000c000) 154 | #define D5_MADR *((volatile unsigned int *)0x1000c010) 155 | #define D5_QWC *((volatile unsigned int *)0x1000c020) 156 | 157 | #define D6_CHCR *((volatile unsigned int *)0x1000c400) 158 | #define D6_MADR *((volatile unsigned int *)0x1000c410) 159 | #define D6_QWC *((volatile unsigned int *)0x1000c420) 160 | 161 | #define D7_CHCR *((volatile unsigned int *)0x1000c800) 162 | #define D7_MADR *((volatile unsigned int *)0x1000c810) 163 | #define D7_QWC *((volatile unsigned int *)0x1000c820) 164 | 165 | #define D8_CHCR *((volatile unsigned int *)0x1000d000) 166 | #define D8_MADR *((volatile unsigned int *)0x1000d010) 167 | #define D8_QWC *((volatile unsigned int *)0x1000d020) 168 | 169 | #define D8_SADR *((volatile unsigned int *)0x1000d080) 170 | 171 | #define D9_CHCR *((volatile unsigned int *)0x1000d400) 172 | #define D9_MADR *((volatile unsigned int *)0x1000d410) 173 | #define D9_QWC *((volatile unsigned int *)0x1000d420) 174 | #define D9_TADR *((volatile unsigned int *)0x1000d430) 175 | 176 | #define D9_SADR *((volatile unsigned int *)0x1000d480) 177 | 178 | /* DMAC */ 179 | #define D_CTRL *((volatile unsigned int *)0x1000e000) 180 | #define D_STAT *((volatile unsigned int *)0x1000e010) 181 | #define D_PCR *((volatile unsigned int *)0x1000e020) 182 | #define D_SQWC *((volatile unsigned int *)0x1000e030) 183 | #define D_RBSR *((volatile unsigned int *)0x1000e040) 184 | #define D_RBOR *((volatile unsigned int *)0x1000e050) 185 | #define D_STADR *((volatile unsigned int *)0x1000e060) 186 | /* INTC */ 187 | // #define I_STAT 0x1000f000 188 | // #define I_MASK 0x1000f010 189 | 190 | /* TOOL putchar */ 191 | // .byte KPUTCHAR(0x1000f180) 192 | /* SIF */ 193 | // #define SB_SMFLG (0x1000f230) 194 | 195 | /* DMAC */ 196 | #define D_ENABLER *((volatile unsigned int *)0x1000f520) 197 | #define D_ENABLEW *((volatile unsigned int *)0x1000f590) 198 | 199 | /* VU Mem */ 200 | #define VUMicroMem0 *((volatile unsigned int *)0x11000000) 201 | #define VUMem0 *((volatile unsigned int *)0x11004000) 202 | #define VUMicroMem1 *((volatile unsigned int *)0x11008000) 203 | #define VUMem1 *((volatile unsigned int *)0x1100c000) 204 | 205 | /* GS Privileged */ 206 | #define GS_PMODE *((volatile unsigned long *)0x12000000) 207 | #define GS_SMODE1 *((volatile unsigned long *)0x12000010) 208 | #define GS_SMODE2 *((volatile unsigned long *)0x12000020) 209 | #define GS_SRFSH *((volatile unsigned long *)0x12000030) 210 | #define GS_SYNCH1 *((volatile unsigned long *)0x12000040) 211 | #define GS_SYNCH2 *((volatile unsigned long *)0x12000050) 212 | #define GS_SYNCV *((volatile unsigned long *)0x12000060) 213 | #define GS_DISPFB1 *((volatile unsigned long *)0x12000070) 214 | #define GS_DISPLAY1 *((volatile unsigned long *)0x12000080) 215 | #define GS_DISPFB2 *((volatile unsigned long *)0x12000090) 216 | #define GS_DISPLAY2 *((volatile unsigned long *)0x120000a0) 217 | #define GS_EXTBUF *((volatile unsigned long *)0x120000b0) 218 | #define GS_EXTDATA *((volatile unsigned long *)0x120000c0) 219 | #define GS_EXTWRITE *((volatile unsigned long *)0x120000d0) 220 | #define GS_BGCOLOR *((volatile unsigned long *)0x120000e0) 221 | 222 | #define GS_CSR *((volatile unsigned long *)0x12001000) 223 | #define GS_IMR *((volatile unsigned long *)0x12001010) 224 | 225 | #define GS_BUSDIR *((volatile unsigned long *)0x12001040) 226 | 227 | #define GS_SIGLBLID *((volatile unsigned long *)0x12001080) 228 | 229 | /* GS General */ 230 | #define GS_PRIM 0x00 231 | #define GS_RGBAQ 0x01 232 | #define GS_ST 0x02 233 | #define GS_UV 0x03 234 | #define GS_XYZF2 0x04 235 | #define GS_XYZ2 0x05 236 | #define GS_TEX0_1 0x06 237 | #define GS_TEX0_2 0x07 238 | #define GS_CLAMP_1 0x08 239 | #define GS_CLAMP_2 0x09 240 | #define GS_FOG 0x0a 241 | #define GS_XYZF3 0x0c 242 | #define GS_XYZ3 0x0d 243 | #define GS_AD 0x0e 244 | #define GS_TEX1_1 0x14 245 | #define GS_TEX1_2 0x15 246 | #define GS_TEX2_1 0x16 247 | #define GS_TEX2_2 0x17 248 | #define GS_XYOFFSET_1 0x18 249 | #define GS_XYOFFSET_2 0x19 250 | #define GS_PRMODECONT 0x1a 251 | #define GS_PRMODE 0x1b 252 | #define GS_TEXCLUT 0x1c 253 | #define GS_SCANMSK 0x22 254 | #define GS_MIPTBP1_1 0x34 255 | #define GS_MIPTBP1_2 0x35 256 | #define GS_MIPTBP2_1 0x36 257 | #define GS_MIPTBP2_2 0x37 258 | #define GS_TEXA 0x3b 259 | #define GS_FOGCOL 0x3d 260 | #define GS_TEXFLUSH 0x3f 261 | #define GS_SCISSOR_1 0x40 262 | #define GS_SCISSOR_2 0x41 263 | #define GS_ALPHA_1 0x42 264 | #define GS_ALPHA_2 0x43 265 | #define GS_DIMX 0x44 266 | #define GS_DTHE 0x45 267 | #define GS_COLCLAMP 0x46 268 | #define GS_TEST_1 0x47 269 | #define GS_TEST_2 0x48 270 | #define GS_PABE 0x49 271 | #define GS_FBA_1 0x4a 272 | #define GS_FBA_2 0x4b 273 | #define GS_FRAME_1 0x4c 274 | #define GS_FRAME_2 0x4d 275 | #define GS_ZBUF_1 0x4e 276 | #define GS_ZBUF_2 0x4f 277 | #define GS_BITBLTBUF 0x50 278 | #define GS_TRXPOS 0x51 279 | #define GS_TRXREG 0x52 280 | #define GS_TRXDIR 0x53 281 | #define GS_HWREG 0x54 282 | #define GS_SIGNAL 0x60 283 | #define GS_FINISH 0x61 284 | #define GS_LABEL 0x62 285 | 286 | #endif 287 | -------------------------------------------------------------------------------- /iop/net_fio.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com) 4 | * This file is subject to the terms and conditions of the PS2Link License. 5 | * See the file LICENSE in the main directory of this distribution for more 6 | * details. 7 | */ 8 | 9 | // Fu*k knows why net_fio & net_fsys are separated.. 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | #include "ps2ip.h" 20 | #include "net_fio.h" 21 | #include "hostlink.h" 22 | #include "globals.h" 23 | 24 | unsigned int remote_pc_addr = 0xffffffff; 25 | 26 | #define PACKET_MAXSIZE 4096 27 | 28 | static char send_packet[PACKET_MAXSIZE] __attribute__((aligned(16))); 29 | static char recv_packet[PACKET_MAXSIZE] __attribute__((aligned(16))); 30 | 31 | static int pko_fileio_sock = -1; 32 | static int pko_fileio_active = 0; 33 | 34 | //---------------------------------------------------------------------- 35 | // 36 | void pko_close_socket(void) 37 | { 38 | int ret; 39 | 40 | ret = disconnect(pko_fileio_sock); 41 | if (ret < 0) { 42 | printf("pko_file: disconnect returned error %d\n", ret); 43 | } 44 | pko_fileio_sock = -1; 45 | } 46 | 47 | //---------------------------------------------------------------------- 48 | // 49 | void pko_close_fsys(void) 50 | { 51 | if (pko_fileio_sock > 0) { 52 | disconnect(pko_fileio_sock); 53 | } 54 | pko_fileio_active = 0; 55 | return; 56 | } 57 | 58 | //---------------------------------------------------------------------- 59 | // XXX: Hm, this func should behave sorta like pko_recv_bytes imho.. 60 | // i.e. check if it was able to send just a part of the packet etc.. 61 | static inline int 62 | pko_lwip_send(int sock, void *buf, int len, int flag) 63 | { 64 | int ret; 65 | ret = send(sock, buf, len, flag); 66 | if (ret < 0) { 67 | dbgprintf("pko_file: lwip_send() error %d\n", ret); 68 | pko_close_socket(); 69 | return -1; 70 | } else { 71 | return ret; 72 | } 73 | } 74 | 75 | 76 | //---------------------------------------------------------------------- 77 | // Do repetetive recv() calles until 'bytes' bytes are received 78 | // or error returned 79 | int pko_recv_bytes(int sock, char *buf, int bytes) 80 | { 81 | int left; 82 | 83 | left = bytes; 84 | 85 | while (left > 0) { 86 | int len; 87 | len = recv(sock, &buf[bytes - left], left, 0); 88 | if (len < 0) { 89 | dbgprintf("pko_file: pko_recv_bytes error!!\n"); 90 | return -1; 91 | } 92 | left -= len; 93 | } 94 | return bytes; 95 | } 96 | 97 | 98 | //---------------------------------------------------------------------- 99 | // Receive a 'packet' of the expected type 'pkt_type', and lenght 'len' 100 | int pko_accept_pkt(int sock, char *buf, int len, int pkt_type) 101 | { 102 | int length; 103 | pko_pkt_hdr *hdr; 104 | unsigned int hcmd; 105 | unsigned short hlen; 106 | 107 | 108 | length = pko_recv_bytes(sock, buf, sizeof(pko_pkt_hdr)); 109 | if (length < 0) { 110 | dbgprintf("pko_file: accept_pkt recv error\n"); 111 | return -1; 112 | } 113 | 114 | if (length < sizeof(pko_pkt_hdr)) { 115 | dbgprintf("pko_file: XXX: did not receive a full header!!!! " 116 | "Fix this! (%d)\n", 117 | length); 118 | } 119 | 120 | hdr = (pko_pkt_hdr *)buf; 121 | hcmd = ntohl(hdr->cmd); 122 | hlen = ntohs(hdr->len); 123 | 124 | if (hcmd != pkt_type) { 125 | dbgprintf("pko_file: pko_accept_pkt: Expected %x, got %x\n", 126 | pkt_type, hcmd); 127 | return 0; 128 | } 129 | 130 | if (hlen > len) { 131 | dbgprintf("pko_file: pko_accept_pkt: hdr->len is too large!! " 132 | "(%d, can only receive %d)\n", 133 | hlen, len); 134 | return 0; 135 | } 136 | 137 | // get the actual packet data 138 | length = pko_recv_bytes(sock, buf + sizeof(pko_pkt_hdr), 139 | hlen - sizeof(pko_pkt_hdr)); 140 | 141 | if (length < 0) { 142 | dbgprintf("pko_file: accept recv2 error!!\n"); 143 | return 0; 144 | } 145 | 146 | if (length < (hlen - sizeof(pko_pkt_hdr))) { 147 | dbgprintf("pko_accept_pkt: Did not receive full packet!!! " 148 | "Fix this! (%d)\n", 149 | length); 150 | } 151 | 152 | return 1; 153 | } 154 | 155 | //---------------------------------------------------------------------- 156 | // 157 | int pko_open_file(char *path, int flags) 158 | { 159 | pko_pkt_open_req *openreq; 160 | pko_pkt_file_rly *openrly; 161 | 162 | if (pko_fileio_sock < 0) { 163 | return -1; 164 | } 165 | 166 | dbgprintf("pko_file: file open req (%s, %x)\n", path, flags); 167 | 168 | openreq = (pko_pkt_open_req *)&send_packet[0]; 169 | 170 | // Build packet 171 | openreq->cmd = htonl(PKO_OPEN_CMD); 172 | openreq->len = htons((unsigned short)sizeof(pko_pkt_open_req)); 173 | openreq->flags = htonl(flags); 174 | strncpy(openreq->path, path, PKO_MAX_PATH); 175 | openreq->path[PKO_MAX_PATH - 1] = 0; // Make sure it's null-terminated 176 | 177 | if (pko_lwip_send(pko_fileio_sock, openreq, sizeof(pko_pkt_open_req), 0) < 0) { 178 | return -1; 179 | } 180 | 181 | if (!pko_accept_pkt(pko_fileio_sock, recv_packet, 182 | sizeof(pko_pkt_file_rly), PKO_OPEN_RLY)) { 183 | dbgprintf("pko_file: pko_open_file: did not receive OPEN_RLY\n"); 184 | return -1; 185 | } 186 | 187 | openrly = (pko_pkt_file_rly *)recv_packet; 188 | 189 | dbgprintf("pko_file: file open reply received (ret %ld)\n", ntohl(openrly->retval)); 190 | 191 | return ntohl(openrly->retval); 192 | } 193 | 194 | 195 | //---------------------------------------------------------------------- 196 | // 197 | int pko_close_file(int fd) 198 | { 199 | pko_pkt_close_req *closereq; 200 | pko_pkt_file_rly *closerly; 201 | 202 | 203 | if (pko_fileio_sock < 0) { 204 | return -1; 205 | } 206 | 207 | dbgprintf("pko_file: file close req (fd: %d)\n", fd); 208 | 209 | closereq = (pko_pkt_close_req *)&send_packet[0]; 210 | closerly = (pko_pkt_file_rly *)&recv_packet[0]; 211 | 212 | closereq->cmd = htonl(PKO_CLOSE_CMD); 213 | closereq->len = htons((unsigned short)sizeof(pko_pkt_close_req)); 214 | closereq->fd = htonl(fd); 215 | 216 | if (pko_lwip_send(pko_fileio_sock, closereq, sizeof(pko_pkt_close_req), 0) < 0) { 217 | return -1; 218 | } 219 | 220 | if (!pko_accept_pkt(pko_fileio_sock, (char *)closerly, 221 | sizeof(pko_pkt_file_rly), PKO_CLOSE_RLY)) { 222 | dbgprintf("pko_file: pko_close_file: did not receive PKO_CLOSE_RLY\n"); 223 | return -1; 224 | } 225 | 226 | dbgprintf("pko_file: pko_close_file: close reply received (ret %ld)\n", 227 | ntohl(closerly->retval)); 228 | 229 | return ntohl(closerly->retval); 230 | } 231 | 232 | //---------------------------------------------------------------------- 233 | // 234 | int pko_lseek_file(int fd, unsigned int offset, int whence) 235 | { 236 | pko_pkt_lseek_req *lseekreq; 237 | pko_pkt_file_rly *lseekrly; 238 | 239 | 240 | if (pko_fileio_sock < 0) { 241 | return -1; 242 | } 243 | 244 | dbgprintf("pko_file: file lseek req (fd: %d)\n", fd); 245 | 246 | lseekreq = (pko_pkt_lseek_req *)&send_packet[0]; 247 | lseekrly = (pko_pkt_file_rly *)&recv_packet[0]; 248 | 249 | lseekreq->cmd = htonl(PKO_LSEEK_CMD); 250 | lseekreq->len = htons((unsigned short)sizeof(pko_pkt_lseek_req)); 251 | lseekreq->fd = htonl(fd); 252 | lseekreq->offset = htonl(offset); 253 | lseekreq->whence = htonl(whence); 254 | 255 | if (pko_lwip_send(pko_fileio_sock, lseekreq, sizeof(pko_pkt_lseek_req), 0) < 0) { 256 | return -1; 257 | } 258 | 259 | if (!pko_accept_pkt(pko_fileio_sock, (char *)lseekrly, 260 | sizeof(pko_pkt_file_rly), PKO_LSEEK_RLY)) { 261 | dbgprintf("pko_file: pko_lseek_file: did not receive PKO_LSEEK_RLY\n"); 262 | return -1; 263 | } 264 | 265 | dbgprintf("pko_file: pko_lseek_file: lseek reply received (ret %ld)\n", 266 | ntohl(lseekrly->retval)); 267 | 268 | return ntohl(lseekrly->retval); 269 | } 270 | 271 | 272 | //---------------------------------------------------------------------- 273 | // 274 | int pko_write_file(int fd, char *buf, int length) 275 | { 276 | pko_pkt_write_req *writecmd; 277 | pko_pkt_file_rly *writerly; 278 | int hlen; 279 | int writtenbytes; 280 | int nbytes; 281 | int retval; 282 | 283 | if (pko_fileio_sock < 0) { 284 | return -1; 285 | } 286 | 287 | dbgprintf("pko_file: file write req (fd: %d)\n", fd); 288 | 289 | writecmd = (pko_pkt_write_req *)&send_packet[0]; 290 | writerly = (pko_pkt_file_rly *)&recv_packet[0]; 291 | 292 | hlen = (unsigned short)sizeof(pko_pkt_write_req); 293 | writecmd->cmd = htonl(PKO_WRITE_CMD); 294 | writecmd->len = htons(hlen); 295 | writecmd->fd = htonl(fd); 296 | 297 | // Divide the write request 298 | writtenbytes = 0; 299 | while (writtenbytes < length) { 300 | 301 | if ((length - writtenbytes) > PKO_MAX_WRITE_SEGMENT) { 302 | // Need to split in several read reqs 303 | nbytes = PKO_MAX_READ_SEGMENT; 304 | } else { 305 | nbytes = length - writtenbytes; 306 | } 307 | 308 | writecmd->nbytes = htonl(nbytes); 309 | #ifdef ZEROCOPY 310 | /* Send the packet header. */ 311 | if (pko_lwip_send(pko_fileio_sock, writecmd, hlen, 0) < 0) 312 | return -1; 313 | /* Send the write() data. */ 314 | if (pko_lwip_send(pko_fileio_sock, &buf[writtenbytes], nbytes, 0) < 0) 315 | return -1; 316 | #else 317 | // Copy data to the acutal packet 318 | memcpy(&send_packet[sizeof(pko_pkt_write_req)], &buf[writtenbytes], 319 | nbytes); 320 | 321 | if (pko_lwip_send(pko_fileio_sock, writecmd, hlen + nbytes, 0) < 0) 322 | return -1; 323 | #endif 324 | 325 | 326 | // Get reply 327 | if (!pko_accept_pkt(pko_fileio_sock, (char *)writerly, 328 | sizeof(pko_pkt_file_rly), PKO_WRITE_RLY)) { 329 | dbgprintf("pko_file: pko_write_file: " 330 | "did not receive PKO_WRITE_RLY\n"); 331 | return -1; 332 | } 333 | retval = ntohl(writerly->retval); 334 | 335 | dbgprintf("pko_file: wrote %d bytes (asked for %d)\n", 336 | retval, nbytes); 337 | 338 | if (retval < 0) { 339 | // Error 340 | dbgprintf("pko_file: pko_write_file: received error on write req (%d)\n", 341 | retval); 342 | return retval; 343 | } 344 | 345 | writtenbytes += retval; 346 | if (retval < nbytes) { 347 | // EOF? 348 | break; 349 | } 350 | } 351 | return writtenbytes; 352 | } 353 | 354 | //---------------------------------------------------------------------- 355 | // 356 | int pko_read_file(int fd, char *buf, int length) 357 | { 358 | int nbytes; 359 | int i; 360 | pko_pkt_read_req *readcmd; 361 | pko_pkt_read_rly *readrly; 362 | 363 | 364 | if (pko_fileio_sock < 0) { 365 | return -1; 366 | } 367 | 368 | readcmd = (pko_pkt_read_req *)&send_packet[0]; 369 | readrly = (pko_pkt_read_rly *)&recv_packet[0]; 370 | 371 | readcmd->cmd = htonl(PKO_READ_CMD); 372 | readcmd->len = htons((unsigned short)sizeof(pko_pkt_read_req)); 373 | readcmd->fd = htonl(fd); 374 | 375 | 376 | if (length < 0) { 377 | dbgprintf("pko_read_file: illegal req!! (whish to read < 0 bytes!)\n"); 378 | return -1; 379 | } 380 | 381 | readcmd->nbytes = htonl(length); 382 | 383 | i = send(pko_fileio_sock, readcmd, sizeof(pko_pkt_read_req), 0); 384 | if (i < 0) { 385 | dbgprintf("pko_file: pko_read_file: send failed (%d)\n", i); 386 | return -1; 387 | } 388 | 389 | if (!pko_accept_pkt(pko_fileio_sock, (char *)readrly, 390 | sizeof(pko_pkt_read_rly), PKO_READ_RLY)) { 391 | dbgprintf("pko_file: pko_read_file: " 392 | "did not receive PKO_READ_RLY\n"); 393 | return -1; 394 | } 395 | 396 | nbytes = ntohl(readrly->nbytes); 397 | dbgprintf("pko_file: pko_read_file: Reply said there's %d bytes to read " 398 | "(wanted %d)\n", 399 | nbytes, length); 400 | 401 | // Now read the actual file data 402 | i = pko_recv_bytes(pko_fileio_sock, &buf[0], nbytes); 403 | if (i < 0) { 404 | dbgprintf("pko_file: pko_read_file, data read error\n"); 405 | return -1; 406 | } 407 | return nbytes; 408 | } 409 | 410 | //---------------------------------------------------------------------- 411 | // 412 | int pko_remove(char *name) 413 | { 414 | pko_pkt_remove_req *removereq; 415 | pko_pkt_file_rly *removerly; 416 | 417 | if (pko_fileio_sock < 0) { 418 | return -1; 419 | } 420 | 421 | dbgprintf("pko_file: file remove req (%s)\n", name); 422 | 423 | removereq = (pko_pkt_remove_req *)&send_packet[0]; 424 | 425 | // Build packet 426 | removereq->cmd = htonl(PKO_REMOVE_CMD); 427 | removereq->len = htons((unsigned short)sizeof(pko_pkt_remove_req)); 428 | strncpy(removereq->name, name, PKO_MAX_PATH); 429 | removereq->name[PKO_MAX_PATH - 1] = 0; // Make sure it's null-terminated 430 | 431 | if (pko_lwip_send(pko_fileio_sock, removereq, sizeof(pko_pkt_remove_req), 0) < 0) { 432 | return -1; 433 | } 434 | 435 | if (!pko_accept_pkt(pko_fileio_sock, recv_packet, 436 | sizeof(pko_pkt_file_rly), PKO_REMOVE_RLY)) { 437 | dbgprintf("pko_file: pko_remove: did not receive REMOVE_RLY\n"); 438 | return -1; 439 | } 440 | 441 | removerly = (pko_pkt_file_rly *)recv_packet; 442 | dbgprintf("pko_file: file remove reply received (ret %ld)\n", ntohl(removerly->retval)); 443 | return ntohl(removerly->retval); 444 | } 445 | 446 | //---------------------------------------------------------------------- 447 | // 448 | int pko_mkdir(char *name, int mode) 449 | { 450 | pko_pkt_mkdir_req *mkdirreq; 451 | pko_pkt_file_rly *mkdirrly; 452 | 453 | if (pko_fileio_sock < 0) { 454 | return -1; 455 | } 456 | 457 | dbgprintf("pko_file: make dir req (%s)\n", name); 458 | 459 | mkdirreq = (pko_pkt_mkdir_req *)&send_packet[0]; 460 | 461 | // Build packet 462 | mkdirreq->cmd = htonl(PKO_MKDIR_CMD); 463 | mkdirreq->len = htons((unsigned short)sizeof(pko_pkt_mkdir_req)); 464 | mkdirreq->mode = mode; 465 | strncpy(mkdirreq->name, name, PKO_MAX_PATH); 466 | mkdirreq->name[PKO_MAX_PATH - 1] = 0; // Make sure it's null-terminated 467 | 468 | if (pko_lwip_send(pko_fileio_sock, mkdirreq, sizeof(pko_pkt_mkdir_req), 0) < 0) { 469 | return -1; 470 | } 471 | 472 | if (!pko_accept_pkt(pko_fileio_sock, recv_packet, 473 | sizeof(pko_pkt_file_rly), PKO_MKDIR_RLY)) { 474 | dbgprintf("pko_file: pko_mkdir: did not receive MKDIR_RLY\n"); 475 | return -1; 476 | } 477 | 478 | mkdirrly = (pko_pkt_file_rly *)recv_packet; 479 | dbgprintf("pko_file: make dir reply received (ret %ld)\n", ntohl(mkdirrly->retval)); 480 | return ntohl(mkdirrly->retval); 481 | } 482 | 483 | //---------------------------------------------------------------------- 484 | // 485 | int pko_rmdir(char *name) 486 | { 487 | pko_pkt_rmdir_req *rmdirreq; 488 | pko_pkt_file_rly *rmdirrly; 489 | 490 | if (pko_fileio_sock < 0) { 491 | return -1; 492 | } 493 | 494 | dbgprintf("pko_file: remove dir req (%s)\n", name); 495 | 496 | rmdirreq = (pko_pkt_rmdir_req *)&send_packet[0]; 497 | 498 | // Build packet 499 | rmdirreq->cmd = htonl(PKO_RMDIR_CMD); 500 | rmdirreq->len = htons((unsigned short)sizeof(pko_pkt_rmdir_req)); 501 | strncpy(rmdirreq->name, name, PKO_MAX_PATH); 502 | rmdirreq->name[PKO_MAX_PATH - 1] = 0; // Make sure it's null-terminated 503 | 504 | if (pko_lwip_send(pko_fileio_sock, rmdirreq, sizeof(pko_pkt_rmdir_req), 0) < 0) { 505 | return -1; 506 | } 507 | 508 | if (!pko_accept_pkt(pko_fileio_sock, recv_packet, 509 | sizeof(pko_pkt_file_rly), PKO_RMDIR_RLY)) { 510 | dbgprintf("pko_file: pko_rmdir: did not receive RMDIR_RLY\n"); 511 | return -1; 512 | } 513 | 514 | rmdirrly = (pko_pkt_file_rly *)recv_packet; 515 | dbgprintf("pko_file: remove dir reply received (ret %ld)\n", ntohl(rmdirrly->retval)); 516 | return ntohl(rmdirrly->retval); 517 | } 518 | 519 | //---------------------------------------------------------------------- 520 | // 521 | int pko_open_dir(char *path) 522 | { 523 | pko_pkt_open_req *openreq; 524 | pko_pkt_file_rly *openrly; 525 | 526 | if (pko_fileio_sock < 0) { 527 | return -1; 528 | } 529 | 530 | dbgprintf("pko_file: dir open req (%s)\n", path); 531 | 532 | openreq = (pko_pkt_open_req *)&send_packet[0]; 533 | 534 | // Build packet 535 | openreq->cmd = htonl(PKO_OPENDIR_CMD); 536 | openreq->len = htons((unsigned short)sizeof(pko_pkt_open_req)); 537 | openreq->flags = htonl(0); 538 | strncpy(openreq->path, path, PKO_MAX_PATH); 539 | openreq->path[PKO_MAX_PATH - 1] = 0; // Make sure it's null-terminated 540 | 541 | if (pko_lwip_send(pko_fileio_sock, openreq, sizeof(pko_pkt_open_req), 0) < 0) { 542 | return -1; 543 | } 544 | 545 | if (!pko_accept_pkt(pko_fileio_sock, recv_packet, 546 | sizeof(pko_pkt_file_rly), PKO_OPENDIR_RLY)) { 547 | dbgprintf("pko_file: pko_open_dir: did not receive OPENDIR_RLY\n"); 548 | return -1; 549 | } 550 | 551 | openrly = (pko_pkt_file_rly *)recv_packet; 552 | 553 | dbgprintf("pko_file: dir open reply received (ret %ld)\n", ntohl(openrly->retval)); 554 | 555 | return ntohl(openrly->retval); 556 | } 557 | 558 | //---------------------------------------------------------------------- 559 | // 560 | int pko_read_dir(int fd, void *buf) 561 | { 562 | pko_pkt_dread_req *dirreq; 563 | pko_pkt_dread_rly *dirrly; 564 | io_dirent_t *dirent; 565 | 566 | if (pko_fileio_sock < 0) { 567 | return -1; 568 | } 569 | 570 | dbgprintf("pko_file: dir read req (%x)\n", fd); 571 | 572 | dirreq = (pko_pkt_dread_req *)&send_packet[0]; 573 | 574 | // Build packet 575 | dirreq->cmd = htonl(PKO_READDIR_CMD); 576 | dirreq->len = htons((unsigned short)sizeof(pko_pkt_dread_req)); 577 | dirreq->fd = htonl(fd); 578 | 579 | if (pko_lwip_send(pko_fileio_sock, dirreq, sizeof(pko_pkt_dread_req), 0) < 0) { 580 | return -1; 581 | } 582 | 583 | if (!pko_accept_pkt(pko_fileio_sock, recv_packet, 584 | sizeof(pko_pkt_dread_rly), PKO_READDIR_RLY)) { 585 | dbgprintf("pko_file: pko_read_dir: did not receive OPENDIR_RLY\n"); 586 | return -1; 587 | } 588 | 589 | dirrly = (pko_pkt_dread_rly *)recv_packet; 590 | 591 | dbgprintf("pko_file: dir read reply received (ret %ld)\n", ntohl(dirrly->retval)); 592 | 593 | dirent = (io_dirent_t *)buf; 594 | // now handle the return buffer translation, to build reply bit 595 | dirent->stat.mode = ntohl(dirrly->mode); 596 | dirent->stat.attr = ntohl(dirrly->attr); 597 | dirent->stat.size = ntohl(dirrly->size); 598 | dirent->stat.hisize = ntohl(dirrly->hisize); 599 | memcpy(dirent->stat.ctime, dirrly->ctime, 8 * 3); 600 | strncpy(dirent->name, dirrly->name, 256); 601 | 602 | return ntohl(dirrly->retval); 603 | } 604 | 605 | 606 | //---------------------------------------------------------------------- 607 | // 608 | int pko_close_dir(int fd) 609 | { 610 | pko_pkt_close_req *closereq; 611 | pko_pkt_file_rly *closerly; 612 | 613 | 614 | if (pko_fileio_sock < 0) { 615 | return -1; 616 | } 617 | 618 | dbgprintf("pko_file: dir close req (fd: %d)\n", fd); 619 | 620 | closereq = (pko_pkt_close_req *)&send_packet[0]; 621 | closerly = (pko_pkt_file_rly *)&recv_packet[0]; 622 | 623 | closereq->cmd = htonl(PKO_CLOSEDIR_CMD); 624 | closereq->len = htons((unsigned short)sizeof(pko_pkt_close_req)); 625 | closereq->fd = htonl(fd); 626 | 627 | if (pko_lwip_send(pko_fileio_sock, closereq, sizeof(pko_pkt_close_req), 0) < 0) { 628 | return -1; 629 | } 630 | 631 | if (!pko_accept_pkt(pko_fileio_sock, (char *)closerly, 632 | sizeof(pko_pkt_file_rly), PKO_CLOSEDIR_RLY)) { 633 | dbgprintf("pko_file: pko_close_dir: did not receive PKO_CLOSEDIR_RLY\n"); 634 | return -1; 635 | } 636 | 637 | dbgprintf("pko_file: dir close reply received (ret %ld)\n", 638 | ntohl(closerly->retval)); 639 | 640 | return ntohl(closerly->retval); 641 | } 642 | 643 | //---------------------------------------------------------------------- 644 | // 645 | int pko_get_stat(const char *name, io_stat_t *stat) 646 | { 647 | pko_pkt_getstat_req *getstatreq; 648 | pko_pkt_getstat_rly *getstatrly; 649 | 650 | if (pko_fileio_sock < 0) { 651 | return -1; 652 | } 653 | 654 | dbgprintf("pko_file: make dir req (%s)\n", name); 655 | 656 | getstatreq = (pko_pkt_getstat_req *)&send_packet[0]; 657 | 658 | // Build packet 659 | getstatreq->cmd = htonl(PKO_GETSTAT_CMD); 660 | getstatreq->len = htons((unsigned short)sizeof(pko_pkt_getstat_req)); 661 | strncpy(getstatreq->name, name, PKO_MAX_PATH); 662 | getstatreq->name[PKO_MAX_PATH - 1] = 0; // Make sure it's null-terminated 663 | 664 | if (pko_lwip_send(pko_fileio_sock, getstatreq, sizeof(pko_pkt_getstat_req), 0) < 0) { 665 | return -1; 666 | } 667 | 668 | if (!pko_accept_pkt(pko_fileio_sock, recv_packet, 669 | sizeof(pko_pkt_getstat_rly), PKO_GETSTAT_RLY)) { 670 | dbgprintf("pko_file: pko_get_stat: did not receive PKO_GETSTAT_RLY\n"); 671 | return -1; 672 | } 673 | 674 | getstatrly = (pko_pkt_getstat_rly *)recv_packet; 675 | 676 | dbgprintf("pko_file: get stat reply received (ret %ld)\n", ntohl(getstatrly->retval)); 677 | if (ntohl(getstatrly->retval) == 0) { 678 | // now handle the return buffer translation, to build reply bit 679 | stat->mode = ntohl(getstatrly->mode); 680 | stat->attr = ntohl(getstatrly->attr); 681 | stat->size = ntohl(getstatrly->size); 682 | stat->hisize = ntohl(getstatrly->hisize); 683 | memcpy(stat->ctime, getstatrly->ctime, 8 * 3); 684 | } 685 | 686 | return ntohl(getstatrly->retval); 687 | } 688 | 689 | //---------------------------------------------------------------------- 690 | // Thread that waits for a PC to connect/disconnect/reconnect blah.. 691 | int pko_file_serv(void *argv) 692 | { 693 | struct sockaddr_in server_addr; 694 | struct sockaddr_in client_addr; 695 | int sock; 696 | int ret; 697 | 698 | dbgprintf(" - PS2 Side application -\n"); 699 | 700 | memset((void *)&server_addr, 0, sizeof(server_addr)); 701 | // Should perhaps specify PC side ip.. 702 | server_addr.sin_family = AF_INET; 703 | server_addr.sin_addr.s_addr = htonl(INADDR_ANY); 704 | server_addr.sin_port = htons(PKO_PORT); 705 | 706 | while ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 707 | dbgprintf("pko_file: socket creation error (%d)\n", sock); 708 | return -1; 709 | } 710 | 711 | ret = bind(sock, (struct sockaddr *)&server_addr, 712 | sizeof(server_addr)); 713 | if (ret < 0) { 714 | dbgprintf("pko_file: bind error (%d)\n", ret); 715 | disconnect(sock); 716 | return -1; 717 | } 718 | 719 | ret = listen(sock, 5); 720 | 721 | if (ret < 0) { 722 | dbgprintf("pko_file: listen error (%d)\n", ret); 723 | disconnect(sock); 724 | return -1; 725 | } 726 | 727 | // Active flag kinda sux, cause it wont be checked until a new client has 728 | // connected.. But it's better than nothing and good for now at least 729 | pko_fileio_active = 1; 730 | 731 | // Connection loop 732 | while (pko_fileio_active) { 733 | int client_len; 734 | int client_sock; 735 | dbgprintf("Waiting for connection\n"); 736 | 737 | client_len = sizeof(client_addr); 738 | client_sock = accept(sock, (struct sockaddr *)&client_addr, 739 | &client_len); 740 | if (client_sock < 0) { 741 | dbgprintf("pko_file: accept error (%d)", client_sock); 742 | continue; 743 | } 744 | 745 | dbgprintf("Client connected from %lx\n", 746 | client_addr.sin_addr.s_addr); 747 | 748 | remote_pc_addr = client_addr.sin_addr.s_addr; 749 | 750 | if (pko_fileio_sock > 0) { 751 | dbgprintf("Client reconnected\n"); 752 | ret = disconnect(pko_fileio_sock); 753 | dbgprintf("close ret %d\n", ret); 754 | } 755 | pko_fileio_sock = client_sock; 756 | } 757 | 758 | if (pko_fileio_sock > 0) { 759 | disconnect(pko_fileio_sock); 760 | } 761 | 762 | disconnect(sock); 763 | 764 | ExitDeleteThread(); 765 | return 0; 766 | } 767 | -------------------------------------------------------------------------------- /ee/cmdHandler.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) 3 | * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com) 4 | * This file is subject to the terms and conditions of the PS2Link License. 5 | * See the file LICENSE in the main directory of this distribution for more 6 | * details. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "excepHandler.h" 23 | #include "byteorder.h" 24 | #include "ps2regs.h" 25 | #include "hostlink.h" 26 | #include "ps2link.h" 27 | #include "globals.h" 28 | 29 | #define STAT_SIF0 0x20 30 | 31 | //////////////////////////////////////////////////////////////////////// 32 | // Prototypes 33 | static int cmdThread(void *arg); 34 | static int pkoExecEE(pko_pkt_execee_req *cmd); 35 | static int pkoStopVU(pko_pkt_stop_vu *); 36 | static int pkoStartVU(pko_pkt_start_vu *); 37 | static int pkoDumpMem(pko_pkt_mem_io *); 38 | static int pkoDumpReg(pko_pkt_dump_regs *); 39 | void pkoReset(void); 40 | static int pkoLoadElf(char *path); 41 | static int pkoGSExec(pko_pkt_gsexec_req *); 42 | static int pkoWriteMem(pko_pkt_mem_io *); 43 | 44 | //////////////////////////////////////////////////////////////////////// 45 | 46 | int userThreadID = 0; 47 | static struct sargs_start userArgs; 48 | static int cmdThreadID = 0; 49 | static char userThreadStack[16 * 1024] __attribute__((aligned(16))); 50 | static char cmdThreadStack[16 * 1024] __attribute__((aligned(64))); 51 | static char dataBuffer[16384] __attribute__((aligned(16))); 52 | 53 | 54 | int sifCmdSema; 55 | int sif0HandlerId = 0; 56 | // XXX: Hardcoded address atm.. Should be configurable!! 57 | unsigned int *sifDmaDataPtr = (unsigned int *)(0x20100000 - 2048); 58 | int excepscrdump = 1; 59 | 60 | 61 | //////////////////////////////////////////////////////////////////////// 62 | // Create the argument struct to send to the user thread 63 | static int makeArgs(int cmdargc, char *cmdargv, struct sargs_start *arg_data) 64 | { 65 | int i; 66 | int t; 67 | 68 | if (cmdargc > MAX_ARGS) 69 | cmdargc = MAX_ARGS; 70 | cmdargv[PKO_MAX_PATH - 1] = '\0'; 71 | 72 | memcpy(arg_data->args.payload, cmdargv, PKO_MAX_PATH); 73 | 74 | dbgprintf("cmd->argc %d, argv[0]: %s\n", cmdargc, cmdargv); 75 | 76 | i = 0; 77 | t = 0; 78 | do { 79 | arg_data->args.argv[i] = &arg_data->args.payload[t]; 80 | dbgprintf("arg_data->args.argv[%d]=%s\n", i, arg_data->args.argv[i]); 81 | dbgprintf("arg_data->args.payload[%d]=%s\n", t, &arg_data->args.payload[t]); 82 | t += strlen(&arg_data->args.payload[t]); 83 | t++; 84 | i++; 85 | } while ((i < cmdargc) && (t < PKO_MAX_PATH)); 86 | 87 | arg_data->args.argc = i; 88 | 89 | return 0; 90 | } 91 | 92 | //////////////////////////////////////////////////////////////////////// 93 | // Load the actual elf, and create a thread for it 94 | // Return the thread id 95 | static int 96 | pkoLoadElf(char *path) 97 | { 98 | ee_thread_t th_attr; 99 | t_ExecData elfdata; 100 | int ret; 101 | int pid; 102 | 103 | ret = SifLoadElf(path, &elfdata); 104 | 105 | if (ret < 0) { 106 | dbgprintf("EE: Could not load ELF file\n"); 107 | return -1; 108 | } 109 | 110 | FlushCache(0); 111 | FlushCache(2); 112 | 113 | dbgprintf("EE: LoadElf returned %d\n", ret); 114 | 115 | dbgprintf("EE: Creating user thread (ent: %x, gp: %x, st: %x)\n", 116 | elfdata.epc, elfdata.gp, elfdata.sp); 117 | 118 | if (elfdata.epc == 0) { 119 | dbgprintf("EE: Could not load file\n"); 120 | return -1; 121 | } 122 | 123 | th_attr.func = (void *)elfdata.epc; 124 | th_attr.stack = userThreadStack; 125 | th_attr.stack_size = sizeof(userThreadStack); 126 | th_attr.gp_reg = (void *)elfdata.gp; 127 | th_attr.initial_priority = 64; 128 | 129 | pid = CreateThread(&th_attr); 130 | if (pid < 0) { 131 | printf("EE: Create user thread failed %d\n", pid); 132 | return -1; 133 | } 134 | 135 | dbgprintf("EE: Created user thread: %d\n", pid); 136 | 137 | return pid; 138 | } 139 | 140 | 141 | //////////////////////////////////////////////////////////////////////// 142 | // Load and start the requested elf 143 | static int 144 | pkoExecEE(pko_pkt_execee_req *cmd) 145 | { 146 | char path[PKO_MAX_PATH]; 147 | int ret; 148 | int pid; 149 | 150 | if (userThreadID) { 151 | return -1; 152 | } 153 | 154 | dbgprintf("EE: Executing file %s...\n", cmd->argv); 155 | memcpy(path, cmd->argv, PKO_MAX_PATH); 156 | 157 | scr_printf("Executing file %s...\n", path); 158 | 159 | pid = pkoLoadElf(path); 160 | if (pid < 0) { 161 | scr_printf("Could not execute file %s\n", path); 162 | return -1; 163 | } 164 | 165 | FlushCache(0); 166 | FlushCache(2); 167 | 168 | userThreadID = pid; 169 | 170 | makeArgs(ntohl(cmd->argc), path, &userArgs); 171 | 172 | // Hack away.. 173 | userArgs.pid = (int)&userThreadID; 174 | 175 | ret = StartThread(userThreadID, &userArgs); 176 | if (ret < 0) { 177 | printf("EE: Start user thread failed %d\n", ret); 178 | cmdThreadID = 0; 179 | DeleteThread(userThreadID); 180 | return -1; 181 | } 182 | return ret; 183 | } 184 | 185 | //////////////////////////////////////////////////////////////////////// 186 | // takes cmd->data and sends it to GIF via path1 187 | static int 188 | pkoGSExec(pko_pkt_gsexec_req *cmd) 189 | { 190 | int fd; 191 | int len; 192 | fd = open((const char *)cmd->file, O_RDONLY); 193 | if (fd < 0) { 194 | return fd; 195 | } 196 | len = read(fd, dataBuffer, 128); 197 | close(fd); 198 | 199 | if (len < 0) { 200 | printf("EE: pkoGSExec failed\n"); 201 | return -1; 202 | } 203 | 204 | // stop/reset dma02 205 | 206 | // dmasend via GIF channel 207 | asm __volatile__( 208 | "move $10, %0;" 209 | "move $11, %1;" 210 | "lui $8, 0x1001;" 211 | "sw $11, -24544($8);" 212 | "sw $10, -24560($8);" 213 | "ori $9, $0, 0x101;" 214 | "sw $9, -24576($8);" 215 | ::"r"(dataBuffer), "r"((ntohs(cmd->size)) / 16)); 216 | 217 | // dmawait for GIF channel 218 | asm __volatile__( 219 | "lui $8, 0x1001;" 220 | "dmawait:" 221 | "lw $9, -24576($8);" 222 | "nop;" 223 | "andi $9, $9, 0x100;" 224 | "nop;" 225 | "bnez $9, dmawait;" 226 | "nop;"); 227 | return 0; 228 | } 229 | 230 | //////////////////////////////////////////////////////////////////////// 231 | // command to dump cmd->size bytes of memory from cmd->offset 232 | static int 233 | pkoDumpMem(pko_pkt_mem_io *cmd) 234 | { 235 | int fd; 236 | int total, len; 237 | unsigned int offset; 238 | unsigned int size; 239 | char path[PKO_MAX_PATH]; 240 | int ret = 0; 241 | size = ntohl(cmd->size); 242 | offset = ntohl(cmd->offset); 243 | scr_printf("dump mem from 0x%x, size %d\n", 244 | ntohl(cmd->offset), ntohl(cmd->size)); 245 | memcpy(path, cmd->argv, PKO_MAX_PATH); 246 | fd = open(path, O_WRONLY | O_CREAT); 247 | total = 0; 248 | len = 16 * 1024; 249 | if (fd > 0) { 250 | while (total < size) { 251 | if (size < len) { 252 | len = size; 253 | } else if ((size - total) < len) { 254 | len = size - total; 255 | } 256 | 257 | memcpy(dataBuffer, (void *)offset, len); 258 | 259 | if ((ret = write(fd, (void *)dataBuffer, len)) > 0) { 260 | } else { 261 | printf("EE: pkoDumpMem() write failed\n"); 262 | return fd; 263 | } 264 | offset = offset + len; 265 | total += len; 266 | } 267 | } 268 | close(fd); 269 | return ret; 270 | } 271 | 272 | static int 273 | pkoWriteMem(pko_pkt_mem_io *cmd) 274 | { 275 | int fd, len, total; 276 | unsigned int offset; 277 | unsigned int size; 278 | char path[PKO_MAX_PATH]; 279 | int ret = 0; 280 | size = ntohl(cmd->size); 281 | offset = ntohl(cmd->offset); 282 | scr_printf("write mem to 0x%x, size %d\n", 283 | ntohl(cmd->offset), ntohl(cmd->size)); 284 | memcpy(path, cmd->argv, PKO_MAX_PATH); 285 | fd = open(path, O_RDONLY); 286 | total = 0; 287 | len = 16 * 1024; 288 | if (fd > 0) { 289 | while (total < size) { 290 | if (size < len) { 291 | len = size; 292 | } else if ((size - total) < len) { 293 | len = size - total; 294 | } 295 | 296 | if ((ret = read(fd, (void *)dataBuffer, len)) > 0) { 297 | } else { 298 | printf("EE: pkoDumpMem() read failed\n"); 299 | return fd; 300 | } 301 | 302 | memcpy((void *)offset, dataBuffer, len); 303 | offset = offset + len; 304 | total += len; 305 | } 306 | } 307 | close(fd); 308 | return ret; 309 | } 310 | 311 | //////////////////////////////////////////////////////////////////////// 312 | // command to dump various registers ( gs|vif|intc etc ) 313 | static int 314 | pkoDumpReg(pko_pkt_dump_regs *cmd) 315 | { 316 | int fd, ret = 0; 317 | char path[PKO_MAX_PATH]; 318 | unsigned int i, j, size; 319 | unsigned int dmaregs[52] = { 320 | 0x1000e000, 0x1000e010, 0x1000e020, 0x1000e030, 321 | 0x1000e040, 0x1000e050, 0x1000e060, 0x1000f520, // Dma common registers 322 | 0x10008000, 0x10008010, 0x10008020, 0x10008030, 0x10008040, 0x10008050, // DMA0 323 | 0x10009000, 0x10009010, 0x10009020, 0x10009030, 0x10009040, 0x10009050, // DMA1 324 | 0x1000a000, 0x1000a010, 0x1000a020, 0x1000a030, 0x1000a040, 0x1000a050, // DMA2 325 | 0x1000b000, 0x1000b010, 0x1000b020, // DMA3 326 | 0x1000b400, 0x1000b410, 0x1000b420, 0x1000b430, // DMA4 327 | 0x1000c000, 0x1000c010, 0x1000c020, // DMA5 328 | 0x1000c400, 0x1000c410, 0x1000c420, 0x1000c430, // DMA6 329 | 0x1000c800, 0x1000c810, 0x1000c820, // DMA7 330 | 0x1000d000, 0x1000d010, 0x1000d020, 0x1000d080, // DMA8 331 | 0x1000d400, 0x1000d410, 0x1000d420, 0x1000d430, 0x1000d480 // DMA9 332 | }; 333 | unsigned int intcregs[2] = { 334 | 0x1000F000, 0x1000F010}; 335 | unsigned int gsregs[2] = { 336 | 0x12001000, 0x12001080}; 337 | unsigned int gifregs[8] = { 338 | 0x10003020, 0x10003040, 0x10003050, 0x10003060, 339 | 0x10003070, 0x10003080, 0x10003090, 0x100030a0}; 340 | unsigned int timerregs[14] = { 341 | 0x10000000, 0x10000010, 0x10000020, 0x10000030, 342 | 0x10000800, 0x10000810, 0x10000820, 0x10000830, 343 | 0x10001000, 0x10001010, 0x10001020, 344 | 0x10001800, 0x10001810, 0x10001820}; 345 | unsigned int sifregs[1] = { 346 | 0x1000F230}; 347 | unsigned int vif0regs[19] = { 348 | 0x10003800, 0x10003810, 0x10003820, 0x10003830, 0x10003840, 349 | 0x10003850, 0x10003860, 0x10003870, 0x10003880, 0x10003890, 350 | 0x100038d0, 0x10003900, 0x10003910, 0x10003920, 0x10003930, 351 | 0x10003940, 0x10003950, 0x10003960, 0x10003970}; 352 | unsigned int vif1regs[23] = { 353 | 0x10003c00, 0x10003c10, 0x10003c20, 0x10003c30, 0x10003c40, 354 | 0x10003c50, 0x10003c60, 0x10003c70, 0x10003c80, 0x10003c90, 355 | 0x10003ca0, 0x10003cb0, 0x10003cc0, 0x10003cd0, 0x10003ce0, 356 | 0x10003d00, 0x10003d10, 0x10003d20, 0x10003d30, 0x10003d40, 357 | 0x10003d50, 0x10003d60, 0x10003d70}; 358 | unsigned int fiforegs[2] = { 359 | 0x10005000, 0x10007000}; 360 | unsigned int ipuregs[4] = { 361 | 0x10002000, 0x10002010, 0x10002020, 0x10002030}; 362 | unsigned int REGALL_SIZE = 363 | sizeof(dmaregs) + sizeof(intcregs) + sizeof(timerregs) + 364 | sizeof(gsregs) + sizeof(sifregs) + sizeof(fiforegs) + 365 | sizeof(gifregs) + sizeof(vif0regs) + sizeof(vif1regs) + 366 | sizeof(ipuregs); 367 | unsigned int regs[REGALL_SIZE]; 368 | 369 | size = 0; 370 | j = 0; 371 | switch (ntohl(cmd->regs)) { 372 | case REGDMA: 373 | for (i = 0; i < sizeof(dmaregs) / 4; i++) { 374 | regs[j++] = *((volatile unsigned int *)dmaregs[i]); 375 | } 376 | size = sizeof(dmaregs); 377 | break; 378 | case REGINTC: 379 | for (i = 0; i < sizeof(intcregs) / 4; i++) { 380 | regs[j++] = *((volatile unsigned int *)intcregs[i]); 381 | } 382 | size = sizeof(intcregs); 383 | break; 384 | case REGTIMER: 385 | for (i = 0; i < sizeof(timerregs) / 4; i++) { 386 | regs[j++] = *((volatile unsigned int *)timerregs[i]); 387 | } 388 | size = sizeof(timerregs); 389 | break; 390 | case REGGS: 391 | for (i = 0; i < sizeof(gsregs) / 4; i++) { 392 | regs[j++] = *((volatile unsigned int *)gsregs[i]); 393 | } 394 | size = sizeof(gsregs); 395 | break; 396 | case REGSIF: 397 | for (i = 0; i < sizeof(sifregs) / 4; i++) { 398 | regs[j++] = *((volatile unsigned int *)sifregs[i]); 399 | } 400 | size = sizeof(sifregs); 401 | break; 402 | case REGFIFO: 403 | for (i = 0; i < sizeof(fiforegs) / 4; i++) { 404 | regs[j++] = *((volatile unsigned int *)fiforegs[i]); 405 | } 406 | size = sizeof(fiforegs); 407 | break; 408 | case REGGIF: 409 | for (i = 0; i < sizeof(gifregs) / 4; i++) { 410 | regs[j++] = *((volatile unsigned int *)gifregs[i]); 411 | } 412 | size = sizeof(gifregs); 413 | break; 414 | case REGVIF0: 415 | for (i = 0; i < sizeof(vif0regs) / 4; i++) { 416 | regs[j++] = *((volatile unsigned int *)vif0regs[i]); 417 | } 418 | size = sizeof(vif0regs); 419 | break; 420 | case REGVIF1: 421 | for (i = 0; i < sizeof(vif1regs) / 4; i++) { 422 | regs[j++] = *((volatile unsigned int *)vif1regs[i]); 423 | } 424 | size = sizeof(vif1regs); 425 | break; 426 | case REGIPU: 427 | for (i = 0; i < sizeof(ipuregs) / 4; i++) { 428 | regs[j++] = *((volatile unsigned int *)ipuregs[i]); 429 | } 430 | size = sizeof(ipuregs); 431 | break; 432 | case REGVU1: 433 | asm __volatile__( 434 | ".set noat;" 435 | // stop VU0 and VU1 436 | "ori $8, $0, 0x101;" 437 | "ctc2 $8, $28;" 438 | "vnop;" 439 | // FIXME remember to save/restore vi1 and vf1 440 | 441 | // Save VU1 floats 442 | "move $8, %0;" // save away dst 443 | "ori $1, $0, 1024;" // start of vu1 mapped floats 444 | "ctc2 $1, $vi1;" // ctc2 t0, vi1 445 | "ori $1, $0, 32;" 446 | "vu1_float_loop:" 447 | "vlqi $vf1, ($vi1++);" 448 | "sqc2 $vf1, 0($8);" 449 | "addiu $1, -1;" 450 | "addiu $8, 16;" 451 | "nop;" 452 | "bnez $1, vu1_float_loop;" 453 | "nop;" 454 | 455 | // Save VU1 Integers 456 | "ori $1, $0, 1056;" 457 | "ctc2 $1, $vi1;" // ctc2 t0, vi1 458 | "ori $1, $0, 16;" 459 | "vu1_int_loop:" 460 | "vlqi $vf1, ($vi1++);" 461 | "sqc2 $vf1, 0($8);" 462 | "addiu $1, -1;" 463 | "addiu $8, 16;" 464 | "nop;" 465 | "bnez $1, vu1_int_loop;" 466 | "nop;" 467 | 468 | // Stop GIF 469 | // Save VU1 Control registers 470 | "ori $1, $0, 1072;" 471 | "ctc2 $1, $vi1;" 472 | "vlqi $vf1, ($vi1++);" 473 | "sqc2 $vf1, 0($8);" 474 | "vlqi $vf1, ($vi1++);" 475 | "sqc2 $vf1, 16($8);" 476 | "vlqi $vf1, ($vi1++);" 477 | "sqc2 $vf1, 32($8);" 478 | "viaddi $vi1, $vi1, 1;" 479 | "vlqi $vf1, ($vi1++);" 480 | "sqc2 $vf1, 48($8);" 481 | "vlqi $vf1, ($vi1++);" 482 | "sqc2 $vf1, 64($8);" 483 | "vlqi $vf1, ($vi1++);" 484 | "sqc2 $vf1, 80($8);" 485 | "vlqi $vf1, ($vi1++);" 486 | "sqc2 $vf1, 96($8);" 487 | "viaddi $vi1, $vi1, 2;" 488 | "vlqi $vf1, ($vi1++);" 489 | "sqc2 $vf1, 112($8);" 490 | 491 | // FIXME remember to save/restore vi1 and vf1 492 | 493 | "ori $8, $0, 0x202;" 494 | "ctc2 $8, $28;" 495 | "vnop;" 496 | :: "r"(regs)); 497 | size = 896; 498 | break; 499 | case REGVU0: 500 | asm __volatile__( 501 | // stop VU0 502 | "ori $8, $0, 0x1;" 503 | "ctc2 $8, $28;" 504 | "vnop;" 505 | // Dump VU0 float registers 506 | "sqc2 $vf0, 0(%0);" 507 | "sqc2 $vf1, 16(%0);" 508 | "sqc2 $vf2, 32(%0);" 509 | "sqc2 $vf3, 48(%0);" 510 | "sqc2 $vf4, 64(%0);" 511 | "sqc2 $vf5, 80(%0);" 512 | "sqc2 $vf6, 96(%0);" 513 | "sqc2 $vf7, 112(%0);" 514 | "sqc2 $vf8, 128(%0);" 515 | "sqc2 $vf9, 144(%0);" 516 | "sqc2 $vf10, 160(%0);" 517 | "sqc2 $vf11, 176(%0);" 518 | "sqc2 $vf12, 192(%0);" 519 | "sqc2 $vf13, 208(%0);" 520 | "sqc2 $vf14, 224(%0);" 521 | "sqc2 $vf15, 240(%0);" 522 | "sqc2 $vf16, 256(%0);" 523 | "sqc2 $vf17, 272(%0);" 524 | "sqc2 $vf18, 288(%0);" 525 | "sqc2 $vf19, 304(%0);" 526 | "sqc2 $vf20, 320(%0);" 527 | "sqc2 $vf21, 336(%0);" 528 | "sqc2 $vf22, 352(%0);" 529 | "sqc2 $vf23, 368(%0);" 530 | "sqc2 $vf24, 384(%0);" 531 | "sqc2 $vf25, 400(%0);" 532 | "sqc2 $vf26, 416(%0);" 533 | "sqc2 $vf27, 432(%0);" 534 | "sqc2 $vf28, 448(%0);" 535 | "sqc2 $vf29, 464(%0);" 536 | "sqc2 $vf30, 480(%0);" 537 | "sqc2 $vf31, 496(%0);" 538 | 539 | // Save VU0 integer registers 540 | "cfc2 $8, $vi0;" 541 | "sq $8, 512(%0);" 542 | "cfc2 $8, $vi1;" 543 | "sq $8, 528(%0);" 544 | "cfc2 $8, $vi2;" 545 | "sq $8, 544(%0);" 546 | "cfc2 $8, $vi3;" 547 | "sq $8, 560(%0);" 548 | "cfc2 $8, $vi4;" 549 | "sq $8, 576(%0);" 550 | "cfc2 $8, $vi5;" 551 | "sq $8, 592(%0);" 552 | "cfc2 $8, $vi6;" 553 | "sq $8, 608(%0);" 554 | "cfc2 $8, $vi7;" 555 | "sq $8, 624(%0);" 556 | "cfc2 $8, $vi8;" 557 | "sq $8, 640(%0);" 558 | "cfc2 $8, $vi9;" 559 | "sq $8, 656(%0);" 560 | "cfc2 $8, $vi10;" 561 | "sq $8, 672(%0);" 562 | "cfc2 $8, $vi11;" 563 | "sq $8, 688(%0);" 564 | "cfc2 $8, $vi12;" 565 | "sq $8, 704(%0);" 566 | "cfc2 $8, $vi13;" 567 | "sq $8, 720(%0);" 568 | "cfc2 $8, $vi14;" 569 | "sq $8, 736(%0);" 570 | "cfc2 $8, $vi15;" 571 | "sq $8, 752(%0);" 572 | 573 | // Reset VU0 574 | "ori $8, $0, 0x2;" 575 | "ctc2 $8, $28;" 576 | "vnop;" 577 | :: "r"(regs)); 578 | size = 896; 579 | break; 580 | case REGALL: 581 | for (i = 0; i < sizeof(dmaregs) / 4; i++) { 582 | regs[j++] = *((volatile unsigned int *)dmaregs[i]); 583 | } 584 | for (i = 0; i < sizeof(intcregs) / 4; i++) { 585 | regs[j++] = *((volatile unsigned int *)intcregs[i]); 586 | } 587 | for (i = 0; i < sizeof(timerregs) / 4; i++) { 588 | regs[j++] = *((volatile unsigned int *)timerregs[i]); 589 | } 590 | for (i = 0; i < sizeof(gsregs) / 4; i++) { 591 | regs[j++] = *((volatile unsigned int *)gsregs[i]); 592 | } 593 | for (i = 0; i < sizeof(sifregs) / 4; i++) { 594 | regs[j++] = *((volatile unsigned int *)sifregs[i]); 595 | } 596 | for (i = 0; i < sizeof(fiforegs) / 4; i++) { 597 | regs[j++] = *((volatile unsigned int *)fiforegs[i]); 598 | } 599 | for (i = 0; i < sizeof(gifregs) / 4; i++) { 600 | regs[j++] = *((volatile unsigned int *)gifregs[i]); 601 | } 602 | for (i = 0; i < sizeof(vif0regs) / 4; i++) { 603 | regs[j++] = *((volatile unsigned int *)vif0regs[i]); 604 | } 605 | for (i = 0; i < sizeof(vif1regs) / 4; i++) { 606 | regs[j++] = *((volatile unsigned int *)vif1regs[i]); 607 | } 608 | for (i = 0; i < sizeof(ipuregs) / 4; i++) { 609 | regs[j++] = *((volatile unsigned int *)ipuregs[i]); 610 | } 611 | size = REGALL_SIZE; 612 | break; 613 | } 614 | 615 | memcpy(path, cmd->argv, PKO_MAX_PATH); 616 | fd = open(path, O_WRONLY | O_CREAT); 617 | if (fd > 0) { 618 | if ((ret = write(fd, regs, size)) > 0) { 619 | } else { 620 | scr_printf("EE: pkoDumpReg() write failed\n"); 621 | return fd; 622 | } 623 | } 624 | close(fd); 625 | return ret; 626 | } 627 | 628 | //////////////////////////////////////////////////////////////////////// 629 | // command to stop VU0/1 and VIF0/1 630 | static int 631 | pkoStopVU(pko_pkt_stop_vu *cmd) 632 | { 633 | if (ntohs(cmd->vpu) == 0) { 634 | asm( 635 | "ori $25, $0, 0x1;" 636 | "ctc2 $25, $28;" 637 | "sync.p;" 638 | "vnop;"); 639 | VIF0_FBRST = 0x2; 640 | } else if (ntohs(cmd->vpu) == 1) { 641 | asm( 642 | "ori $25, $0, 0x100;" 643 | "ctc2 $25, $28;" 644 | "sync.p;" 645 | "vnop;"); 646 | VIF1_FBRST = 0x2; 647 | } 648 | return 0; 649 | } 650 | 651 | //////////////////////////////////////////////////////////////////////// 652 | // command to reset VU0/1 VIF0/1 653 | static int 654 | pkoStartVU(pko_pkt_start_vu *cmd) 655 | { 656 | if (ntohs(cmd->vpu) == 0) { 657 | asm( 658 | "ori $25, $0, 0x2;" 659 | "ctc2 $25, $28;" 660 | "sync.p;" 661 | "vnop;"); 662 | VIF0_FBRST = 0x8; 663 | } else if (ntohs(cmd->vpu) == 1) { 664 | asm( 665 | "ori $25, $0, 0x200;" 666 | "ctc2 $25, $28;" 667 | "sync.p;" 668 | "vnop;"); 669 | VIF1_FBRST = 0x8; 670 | } 671 | return 0; 672 | } 673 | 674 | 675 | //////////////////////////////////////////////////////////////////////// 676 | // Sif dma interrupt handler, wakes up the cmd handler thread if 677 | // data was sent to our dma area 678 | 679 | static int pkoCmdIntrHandler(int channel) 680 | { 681 | int flag; 682 | 683 | flag = *sifDmaDataPtr; 684 | 685 | iSifSetDChain(); 686 | 687 | if (flag) { 688 | // Clear new packet flag 689 | *sifDmaDataPtr = 0; 690 | 691 | iWakeupThread(cmdThreadID); 692 | } 693 | 694 | asm __volatile__("sync"); 695 | asm __volatile__("ei"); 696 | 697 | ExitHandler(); 698 | return 0; 699 | } 700 | 701 | //////////////////////////////////////////////////////////////////////// 702 | // Sif cmd handler thread, waits to be woken by the sif dma intr handler 703 | static int cmdThread(void *arg) 704 | { 705 | int ret; 706 | int done; 707 | 708 | dbgprintf("EE: Cmd thread\n"); 709 | 710 | done = 0; 711 | while (!done) { 712 | unsigned int cmd; 713 | void *pkt; 714 | SleepThread(); 715 | 716 | cmd = ntohl(sifDmaDataPtr[1]); 717 | pkt = &sifDmaDataPtr[1]; 718 | 719 | switch (cmd) { 720 | case PKO_RESET_CMD: 721 | pkoReset(); 722 | ret = 0; 723 | done = 1; 724 | break; 725 | case PKO_NETDUMP_CMD: 726 | excepscrdump = 0; 727 | break; 728 | case PKO_SCRDUMP_CMD: 729 | excepscrdump = 1; 730 | break; 731 | case PKO_EXECEE_CMD: 732 | dbgprintf("EE: Rpc EXECEE called\n"); 733 | ret = pkoExecEE(pkt); 734 | break; 735 | case PKO_START_VU: 736 | dbgprintf("EE: Start VU\n"); 737 | ret = pkoStartVU(pkt); 738 | break; 739 | case PKO_STOP_VU: 740 | dbgprintf("EE: Stop VU\n"); 741 | ret = pkoStopVU(pkt); 742 | break; 743 | case PKO_DUMP_MEM: 744 | dbgprintf("EE: Dump mem\n"); 745 | ret = pkoDumpMem(pkt); 746 | break; 747 | case PKO_DUMP_REG: 748 | dbgprintf("EE: Dump reg\n"); 749 | ret = pkoDumpReg(pkt); 750 | break; 751 | case PKO_GSEXEC_CMD: 752 | dbgprintf("EE: GS Exec\n"); 753 | ret = pkoGSExec(pkt); 754 | break; 755 | case PKO_WRITE_MEM: 756 | dbgprintf("EE: Write Mem\n"); 757 | ret = pkoWriteMem(pkt); 758 | break; 759 | case PKO_IOPEXCEP_CMD: 760 | iopException(sifDmaDataPtr[3], sifDmaDataPtr[4], sifDmaDataPtr[5], sifDmaDataPtr[2], &sifDmaDataPtr[6], sifDmaDataPtr[41], (char *)&sifDmaDataPtr[43]); 761 | break; 762 | default: 763 | printf("EE: Unknown rpc cmd (%x) !\n", cmd); 764 | ret = -1; 765 | } 766 | } 767 | 768 | ExitDeleteThread(); 769 | return ret; 770 | } 771 | 772 | //////////////////////////////////////////////////////////////////////// 773 | // Create cmd thread & install sif dma interrupt handler 774 | int initCmdRpc(void) 775 | { 776 | ee_thread_t th_attr; 777 | int ret; 778 | 779 | th_attr.func = &cmdThread; 780 | th_attr.stack = cmdThreadStack; 781 | th_attr.stack_size = sizeof(cmdThreadStack); 782 | th_attr.gp_reg = &_gp; 783 | th_attr.initial_priority = 20; 784 | 785 | ret = CreateThread(&th_attr); 786 | if (ret < 0) { 787 | printf("EE: initCmdRpc createThread failed %d\n", ret); 788 | return -1; 789 | } 790 | 791 | cmdThreadID = ret; 792 | 793 | ret = StartThread(cmdThreadID, 0); 794 | if (ret < 0) { 795 | printf("EE: initCmdRpc startThread failed %d\n", ret); 796 | cmdThreadID = 0; 797 | DeleteThread(cmdThreadID); 798 | return -1; 799 | } 800 | 801 | // Install our sif dma interrupt handler 802 | FlushCache(0); 803 | sifDmaDataPtr[0] = 0; 804 | 805 | if (_lw(A_EE_D_STAT) & STAT_SIF0) 806 | _sw(STAT_SIF0, A_EE_D_STAT); 807 | 808 | // If SIF0 (IOP -> EE) is not enabled, enable it. 809 | if (!(_lw(A_EE_D5_CHCR) & EE_CHCR_STR)) 810 | SifSetDChain(); 811 | 812 | sif0HandlerId = AddDmacHandler(DMAC_SIF0, &pkoCmdIntrHandler, 0); 813 | EnableDmac(DMAC_SIF0); 814 | return 0; 815 | } 816 | 817 | //////////////////////////////////////////////////////////////////////// 818 | void pkoReset(void) 819 | { 820 | char *argv[1]; 821 | // Check if user thread is running, if so kill it 822 | if (userThreadID) { 823 | TerminateThread(userThreadID); 824 | DeleteThread(userThreadID); 825 | } 826 | userThreadID = 0; 827 | 828 | if (sif0HandlerId >= 0) { 829 | DisableDmac(DMAC_SIF0); 830 | RemoveDmacHandler(DMAC_SIF0, sif0HandlerId); 831 | } 832 | 833 | SifInitRpc(0); 834 | SifExitRpc(); 835 | 836 | SifIopReset(NULL, 0); 837 | while (SifIopSync()) 838 | ; 839 | 840 | SifInitRpc(0); 841 | SifExitRpc(); 842 | 843 | argv[0] = elfName; 844 | SifLoadFileExit(); 845 | 846 | ExecPS2(&__start, 0, 1, argv); 847 | } 848 | -------------------------------------------------------------------------------- /doxy.conf: -------------------------------------------------------------------------------- 1 | # Doxyfile 1.3.5 2 | 3 | # This file describes the settings to be used by the documentation system 4 | # doxygen (www.doxygen.org) for a project 5 | # 6 | # All text after a hash (#) is considered a comment and will be ignored 7 | # The format is: 8 | # TAG = value [value, ...] 9 | # For lists items can also be appended using: 10 | # TAG += value [value, ...] 11 | # Values that contain spaces should be placed between quotes (" ") 12 | 13 | #--------------------------------------------------------------------------- 14 | # Project related configuration options 15 | #--------------------------------------------------------------------------- 16 | 17 | # The PROJECT_NAME tag is a single word (or a sequence of words surrounded 18 | # by quotes) that should identify the project. 19 | 20 | PROJECT_NAME = ps2link 21 | 22 | # The PROJECT_NUMBER tag can be used to enter a project or revision number. 23 | # This could be handy for archiving the generated documentation or 24 | # if some version control system is used. 25 | 26 | PROJECT_NUMBER = 1.2 27 | 28 | # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 29 | # base path where the generated documentation will be put. 30 | # If a relative path is entered, it will be relative to the location 31 | # where doxygen was started. If left blank the current directory will be used. 32 | 33 | OUTPUT_DIRECTORY = ps2link-doc 34 | 35 | # The OUTPUT_LANGUAGE tag is used to specify the language in which all 36 | # documentation generated by doxygen is written. Doxygen will use this 37 | # information to generate all constant output in the proper language. 38 | # The default language is English, other supported languages are: 39 | # Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, 40 | # Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en 41 | # (Japanese with English messages), Korean, Norwegian, Polish, Portuguese, 42 | # Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. 43 | 44 | OUTPUT_LANGUAGE = English 45 | 46 | # This tag can be used to specify the encoding used in the generated output. 47 | # The encoding is not always determined by the language that is chosen, 48 | # but also whether or not the output is meant for Windows or non-Windows users. 49 | # In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 50 | # forces the Windows encoding (this is the default for the Windows binary), 51 | # whereas setting the tag to NO uses a Unix-style encoding (the default for 52 | # all platforms other than Windows). 53 | 54 | USE_WINDOWS_ENCODING = NO 55 | 56 | # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 57 | # include brief member descriptions after the members that are listed in 58 | # the file and class documentation (similar to JavaDoc). 59 | # Set to NO to disable this. 60 | 61 | BRIEF_MEMBER_DESC = YES 62 | 63 | # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 64 | # the brief description of a member or function before the detailed description. 65 | # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 66 | # brief descriptions will be completely suppressed. 67 | 68 | REPEAT_BRIEF = YES 69 | 70 | # This tag implements a quasi-intelligent brief description abbreviator 71 | # that is used to form the text in various listings. Each string 72 | # in this list, if found as the leading text of the brief description, will be 73 | # stripped from the text and the result after processing the whole list, is used 74 | # as the annotated text. Otherwise, the brief description is used as-is. If left 75 | # blank, the following values are used ("$name" is automatically replaced with the 76 | # name of the entity): "The $name class" "The $name widget" "The $name file" 77 | # "is" "provides" "specifies" "contains" "represents" "a" "an" "the" 78 | 79 | ABBREVIATE_BRIEF = 80 | 81 | # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 82 | # Doxygen will generate a detailed section even if there is only a brief 83 | # description. 84 | 85 | ALWAYS_DETAILED_SEC = NO 86 | 87 | # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited 88 | # members of a class in the documentation of that class as if those members were 89 | # ordinary class members. Constructors, destructors and assignment operators of 90 | # the base classes will not be shown. 91 | 92 | INLINE_INHERITED_MEMB = NO 93 | 94 | # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 95 | # path before files name in the file list and in the header files. If set 96 | # to NO the shortest path that makes the file name unique will be used. 97 | 98 | FULL_PATH_NAMES = NO 99 | 100 | # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 101 | # can be used to strip a user-defined part of the path. Stripping is 102 | # only done if one of the specified strings matches the left-hand part of 103 | # the path. It is allowed to use relative paths in the argument list. 104 | 105 | STRIP_FROM_PATH = 106 | 107 | # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 108 | # (but less readable) file names. This can be useful is your file systems 109 | # doesn't support long names like on DOS, Mac, or CD-ROM. 110 | 111 | SHORT_NAMES = NO 112 | 113 | # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 114 | # will interpret the first line (until the first dot) of a JavaDoc-style 115 | # comment as the brief description. If set to NO, the JavaDoc 116 | # comments will behave just like the Qt-style comments (thus requiring an 117 | # explicit @brief command for a brief description. 118 | 119 | JAVADOC_AUTOBRIEF = YES 120 | 121 | # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 122 | # treat a multi-line C++ special comment block (i.e. a block of //! or /// 123 | # comments) as a brief description. This used to be the default behaviour. 124 | # The new default is to treat a multi-line C++ comment block as a detailed 125 | # description. Set this tag to YES if you prefer the old behaviour instead. 126 | 127 | MULTILINE_CPP_IS_BRIEF = NO 128 | 129 | # If the DETAILS_AT_TOP tag is set to YES then Doxygen 130 | # will output the detailed description near the top, like JavaDoc. 131 | # If set to NO, the detailed description appears after the member 132 | # documentation. 133 | 134 | DETAILS_AT_TOP = YES 135 | 136 | # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 137 | # member inherits the documentation from any documented member that it 138 | # re-implements. 139 | 140 | INHERIT_DOCS = YES 141 | 142 | # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 143 | # tag is set to YES, then doxygen will reuse the documentation of the first 144 | # member in the group (if any) for the other members of the group. By default 145 | # all members of a group must be documented explicitly. 146 | 147 | DISTRIBUTE_GROUP_DOC = NO 148 | 149 | # The TAB_SIZE tag can be used to set the number of spaces in a tab. 150 | # Doxygen uses this value to replace tabs by spaces in code fragments. 151 | 152 | TAB_SIZE = 8 153 | 154 | # This tag can be used to specify a number of aliases that acts 155 | # as commands in the documentation. An alias has the form "name=value". 156 | # For example adding "sideeffect=\par Side Effects:\n" will allow you to 157 | # put the command \sideeffect (or @sideeffect) in the documentation, which 158 | # will result in a user-defined paragraph with heading "Side Effects:". 159 | # You can put \n's in the value part of an alias to insert newlines. 160 | 161 | ALIASES = 162 | 163 | # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources 164 | # only. Doxygen will then generate output that is more tailored for C. 165 | # For instance, some of the names that are used will be different. The list 166 | # of all members will be omitted, etc. 167 | 168 | OPTIMIZE_OUTPUT_FOR_C = YES 169 | 170 | # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 171 | # only. Doxygen will then generate output that is more tailored for Java. 172 | # For instance, namespaces will be presented as packages, qualified scopes 173 | # will look different, etc. 174 | 175 | OPTIMIZE_OUTPUT_JAVA = NO 176 | 177 | # Set the SUBGROUPING tag to YES (the default) to allow class member groups of 178 | # the same type (for instance a group of public functions) to be put as a 179 | # subgroup of that type (e.g. under the Public Functions section). Set it to 180 | # NO to prevent subgrouping. Alternatively, this can be done per class using 181 | # the \nosubgrouping command. 182 | 183 | SUBGROUPING = YES 184 | 185 | #--------------------------------------------------------------------------- 186 | # Build related configuration options 187 | #--------------------------------------------------------------------------- 188 | 189 | # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 190 | # documentation are documented, even if no documentation was available. 191 | # Private class members and static file members will be hidden unless 192 | # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES 193 | 194 | EXTRACT_ALL = YES 195 | 196 | # If the EXTRACT_PRIVATE tag is set to YES all private members of a class 197 | # will be included in the documentation. 198 | 199 | EXTRACT_PRIVATE = NO 200 | 201 | # If the EXTRACT_STATIC tag is set to YES all static members of a file 202 | # will be included in the documentation. 203 | 204 | EXTRACT_STATIC = NO 205 | 206 | # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 207 | # defined locally in source files will be included in the documentation. 208 | # If set to NO only classes defined in header files are included. 209 | 210 | EXTRACT_LOCAL_CLASSES = YES 211 | 212 | # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 213 | # undocumented members of documented classes, files or namespaces. 214 | # If set to NO (the default) these members will be included in the 215 | # various overviews, but no documentation section is generated. 216 | # This option has no effect if EXTRACT_ALL is enabled. 217 | 218 | HIDE_UNDOC_MEMBERS = NO 219 | 220 | # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 221 | # undocumented classes that are normally visible in the class hierarchy. 222 | # If set to NO (the default) these classes will be included in the various 223 | # overviews. This option has no effect if EXTRACT_ALL is enabled. 224 | 225 | HIDE_UNDOC_CLASSES = NO 226 | 227 | # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 228 | # friend (class|struct|union) declarations. 229 | # If set to NO (the default) these declarations will be included in the 230 | # documentation. 231 | 232 | HIDE_FRIEND_COMPOUNDS = NO 233 | 234 | # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 235 | # documentation blocks found inside the body of a function. 236 | # If set to NO (the default) these blocks will be appended to the 237 | # function's detailed documentation block. 238 | 239 | HIDE_IN_BODY_DOCS = NO 240 | 241 | # The INTERNAL_DOCS tag determines if documentation 242 | # that is typed after a \internal command is included. If the tag is set 243 | # to NO (the default) then the documentation will be excluded. 244 | # Set it to YES to include the internal documentation. 245 | 246 | INTERNAL_DOCS = NO 247 | 248 | # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 249 | # file names in lower-case letters. If set to YES upper-case letters are also 250 | # allowed. This is useful if you have classes or files whose names only differ 251 | # in case and if your file system supports case sensitive file names. Windows 252 | # users are advised to set this option to NO. 253 | 254 | CASE_SENSE_NAMES = YES 255 | 256 | # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 257 | # will show members with their full class and namespace scopes in the 258 | # documentation. If set to YES the scope will be hidden. 259 | 260 | HIDE_SCOPE_NAMES = NO 261 | 262 | # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 263 | # will put a list of the files that are included by a file in the documentation 264 | # of that file. 265 | 266 | SHOW_INCLUDE_FILES = YES 267 | 268 | # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 269 | # is inserted in the documentation for inline members. 270 | 271 | INLINE_INFO = YES 272 | 273 | # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 274 | # will sort the (detailed) documentation of file and class members 275 | # alphabetically by member name. If set to NO the members will appear in 276 | # declaration order. 277 | 278 | SORT_MEMBER_DOCS = YES 279 | 280 | # The GENERATE_TODOLIST tag can be used to enable (YES) or 281 | # disable (NO) the todo list. This list is created by putting \todo 282 | # commands in the documentation. 283 | 284 | GENERATE_TODOLIST = YES 285 | 286 | # The GENERATE_TESTLIST tag can be used to enable (YES) or 287 | # disable (NO) the test list. This list is created by putting \test 288 | # commands in the documentation. 289 | 290 | GENERATE_TESTLIST = YES 291 | 292 | # The GENERATE_BUGLIST tag can be used to enable (YES) or 293 | # disable (NO) the bug list. This list is created by putting \bug 294 | # commands in the documentation. 295 | 296 | GENERATE_BUGLIST = YES 297 | 298 | # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 299 | # disable (NO) the deprecated list. This list is created by putting 300 | # \deprecated commands in the documentation. 301 | 302 | GENERATE_DEPRECATEDLIST= YES 303 | 304 | # The ENABLED_SECTIONS tag can be used to enable conditional 305 | # documentation sections, marked by \if sectionname ... \endif. 306 | 307 | ENABLED_SECTIONS = 308 | 309 | # The MAX_INITIALIZER_LINES tag determines the maximum number of lines 310 | # the initial value of a variable or define consists of for it to appear in 311 | # the documentation. If the initializer consists of more lines than specified 312 | # here it will be hidden. Use a value of 0 to hide initializers completely. 313 | # The appearance of the initializer of individual variables and defines in the 314 | # documentation can be controlled using \showinitializer or \hideinitializer 315 | # command in the documentation regardless of this setting. 316 | 317 | MAX_INITIALIZER_LINES = 30 318 | 319 | # Set the SHOW_USED_FILES tag to NO to disable the list of files generated 320 | # at the bottom of the documentation of classes and structs. If set to YES the 321 | # list will mention the files that were used to generate the documentation. 322 | 323 | SHOW_USED_FILES = YES 324 | 325 | #--------------------------------------------------------------------------- 326 | # configuration options related to warning and progress messages 327 | #--------------------------------------------------------------------------- 328 | 329 | # The QUIET tag can be used to turn on/off the messages that are generated 330 | # by doxygen. Possible values are YES and NO. If left blank NO is used. 331 | 332 | QUIET = NO 333 | 334 | # The WARNINGS tag can be used to turn on/off the warning messages that are 335 | # generated by doxygen. Possible values are YES and NO. If left blank 336 | # NO is used. 337 | 338 | WARNINGS = YES 339 | 340 | # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 341 | # for undocumented members. If EXTRACT_ALL is set to YES then this flag will 342 | # automatically be disabled. 343 | 344 | WARN_IF_UNDOCUMENTED = YES 345 | 346 | # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 347 | # potential errors in the documentation, such as not documenting some 348 | # parameters in a documented function, or documenting parameters that 349 | # don't exist or using markup commands wrongly. 350 | 351 | WARN_IF_DOC_ERROR = YES 352 | 353 | # The WARN_FORMAT tag determines the format of the warning messages that 354 | # doxygen can produce. The string should contain the $file, $line, and $text 355 | # tags, which will be replaced by the file and line number from which the 356 | # warning originated and the warning text. 357 | 358 | WARN_FORMAT = "$file:$line: $text" 359 | 360 | # The WARN_LOGFILE tag can be used to specify a file to which warning 361 | # and error messages should be written. If left blank the output is written 362 | # to stderr. 363 | 364 | WARN_LOGFILE = warn.log 365 | 366 | #--------------------------------------------------------------------------- 367 | # configuration options related to the input files 368 | #--------------------------------------------------------------------------- 369 | 370 | # The INPUT tag can be used to specify the files and/or directories that contain 371 | # documented source files. You may enter file names like "myfile.cpp" or 372 | # directories like "/usr/src/myproject". Separate the files or directories 373 | # with spaces. 374 | 375 | INPUT = 376 | 377 | # If the value of the INPUT tag contains directories, you can use the 378 | # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 379 | # and *.h) to filter out the source-files in the directories. If left 380 | # blank the following patterns are tested: 381 | # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp 382 | # *.h++ *.idl *.odl *.cs *.php *.php3 *.inc 383 | 384 | FILE_PATTERNS = 385 | 386 | # The RECURSIVE tag can be used to turn specify whether or not subdirectories 387 | # should be searched for input files as well. Possible values are YES and NO. 388 | # If left blank NO is used. 389 | 390 | RECURSIVE = YES 391 | 392 | # The EXCLUDE tag can be used to specify files and/or directories that should 393 | # excluded from the INPUT source files. This way you can easily exclude a 394 | # subdirectory from a directory tree whose root is specified with the INPUT tag. 395 | 396 | EXCLUDE = 397 | 398 | # The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories 399 | # that are symbolic links (a Unix filesystem feature) are excluded from the input. 400 | 401 | EXCLUDE_SYMLINKS = NO 402 | 403 | # If the value of the INPUT tag contains directories, you can use the 404 | # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 405 | # certain files from those directories. 406 | 407 | EXCLUDE_PATTERNS = */samples/* 408 | 409 | # The EXAMPLE_PATH tag can be used to specify one or more files or 410 | # directories that contain example code fragments that are included (see 411 | # the \include command). 412 | 413 | EXAMPLE_PATH = 414 | 415 | # If the value of the EXAMPLE_PATH tag contains directories, you can use the 416 | # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 417 | # and *.h) to filter out the source-files in the directories. If left 418 | # blank all files are included. 419 | 420 | EXAMPLE_PATTERNS = 421 | 422 | # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 423 | # searched for input files to be used with the \include or \dontinclude 424 | # commands irrespective of the value of the RECURSIVE tag. 425 | # Possible values are YES and NO. If left blank NO is used. 426 | 427 | EXAMPLE_RECURSIVE = NO 428 | 429 | # The IMAGE_PATH tag can be used to specify one or more files or 430 | # directories that contain image that are included in the documentation (see 431 | # the \image command). 432 | 433 | IMAGE_PATH = 434 | 435 | # The INPUT_FILTER tag can be used to specify a program that doxygen should 436 | # invoke to filter for each input file. Doxygen will invoke the filter program 437 | # by executing (via popen()) the command , where 438 | # is the value of the INPUT_FILTER tag, and is the name of an 439 | # input file. Doxygen will then use the output that the filter program writes 440 | # to standard output. 441 | 442 | INPUT_FILTER = 443 | 444 | # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 445 | # INPUT_FILTER) will be used to filter the input files when producing source 446 | # files to browse (i.e. when SOURCE_BROWSER is set to YES). 447 | 448 | FILTER_SOURCE_FILES = NO 449 | 450 | #--------------------------------------------------------------------------- 451 | # configuration options related to source browsing 452 | #--------------------------------------------------------------------------- 453 | 454 | # If the SOURCE_BROWSER tag is set to YES then a list of source files will 455 | # be generated. Documented entities will be cross-referenced with these sources. 456 | # Note: To get rid of all source code in the generated output, make sure also 457 | # VERBATIM_HEADERS is set to NO. 458 | 459 | SOURCE_BROWSER = NO 460 | 461 | # Setting the INLINE_SOURCES tag to YES will include the body 462 | # of functions and classes directly in the documentation. 463 | 464 | INLINE_SOURCES = NO 465 | 466 | # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 467 | # doxygen to hide any special comment blocks from generated source code 468 | # fragments. Normal C and C++ comments will always remain visible. 469 | 470 | STRIP_CODE_COMMENTS = YES 471 | 472 | # If the REFERENCED_BY_RELATION tag is set to YES (the default) 473 | # then for each documented function all documented 474 | # functions referencing it will be listed. 475 | 476 | REFERENCED_BY_RELATION = YES 477 | 478 | # If the REFERENCES_RELATION tag is set to YES (the default) 479 | # then for each documented function all documented entities 480 | # called/used by that function will be listed. 481 | 482 | REFERENCES_RELATION = YES 483 | 484 | # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 485 | # will generate a verbatim copy of the header file for each class for 486 | # which an include is specified. Set to NO to disable this. 487 | 488 | VERBATIM_HEADERS = YES 489 | 490 | #--------------------------------------------------------------------------- 491 | # configuration options related to the alphabetical class index 492 | #--------------------------------------------------------------------------- 493 | 494 | # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 495 | # of all compounds will be generated. Enable this if the project 496 | # contains a lot of classes, structs, unions or interfaces. 497 | 498 | ALPHABETICAL_INDEX = NO 499 | 500 | # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 501 | # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 502 | # in which this list will be split (can be a number in the range [1..20]) 503 | 504 | COLS_IN_ALPHA_INDEX = 5 505 | 506 | # In case all classes in a project start with a common prefix, all 507 | # classes will be put under the same header in the alphabetical index. 508 | # The IGNORE_PREFIX tag can be used to specify one or more prefixes that 509 | # should be ignored while generating the index headers. 510 | 511 | IGNORE_PREFIX = 512 | 513 | #--------------------------------------------------------------------------- 514 | # configuration options related to the HTML output 515 | #--------------------------------------------------------------------------- 516 | 517 | # If the GENERATE_HTML tag is set to YES (the default) Doxygen will 518 | # generate HTML output. 519 | 520 | GENERATE_HTML = YES 521 | 522 | # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 523 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 524 | # put in front of it. If left blank `html' will be used as the default path. 525 | 526 | HTML_OUTPUT = html 527 | 528 | # The HTML_FILE_EXTENSION tag can be used to specify the file extension for 529 | # each generated HTML page (for example: .htm,.php,.asp). If it is left blank 530 | # doxygen will generate files with .html extension. 531 | 532 | HTML_FILE_EXTENSION = .html 533 | 534 | # The HTML_HEADER tag can be used to specify a personal HTML header for 535 | # each generated HTML page. If it is left blank doxygen will generate a 536 | # standard header. 537 | 538 | HTML_HEADER = 539 | 540 | # The HTML_FOOTER tag can be used to specify a personal HTML footer for 541 | # each generated HTML page. If it is left blank doxygen will generate a 542 | # standard footer. 543 | 544 | HTML_FOOTER = 545 | 546 | # The HTML_STYLESHEET tag can be used to specify a user-defined cascading 547 | # style sheet that is used by each HTML page. It can be used to 548 | # fine-tune the look of the HTML output. If the tag is left blank doxygen 549 | # will generate a default style sheet. Note that doxygen will try to copy 550 | # the style sheet file to the HTML output directory, so don't put your own 551 | # stylesheet in the HTML output directory as well, or it will be erased! 552 | 553 | HTML_STYLESHEET = 554 | 555 | # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 556 | # files or namespaces will be aligned in HTML using tables. If set to 557 | # NO a bullet list will be used. 558 | 559 | HTML_ALIGN_MEMBERS = YES 560 | 561 | # If the GENERATE_HTMLHELP tag is set to YES, additional index files 562 | # will be generated that can be used as input for tools like the 563 | # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 564 | # of the generated HTML documentation. 565 | 566 | GENERATE_HTMLHELP = NO 567 | 568 | # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 569 | # be used to specify the file name of the resulting .chm file. You 570 | # can add a path in front of the file if the result should not be 571 | # written to the html output directory. 572 | 573 | CHM_FILE = 574 | 575 | # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 576 | # be used to specify the location (absolute path including file name) of 577 | # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 578 | # the HTML help compiler on the generated index.hhp. 579 | 580 | HHC_LOCATION = 581 | 582 | # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 583 | # controls if a separate .chi index file is generated (YES) or that 584 | # it should be included in the master .chm file (NO). 585 | 586 | GENERATE_CHI = NO 587 | 588 | # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 589 | # controls whether a binary table of contents is generated (YES) or a 590 | # normal table of contents (NO) in the .chm file. 591 | 592 | BINARY_TOC = NO 593 | 594 | # The TOC_EXPAND flag can be set to YES to add extra items for group members 595 | # to the contents of the HTML help documentation and to the tree view. 596 | 597 | TOC_EXPAND = NO 598 | 599 | # The DISABLE_INDEX tag can be used to turn on/off the condensed index at 600 | # top of each HTML page. The value NO (the default) enables the index and 601 | # the value YES disables it. 602 | 603 | DISABLE_INDEX = NO 604 | 605 | # This tag can be used to set the number of enum values (range [1..20]) 606 | # that doxygen will group on one line in the generated HTML documentation. 607 | 608 | ENUM_VALUES_PER_LINE = 4 609 | 610 | # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be 611 | # generated containing a tree-like index structure (just like the one that 612 | # is generated for HTML Help). For this to work a browser that supports 613 | # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 614 | # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 615 | # probably better off using the HTML help feature. 616 | 617 | GENERATE_TREEVIEW = NO 618 | 619 | # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 620 | # used to set the initial width (in pixels) of the frame in which the tree 621 | # is shown. 622 | 623 | TREEVIEW_WIDTH = 250 624 | 625 | #--------------------------------------------------------------------------- 626 | # configuration options related to the LaTeX output 627 | #--------------------------------------------------------------------------- 628 | 629 | # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 630 | # generate Latex output. 631 | 632 | GENERATE_LATEX = NO 633 | 634 | # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 635 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 636 | # put in front of it. If left blank `latex' will be used as the default path. 637 | 638 | LATEX_OUTPUT = latex 639 | 640 | # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 641 | # invoked. If left blank `latex' will be used as the default command name. 642 | 643 | LATEX_CMD_NAME = latex 644 | 645 | # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 646 | # generate index for LaTeX. If left blank `makeindex' will be used as the 647 | # default command name. 648 | 649 | MAKEINDEX_CMD_NAME = makeindex 650 | 651 | # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 652 | # LaTeX documents. This may be useful for small projects and may help to 653 | # save some trees in general. 654 | 655 | COMPACT_LATEX = NO 656 | 657 | # The PAPER_TYPE tag can be used to set the paper type that is used 658 | # by the printer. Possible values are: a4, a4wide, letter, legal and 659 | # executive. If left blank a4wide will be used. 660 | 661 | PAPER_TYPE = a4wide 662 | 663 | # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 664 | # packages that should be included in the LaTeX output. 665 | 666 | EXTRA_PACKAGES = 667 | 668 | # The LATEX_HEADER tag can be used to specify a personal LaTeX header for 669 | # the generated latex document. The header should contain everything until 670 | # the first chapter. If it is left blank doxygen will generate a 671 | # standard header. Notice: only use this tag if you know what you are doing! 672 | 673 | LATEX_HEADER = 674 | 675 | # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 676 | # is prepared for conversion to pdf (using ps2pdf). The pdf file will 677 | # contain links (just like the HTML output) instead of page references 678 | # This makes the output suitable for online browsing using a pdf viewer. 679 | 680 | PDF_HYPERLINKS = NO 681 | 682 | # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 683 | # plain latex in the generated Makefile. Set this option to YES to get a 684 | # higher quality PDF documentation. 685 | 686 | USE_PDFLATEX = NO 687 | 688 | # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 689 | # command to the generated LaTeX files. This will instruct LaTeX to keep 690 | # running if errors occur, instead of asking the user for help. 691 | # This option is also used when generating formulas in HTML. 692 | 693 | LATEX_BATCHMODE = NO 694 | 695 | # If LATEX_HIDE_INDICES is set to YES then doxygen will not 696 | # include the index chapters (such as File Index, Compound Index, etc.) 697 | # in the output. 698 | 699 | LATEX_HIDE_INDICES = NO 700 | 701 | #--------------------------------------------------------------------------- 702 | # configuration options related to the RTF output 703 | #--------------------------------------------------------------------------- 704 | 705 | # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 706 | # The RTF output is optimized for Word 97 and may not look very pretty with 707 | # other RTF readers or editors. 708 | 709 | GENERATE_RTF = NO 710 | 711 | # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 712 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 713 | # put in front of it. If left blank `rtf' will be used as the default path. 714 | 715 | RTF_OUTPUT = rtf 716 | 717 | # If the COMPACT_RTF tag is set to YES Doxygen generates more compact 718 | # RTF documents. This may be useful for small projects and may help to 719 | # save some trees in general. 720 | 721 | COMPACT_RTF = NO 722 | 723 | # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 724 | # will contain hyperlink fields. The RTF file will 725 | # contain links (just like the HTML output) instead of page references. 726 | # This makes the output suitable for online browsing using WORD or other 727 | # programs which support those fields. 728 | # Note: wordpad (write) and others do not support links. 729 | 730 | RTF_HYPERLINKS = NO 731 | 732 | # Load stylesheet definitions from file. Syntax is similar to doxygen's 733 | # config file, i.e. a series of assignments. You only have to provide 734 | # replacements, missing definitions are set to their default value. 735 | 736 | RTF_STYLESHEET_FILE = 737 | 738 | # Set optional variables used in the generation of an rtf document. 739 | # Syntax is similar to doxygen's config file. 740 | 741 | RTF_EXTENSIONS_FILE = 742 | 743 | #--------------------------------------------------------------------------- 744 | # configuration options related to the man page output 745 | #--------------------------------------------------------------------------- 746 | 747 | # If the GENERATE_MAN tag is set to YES (the default) Doxygen will 748 | # generate man pages 749 | 750 | GENERATE_MAN = NO 751 | 752 | # The MAN_OUTPUT tag is used to specify where the man pages will be put. 753 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 754 | # put in front of it. If left blank `man' will be used as the default path. 755 | 756 | MAN_OUTPUT = man 757 | 758 | # The MAN_EXTENSION tag determines the extension that is added to 759 | # the generated man pages (default is the subroutine's section .3) 760 | 761 | MAN_EXTENSION = .3 762 | 763 | # If the MAN_LINKS tag is set to YES and Doxygen generates man output, 764 | # then it will generate one additional man file for each entity 765 | # documented in the real man page(s). These additional files 766 | # only source the real man page, but without them the man command 767 | # would be unable to find the correct page. The default is NO. 768 | 769 | MAN_LINKS = NO 770 | 771 | #--------------------------------------------------------------------------- 772 | # configuration options related to the XML output 773 | #--------------------------------------------------------------------------- 774 | 775 | # If the GENERATE_XML tag is set to YES Doxygen will 776 | # generate an XML file that captures the structure of 777 | # the code including all documentation. 778 | 779 | GENERATE_XML = NO 780 | 781 | # The XML_OUTPUT tag is used to specify where the XML pages will be put. 782 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 783 | # put in front of it. If left blank `xml' will be used as the default path. 784 | 785 | XML_OUTPUT = xml 786 | 787 | # The XML_SCHEMA tag can be used to specify an XML schema, 788 | # which can be used by a validating XML parser to check the 789 | # syntax of the XML files. 790 | 791 | XML_SCHEMA = 792 | 793 | # The XML_DTD tag can be used to specify an XML DTD, 794 | # which can be used by a validating XML parser to check the 795 | # syntax of the XML files. 796 | 797 | XML_DTD = 798 | 799 | # If the XML_PROGRAMLISTING tag is set to YES Doxygen will 800 | # dump the program listings (including syntax highlighting 801 | # and cross-referencing information) to the XML output. Note that 802 | # enabling this will significantly increase the size of the XML output. 803 | 804 | XML_PROGRAMLISTING = YES 805 | 806 | #--------------------------------------------------------------------------- 807 | # configuration options for the AutoGen Definitions output 808 | #--------------------------------------------------------------------------- 809 | 810 | # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 811 | # generate an AutoGen Definitions (see autogen.sf.net) file 812 | # that captures the structure of the code including all 813 | # documentation. Note that this feature is still experimental 814 | # and incomplete at the moment. 815 | 816 | GENERATE_AUTOGEN_DEF = NO 817 | 818 | #--------------------------------------------------------------------------- 819 | # configuration options related to the Perl module output 820 | #--------------------------------------------------------------------------- 821 | 822 | # If the GENERATE_PERLMOD tag is set to YES Doxygen will 823 | # generate a Perl module file that captures the structure of 824 | # the code including all documentation. Note that this 825 | # feature is still experimental and incomplete at the 826 | # moment. 827 | 828 | GENERATE_PERLMOD = NO 829 | 830 | # If the PERLMOD_LATEX tag is set to YES Doxygen will generate 831 | # the necessary Makefile rules, Perl scripts and LaTeX code to be able 832 | # to generate PDF and DVI output from the Perl module output. 833 | 834 | PERLMOD_LATEX = NO 835 | 836 | # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 837 | # nicely formatted so it can be parsed by a human reader. This is useful 838 | # if you want to understand what is going on. On the other hand, if this 839 | # tag is set to NO the size of the Perl module output will be much smaller 840 | # and Perl will parse it just the same. 841 | 842 | PERLMOD_PRETTY = YES 843 | 844 | # The names of the make variables in the generated doxyrules.make file 845 | # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 846 | # This is useful so different doxyrules.make files included by the same 847 | # Makefile don't overwrite each other's variables. 848 | 849 | PERLMOD_MAKEVAR_PREFIX = 850 | 851 | #--------------------------------------------------------------------------- 852 | # Configuration options related to the preprocessor 853 | #--------------------------------------------------------------------------- 854 | 855 | # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 856 | # evaluate all C-preprocessor directives found in the sources and include 857 | # files. 858 | 859 | ENABLE_PREPROCESSING = YES 860 | 861 | # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 862 | # names in the source code. If set to NO (the default) only conditional 863 | # compilation will be performed. Macro expansion can be done in a controlled 864 | # way by setting EXPAND_ONLY_PREDEF to YES. 865 | 866 | MACRO_EXPANSION = NO 867 | 868 | # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 869 | # then the macro expansion is limited to the macros specified with the 870 | # PREDEFINED and EXPAND_AS_PREDEFINED tags. 871 | 872 | EXPAND_ONLY_PREDEF = NO 873 | 874 | # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 875 | # in the INCLUDE_PATH (see below) will be search if a #include is found. 876 | 877 | SEARCH_INCLUDES = YES 878 | 879 | # The INCLUDE_PATH tag can be used to specify one or more directories that 880 | # contain include files that are not input files but should be processed by 881 | # the preprocessor. 882 | 883 | INCLUDE_PATH = 884 | 885 | # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 886 | # patterns (like *.h and *.hpp) to filter out the header-files in the 887 | # directories. If left blank, the patterns specified with FILE_PATTERNS will 888 | # be used. 889 | 890 | INCLUDE_FILE_PATTERNS = 891 | 892 | # The PREDEFINED tag can be used to specify one or more macro names that 893 | # are defined before the preprocessor is started (similar to the -D option of 894 | # gcc). The argument of the tag is a list of macros of the form: name 895 | # or name=definition (no spaces). If the definition and the = are 896 | # omitted =1 is assumed. 897 | 898 | PREDEFINED = 899 | 900 | # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 901 | # this tag can be used to specify a list of macro names that should be expanded. 902 | # The macro definition that is found in the sources will be used. 903 | # Use the PREDEFINED tag if you want to use a different macro definition. 904 | 905 | EXPAND_AS_DEFINED = 906 | 907 | # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 908 | # doxygen's preprocessor will remove all function-like macros that are alone 909 | # on a line, have an all uppercase name, and do not end with a semicolon. Such 910 | # function macros are typically used for boiler-plate code, and will confuse the 911 | # parser if not removed. 912 | 913 | SKIP_FUNCTION_MACROS = YES 914 | 915 | #--------------------------------------------------------------------------- 916 | # Configuration::addtions related to external references 917 | #--------------------------------------------------------------------------- 918 | 919 | # The TAGFILES option can be used to specify one or more tagfiles. 920 | # Optionally an initial location of the external documentation 921 | # can be added for each tagfile. The format of a tag file without 922 | # this location is as follows: 923 | # TAGFILES = file1 file2 ... 924 | # Adding location for the tag files is done as follows: 925 | # TAGFILES = file1=loc1 "file2 = loc2" ... 926 | # where "loc1" and "loc2" can be relative or absolute paths or 927 | # URLs. If a location is present for each tag, the installdox tool 928 | # does not have to be run to correct the links. 929 | # Note that each tag file must have a unique name 930 | # (where the name does NOT include the path) 931 | # If a tag file is not located in the directory in which doxygen 932 | # is run, you must also specify the path to the tagfile here. 933 | 934 | TAGFILES = 935 | 936 | # When a file name is specified after GENERATE_TAGFILE, doxygen will create 937 | # a tag file that is based on the input files it reads. 938 | 939 | GENERATE_TAGFILE = 940 | 941 | # If the ALLEXTERNALS tag is set to YES all external classes will be listed 942 | # in the class index. If set to NO only the inherited external classes 943 | # will be listed. 944 | 945 | ALLEXTERNALS = NO 946 | 947 | # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 948 | # in the modules index. If set to NO, only the current project's groups will 949 | # be listed. 950 | 951 | EXTERNAL_GROUPS = YES 952 | 953 | # The PERL_PATH should be the absolute path and name of the perl script 954 | # interpreter (i.e. the result of `which perl'). 955 | 956 | PERL_PATH = /usr/bin/perl 957 | 958 | #--------------------------------------------------------------------------- 959 | # Configuration options related to the dot tool 960 | #--------------------------------------------------------------------------- 961 | 962 | # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 963 | # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or 964 | # super classes. Setting the tag to NO turns the diagrams off. Note that this 965 | # option is superseded by the HAVE_DOT option below. This is only a fallback. It is 966 | # recommended to install and use dot, since it yields more powerful graphs. 967 | 968 | CLASS_DIAGRAMS = YES 969 | 970 | # If set to YES, the inheritance and collaboration graphs will hide 971 | # inheritance and usage relations if the target is undocumented 972 | # or is not a class. 973 | 974 | HIDE_UNDOC_RELATIONS = YES 975 | 976 | # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 977 | # available from the path. This tool is part of Graphviz, a graph visualization 978 | # toolkit from AT&T and Lucent Bell Labs. The other options in this section 979 | # have no effect if this option is set to NO (the default) 980 | 981 | HAVE_DOT = NO 982 | 983 | # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 984 | # will generate a graph for each documented class showing the direct and 985 | # indirect inheritance relations. Setting this tag to YES will force the 986 | # the CLASS_DIAGRAMS tag to NO. 987 | 988 | CLASS_GRAPH = YES 989 | 990 | # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 991 | # will generate a graph for each documented class showing the direct and 992 | # indirect implementation dependencies (inheritance, containment, and 993 | # class references variables) of the class with other documented classes. 994 | 995 | COLLABORATION_GRAPH = YES 996 | 997 | # If the UML_LOOK tag is set to YES doxygen will generate inheritance and 998 | # collaboration diagrams in a style similar to the OMG's Unified Modeling 999 | # Language. 1000 | 1001 | UML_LOOK = NO 1002 | 1003 | # If set to YES, the inheritance and collaboration graphs will show the 1004 | # relations between templates and their instances. 1005 | 1006 | TEMPLATE_RELATIONS = NO 1007 | 1008 | # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 1009 | # tags are set to YES then doxygen will generate a graph for each documented 1010 | # file showing the direct and indirect include dependencies of the file with 1011 | # other documented files. 1012 | 1013 | INCLUDE_GRAPH = YES 1014 | 1015 | # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 1016 | # HAVE_DOT tags are set to YES then doxygen will generate a graph for each 1017 | # documented header file showing the documented files that directly or 1018 | # indirectly include this file. 1019 | 1020 | INCLUDED_BY_GRAPH = YES 1021 | 1022 | # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 1023 | # generate a call dependency graph for every global function or class method. 1024 | # Note that enabling this option will significantly increase the time of a run. 1025 | # So in most cases it will be better to enable call graphs for selected 1026 | # functions only using the \callgraph command. 1027 | 1028 | CALL_GRAPH = NO 1029 | 1030 | # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 1031 | # will graphical hierarchy of all classes instead of a textual one. 1032 | 1033 | GRAPHICAL_HIERARCHY = YES 1034 | 1035 | # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 1036 | # generated by dot. Possible values are png, jpg, or gif 1037 | # If left blank png will be used. 1038 | 1039 | DOT_IMAGE_FORMAT = png 1040 | 1041 | # The tag DOT_PATH can be used to specify the path where the dot tool can be 1042 | # found. If left blank, it is assumed the dot tool can be found on the path. 1043 | 1044 | DOT_PATH = 1045 | 1046 | # The DOTFILE_DIRS tag can be used to specify one or more directories that 1047 | # contain dot files that are included in the documentation (see the 1048 | # \dotfile command). 1049 | 1050 | DOTFILE_DIRS = 1051 | 1052 | # The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 1053 | # (in pixels) of the graphs generated by dot. If a graph becomes larger than 1054 | # this value, doxygen will try to truncate the graph, so that it fits within 1055 | # the specified constraint. Beware that most browsers cannot cope with very 1056 | # large images. 1057 | 1058 | MAX_DOT_GRAPH_WIDTH = 1024 1059 | 1060 | # The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 1061 | # (in pixels) of the graphs generated by dot. If a graph becomes larger than 1062 | # this value, doxygen will try to truncate the graph, so that it fits within 1063 | # the specified constraint. Beware that most browsers cannot cope with very 1064 | # large images. 1065 | 1066 | MAX_DOT_GRAPH_HEIGHT = 1024 1067 | 1068 | # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 1069 | # graphs generated by dot. A depth value of 3 means that only nodes reachable 1070 | # from the root by following a path via at most 3 edges will be shown. Nodes that 1071 | # lay further from the root node will be omitted. Note that setting this option to 1072 | # 1 or 2 may greatly reduce the computation time needed for large code bases. Also 1073 | # note that a graph may be further truncated if the graph's image dimensions are 1074 | # not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). 1075 | # If 0 is used for the depth value (the default), the graph is not depth-constrained. 1076 | 1077 | MAX_DOT_GRAPH_DEPTH = 0 1078 | 1079 | # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 1080 | # generate a legend page explaining the meaning of the various boxes and 1081 | # arrows in the dot generated graphs. 1082 | 1083 | GENERATE_LEGEND = YES 1084 | 1085 | # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 1086 | # remove the intermediate dot files that are used to generate 1087 | # the various graphs. 1088 | 1089 | DOT_CLEANUP = YES 1090 | 1091 | #--------------------------------------------------------------------------- 1092 | # Configuration::addtions related to the search engine 1093 | #--------------------------------------------------------------------------- 1094 | 1095 | # The SEARCHENGINE tag specifies whether or not a search engine should be 1096 | # used. If set to NO the values of all tags below this one will be ignored. 1097 | 1098 | SEARCHENGINE = NO 1099 | --------------------------------------------------------------------------------