PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
iopcontrol.c
Go to the documentation of this file.
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# (C)2001, Gustavo Scotti (gustavo@scotti.com)
7# (c) 2003 Marcus R. Brown (mrbrown@0xd6.org)
8# Licenced under Academic Free License version 2.0
9# Review ps2sdk README & LICENSE files for further details.
10*/
11
17#include <tamtypes.h>
18#include <kernel.h>
19#include <sifcmd.h>
20#include <sifrpc.h>
21#include <string.h>
22#include <stdio.h>
23
24#include <iopcontrol.h>
25
26#ifdef F___iop_control_internals
27int _iop_reboot_count = 0;
28#endif
29
30extern int _iop_reboot_count;
31
32#ifdef F_SifIopReset
33
34int SifIopReset(const char *arg, int mode)
35{
36 static SifCmdResetData_t reset_pkt __attribute__((aligned(64)));
37 struct t_SifDmaTransfer dmat;
38 int arglen;
39
40 _iop_reboot_count++; // increment reboot counter to allow RPC clients to detect unbinding!
41
42 SifStopDma(); // Stop DMA transfers across SIF0 (IOP -> EE).
43
44 /* The original did not null-terminate, had no bounds-checking and counted the characters as it copied.
45 The IOP side will only copy up to arglen characters. */
46 if (arg != NULL) {
47 for (arglen = 0; arg[arglen] != '\0'; arglen++)
48 reset_pkt.arg[arglen] = arg[arglen];
49 } else { // While NULL was not officially supported, do this for backward-compatibility with old homebrew projects.
50 arglen = 0;
51 }
52
53 reset_pkt.header.psize = sizeof reset_pkt; // dsize is not initialized (and not processed, even on the IOP).
54 reset_pkt.header.cid = SIF_CMD_RESET_CMD;
55 reset_pkt.arglen = arglen;
56 reset_pkt.mode = mode;
57
58 dmat.src = &reset_pkt;
59 dmat.dest = (void *)SifGetReg(SIF_SYSREG_SUBADDR);
60 dmat.size = sizeof(reset_pkt);
61 dmat.attr = SIF_DMA_ERT | SIF_DMA_INT_O;
62 SifWriteBackDCache(&reset_pkt, sizeof(reset_pkt));
63
65
66 if (!SifSetDma(&dmat, 1))
67 return 0;
68
71 SifSetReg(SIF_SYSREG_RPCINIT, 0);
72 SifSetReg(SIF_SYSREG_SUBADDR, (int)NULL);
73
74 return 1;
75}
76#endif
77
78#ifdef F_SifIopReboot
79int SifIopReboot(const char *arg)
80{
81 char param_str[RESET_ARG_MAX + 1];
82
83 if (strlen(arg) + 11 > RESET_ARG_MAX) {
84 printf("too long parameter \'%s\'\n", arg);
85 return 0;
86 }
87
88 SifInitRpc(0);
89 SifExitRpc();
90
91 strcpy(param_str, "rom0:UDNL ");
92 strcat(param_str, arg);
93
94 return SifIopReset(param_str, 0);
95}
96#endif
97
98#ifdef F_SifIopIsAlive
99int SifIopIsAlive(void)
100{
101 return ((SifGetReg(SIF_REG_SMFLAG) & SIF_STAT_SIFINIT) != 0);
102}
103#endif
104
105#ifdef F_SifIopSync
106int SifIopSync()
107{
108 return ((SifGetReg(SIF_REG_SMFLAG) & SIF_STAT_BOOTEND) != 0);
109}
110#endif
#define RESET_ARG_MAX
Definition sifcmd.h:73
int SifIopIsAlive(void)
int SifIopReboot(const char *arg)
int SifIopReset(const char *arg, int mode)
int SifIopSync(void)
#define SIF_STAT_CMDINIT
Definition sifdma.h:48
#define SIF_STAT_BOOTEND
Definition sifdma.h:50
@ SIF_REG_SMFLAG
Definition sifdma.h:36
#define SIF_STAT_SIFINIT
Definition sifdma.h:46