sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
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
16
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
26int _iop_reboot_count = 0;
27
28extern int _iop_reboot_count;
29
30
31int SifIopReset(const char *arg, int mode)
32{
33 static SifCmdResetData_t reset_pkt __attribute__((aligned(64)));
34 struct t_SifDmaTransfer dmat;
35 int arglen;
36
37 _iop_reboot_count++; // increment reboot counter to allow RPC clients to detect unbinding!
38
39 sceSifStopDma(); // Stop DMA transfers across SIF0 (IOP -> EE).
40
41 /* The original did not null-terminate, had no bounds-checking and counted the characters as it copied.
42 The IOP side will only copy up to arglen characters. */
43 if (arg != NULL) {
44 for (arglen = 0; arg[arglen] != '\0'; arglen++)
45 reset_pkt.arg[arglen] = arg[arglen];
46 } else { // While NULL was not officially supported, do this for backward-compatibility with old homebrew projects.
47 arglen = 0;
48 }
49
50 reset_pkt.header.psize = sizeof reset_pkt; // dsize is not initialized (and not processed, even on the IOP).
51 reset_pkt.header.cid = SIF_CMD_RESET_CMD;
52 reset_pkt.arglen = arglen;
53 reset_pkt.mode = mode;
54
55 dmat.src = &reset_pkt;
56 dmat.dest = (void *)sceSifGetReg(SIF_SYSREG_SUBADDR);
57 dmat.size = sizeof(reset_pkt);
58 dmat.attr = SIF_DMA_ERT | SIF_DMA_INT_O;
59 sceSifWriteBackDCache(&reset_pkt, sizeof(reset_pkt));
60
61 sceSifSetReg(SIF_REG_SMFLAG, SIF_STAT_BOOTEND);
62
63 if (!sceSifSetDma(&dmat, 1))
64 return 0;
65
66 sceSifSetReg(SIF_REG_SMFLAG, SIF_STAT_SIFINIT);
67 sceSifSetReg(SIF_REG_SMFLAG, SIF_STAT_CMDINIT);
68 sceSifSetReg(SIF_SYSREG_RPCINIT, 0);
69 sceSifSetReg(SIF_SYSREG_SUBADDR, (int)NULL);
70
71 return 1;
72}
73
74int SifIopReboot(const char *arg)
75{
76 char param_str[RESET_ARG_MAX + 1];
77
78 if (strlen(arg) + 11 > RESET_ARG_MAX) {
79 printf("too long parameter \'%s\'\n", arg);
80 return 0;
81 }
82
83 sceSifInitRpc(0);
84 sceSifExitRpc();
85
86 snprintf(param_str, sizeof(param_str), "rom0:UDNL %s", arg);
87
88 return SifIopReset(param_str, 0);
89}
90
92{
93 return ((sceSifGetReg(SIF_REG_SMFLAG) & SIF_STAT_SIFINIT) != 0);
94}
95
97{
98 return ((sceSifGetReg(SIF_REG_SMFLAG) & SIF_STAT_BOOTEND) != 0);
99}
int SifIopIsAlive(void)
Definition iopcontrol.c:91
int SifIopReboot(const char *arg)
Definition iopcontrol.c:74
int SifIopReset(const char *arg, int mode)
Definition iopcontrol.c:31
int SifIopSync(void)
Definition iopcontrol.c:96
#define RESET_ARG_MAX
#define SIF_STAT_CMDINIT
Definition sifdma.h:49
#define SIF_STAT_BOOTEND
Definition sifdma.h:51
@ SIF_REG_SMFLAG
Definition sifdma.h:37
#define SIF_STAT_SIFINIT
Definition sifdma.h:47