sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Loading...
Searching...
No Matches
SifIopRebootBuffer.c
Go to the documentation of this file.
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Licenced under Academic Free License version 2.0
7# Review ps2sdk README & LICENSE files for further details.
8*/
9
14
15#include "kernel.h"
16#include "iopcontrol.h"
17#include "iopcontrol_special.h"
18#include "loadfile.h"
19#include "iopheap.h"
20#include "sifdma.h"
21#include "sifrpc.h"
22#include "string.h"
23#include "sbv_patches.h"
24
25#define IMGDRV_IRX_SIZE ((size__imgdrv_irx + 15) & ~15) // Was a hardcoded value of 0x400 bytes
26#define IOPBTCONF_IOP_MAX_SIZE 0x400
27
28extern int _iop_reboot_count;
29
30extern u8 iopbtconf_img[IOPBTCONF_IOP_MAX_SIZE];
31extern unsigned char _imgdrv_irx[];
32extern unsigned int size__imgdrv_irx;
33
34extern int imgdrv_offset_ioprpimg;
35extern int imgdrv_offset_ioprpsiz;
36
37extern void init_imgdrv_offsets(void);
38
39u8 iopbtconf_img[IOPBTCONF_IOP_MAX_SIZE] __attribute__((aligned(64)));
40int imgdrv_offset_ioprpimg = 0;
41int imgdrv_offset_ioprpsiz = 0;
42
43void init_imgdrv_offsets(void)
44{
45 if (imgdrv_offset_ioprpimg == 0 || imgdrv_offset_ioprpsiz == 0) {
46 int i;
47
48 for (i = 0; (unsigned int)i < size__imgdrv_irx; i += 4) {
49 if (*(u32 *)((&((unsigned char *)_imgdrv_irx)[i])) == 0xDEC1DEC1) {
50 imgdrv_offset_ioprpimg = i;
51 }
52 if (*(u32 *)((&((unsigned char *)_imgdrv_irx)[i])) == 0xDEC2DEC2) {
53 imgdrv_offset_ioprpsiz = i;
54 }
55 }
56 }
57}
58
59// Our LOADFILE functions are slightly different.
60#define SifLoadModuleSpecial(path, arg_len, args, dontwait) \
61 _SifLoadModule(path, arg_len, args, NULL, LF_F_MOD_LOAD, dontwait);
62
63#define SifLoadModuleEncryptedSpecial(path, arg_len, args, dontwait) \
64 _SifLoadModule(path, arg_len, args, NULL, LF_F_MG_MOD_LOAD, dontwait);
65
66int SifIopRebootBufferEncrypted(const void *udnl, int size)
67{
68 int iopbtconf_img_size;
69 void *imgdrv_iop, *udnl_iop, *iopbtconf_img_iop;
70 int *imgdrv_img_size;
71 void **imgdrv_img;
72 SifDmaTransfer_t dmat[3];
73
74 sceSifInitRpc(0);
75 sceSifExitRpc();
76
77 SifIopReset("", 0);
78 while (!SifIopSync()) {};
79
81 SifInitIopHeap();
82
83 imgdrv_iop = SifAllocIopHeap(IMGDRV_IRX_SIZE);
84 udnl_iop = SifAllocIopHeap(size);
85 iopbtconf_img_iop = SifAllocIopHeap(IOPBTCONF_IOP_MAX_SIZE);
86
87 if (imgdrv_iop == NULL || udnl_iop == NULL || iopbtconf_img_iop == NULL)
88 return -1;
89
90 iopbtconf_img_size = 0; // No support for IOPBTCONF manipulation
91
92 init_imgdrv_offsets();
93 imgdrv_img = (void **)&_imgdrv_irx[imgdrv_offset_ioprpimg];
94 imgdrv_img_size = (int *)&_imgdrv_irx[imgdrv_offset_ioprpsiz];
95 dmat[0].src = _imgdrv_irx;
96 dmat[0].dest = imgdrv_iop;
97 dmat[0].size = IMGDRV_IRX_SIZE;
98 dmat[0].attr = 0;
99 dmat[1].src = (void *)udnl;
100 dmat[1].dest = udnl_iop;
101 dmat[1].size = size;
102 dmat[1].attr = 0;
103 dmat[2].src = iopbtconf_img;
104 dmat[2].dest = iopbtconf_img_iop;
105 dmat[2].size = iopbtconf_img_size;
106 dmat[2].attr = 0;
107 imgdrv_img[0] = udnl_iop;
108 imgdrv_img[1] = iopbtconf_img_iop;
109 imgdrv_img_size[0] = size;
110 imgdrv_img_size[1] = iopbtconf_img_size;
111 FlushCache(0);
112 sceSifSetDma(dmat, 3);
113
115
116 SifLoadModule("rom0:SYSCLIB", 0, NULL);
117 SifLoadModuleBuffer(imgdrv_iop, 0, NULL);
118 SifLoadModuleEncryptedSpecial("img0:", 0, NULL, 1);
119
120 sceSifExitRpc();
122
123 sceSifSetReg(SIF_REG_SMFLAG, SIF_STAT_SIFINIT);
124 sceSifSetReg(SIF_REG_SMFLAG, SIF_STAT_CMDINIT);
125 sceSifSetReg(SIF_REG_SMFLAG, SIF_STAT_BOOTEND);
126 sceSifSetReg(SIF_SYSREG_RPCINIT, 0);
127 sceSifSetReg(SIF_SYSREG_SUBADDR, 0);
128
129 _iop_reboot_count++; // Not originally here: increment to allow RPC clients to detect unbinding.
130
131 return 1;
132}
133
134static int generateIOPBTCONF_img(void *output, const void *ioprp);
135
136int SifIopRebootBuffer(const void *ioprp, int size)
137{
138 int iopbtconf_img_size;
139 void *imgdrv_iop, *ioprp_iop, *iopbtconf_img_iop;
140 int *imgdrv_img_size;
141 void **imgdrv_img;
142 SifDmaTransfer_t dmat[3];
143
144 sceSifInitRpc(0);
145 sceSifExitRpc();
146
147 SifIopReset("", 0);
148 while (!SifIopSync()) {};
149
151 SifInitIopHeap();
152
153 imgdrv_iop = SifAllocIopHeap(IMGDRV_IRX_SIZE);
154 ioprp_iop = SifAllocIopHeap(size);
155 iopbtconf_img_iop = SifAllocIopHeap(IOPBTCONF_IOP_MAX_SIZE);
156
157 if (imgdrv_iop == NULL || ioprp_iop == NULL || iopbtconf_img_iop == NULL)
158 return -1;
159
160 iopbtconf_img_size = generateIOPBTCONF_img(iopbtconf_img, ioprp);
161
162 init_imgdrv_offsets();
163 imgdrv_img = (void **)&_imgdrv_irx[imgdrv_offset_ioprpimg];
164 imgdrv_img_size = (int *)&_imgdrv_irx[imgdrv_offset_ioprpsiz];
165 dmat[0].src = _imgdrv_irx;
166 dmat[0].dest = imgdrv_iop;
167 dmat[0].size = IMGDRV_IRX_SIZE;
168 dmat[0].attr = 0;
169 dmat[1].src = (void *)ioprp;
170 dmat[1].dest = ioprp_iop;
171 dmat[1].size = size;
172 dmat[1].attr = 0;
173 dmat[2].src = iopbtconf_img;
174 dmat[2].dest = iopbtconf_img_iop;
175 dmat[2].size = iopbtconf_img_size;
176 dmat[2].attr = 0;
177 imgdrv_img[0] = ioprp_iop;
178 imgdrv_img[1] = iopbtconf_img_iop;
179 imgdrv_img_size[0] = size;
180 imgdrv_img_size[1] = iopbtconf_img_size;
181 FlushCache(0);
182 sceSifSetDma(dmat, 3);
183
185
186 SifLoadModule("rom0:SYSCLIB", 0, NULL);
187 SifLoadModuleBuffer(imgdrv_iop, 0, NULL);
188 SifLoadModuleSpecial("rom0:UDNL", 11, "img0:\0img1:", 1);
189
190 sceSifExitRpc();
192
193 sceSifSetReg(SIF_REG_SMFLAG, SIF_STAT_SIFINIT);
194 sceSifSetReg(SIF_REG_SMFLAG, SIF_STAT_CMDINIT);
195 sceSifSetReg(SIF_REG_SMFLAG, SIF_STAT_BOOTEND);
196 sceSifSetReg(SIF_SYSREG_RPCINIT, 0);
197 sceSifSetReg(SIF_SYSREG_SUBADDR, 0);
198
199 _iop_reboot_count++; // Not originally here: increment to allow RPC clients to detect unbinding.
200
201 return 1;
202}
203
204typedef struct romdir
205{
206 char name[10];
207 u16 ExtInfoEntrySize;
208 u32 size;
209} romdir_t;
210
211typedef struct extinfo
212{
213 u16 value; /* Only applicable for the version field type. */
214 u8 ExtLength; /* The length of data appended to the end of this entry. */
215 u8 type;
216} extinfo_t;
217
218enum EXTINFO_TYPE {
219 EXTINFO_TYPE_DATE = 1,
220 EXTINFO_TYPE_VERSION,
221 EXTINFO_TYPE_COMMENT,
222 EXTINFO_TYPE_FIXED = 0x7F // Must exist at a fixed location.
223};
224
226{
227 romdir_t romdir[5];
228 u32 extinfo[4];
229};
230
231static const struct iopbtconf_img iopbtconf_img_base = {
232 {{"RESET", 8, 0},
233 {"ROMDIR", 0, 0x50},
234 {"EXTINFO", 0, 0x10},
235 {"IOPBTCONF", 8, -1},
236 {"", 0, 0}},
237 {
238 0x01040000, // EXTINFO {0x0000, 4, EXTINFO_TYPE_DATE},
239 0x20010406, // Date: 2001/04/06
240 0x01040000, // EXTINFO {0x0000, 4, EXTINFO_TYPE_DATE},
241 0x20010406, // Date: 2001/04/06
242 }};
243
244/* Generate an IOPRP image that contains IOPBTCONF, if the original contains IOPBTCONF.
245 This is required because UDNL will only seach succeeding IOPRP images for modules specified within IOPBTCONF. */
246static int generateIOPBTCONF_img(void *output, const void *ioprp)
247{
248 int size, offset, fsize_rounded;
249 romdir_t *romdir;
250 const u8 *ptr_in;
251 u8 *ptr_out;
252
253 romdir = (romdir_t *)ioprp;
254 if (strcmp(romdir[0].name, "RESET") || strcmp(romdir[1].name, "ROMDIR"))
255 return -1;
256
257 // Now locate IOPBTCONF
258 size = 0;
259 offset = 0;
260 for (; romdir->name[0] != '\0'; romdir++, offset += fsize_rounded) {
261 fsize_rounded = (romdir->size + 15) & ~15;
262 if (strcmp(romdir->name, "IOPBTCONF") == 0) {
263 romdir->name[0] = 'X'; // Change 'IOPBTCONF' to 'XOPBTCONF', so that UDNL will not find the original.
264 // Copy IOPBTCONF into the new image.
265 size = romdir->size + sizeof(iopbtconf_img_base);
266 ptr_out = (u8 *)output;
267 ptr_in = (const u8 *)ioprp;
268 memcpy(ptr_out, &iopbtconf_img_base, sizeof(iopbtconf_img_base));
269 memcpy(ptr_out + sizeof(iopbtconf_img_base), &ptr_in[offset], romdir->size);
270 ((romdir_t *)ptr_out)[3].size = romdir->size; // Update the size of IOPBTCONF within the generated IOPRP image.
271 break;
272 }
273 }
274
275 return size;
276}
int SifLoadModule(const char *path, int arg_len, const char *args)
Definition loadfile.c:92
void SifLoadFileExit(void)
Definition loadfile.c:59
int SifLoadFileInit(void)
Definition loadfile.c:38
int SifLoadModuleBuffer(void *ptr, int arg_len, const char *args)
Definition loadfile.c:304
int SifIopReset(const char *arg, int mode)
Definition iopcontrol.c:31
int SifIopSync(void)
Definition iopcontrol.c:96
int SifIopRebootBuffer(const void *ioprp, int size)
int SifIopRebootBufferEncrypted(const void *udnl, int size)
int sbv_patch_enable_lmb(void)
#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