ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
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 
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 
28 extern int _iop_reboot_count;
29 
31 extern unsigned char _imgdrv_irx[];
32 extern unsigned int size__imgdrv_irx;
33 
34 //If for whatever reason imgdrv changes, update these offsets.
35 #define IMGDRV_IRX_PTRS 0x190
36 #define IMGDRV_IRX_SIZES 0x198
37 
38 #ifdef F__iopcontrol_special_internals
39 u8 iopbtconf_img[IOPBTCONF_IOP_MAX_SIZE] __attribute__((aligned(64)));
40 #endif
41 
42 //Our LOADFILE functions are slightly different.
43 #define SifLoadModuleSpecial(path, arg_len, args, dontwait) \
44  _SifLoadModule(path, arg_len, args, NULL, LF_F_MOD_LOAD, dontwait);
45 
46 #define SifLoadModuleEncryptedSpecial(path, arg_len, args, dontwait) \
47  _SifLoadModule(path, arg_len, args, NULL, LF_F_MG_MOD_LOAD, dontwait);
48 
49 #ifdef F_SifIopRebootBufferEncrypted
50 int SifIopRebootBufferEncrypted(const void *udnl, int size)
51 {
52  int iopbtconf_img_size;
53  void *imgdrv_iop, *udnl_iop, *iopbtconf_img_iop;
54  int *imgdrv_img_size;
55  void **imgdrv_img;
56  SifDmaTransfer_t dmat[3];
57 
58  SifInitRpc(0);
59  SifExitRpc();
60 
61  SifIopReset("", 0);
62  while(!SifIopSync()){};
63 
66 
67  imgdrv_iop = SifAllocIopHeap(IMGDRV_IRX_SIZE);
68  udnl_iop = SifAllocIopHeap(size);
69  iopbtconf_img_iop = SifAllocIopHeap(IOPBTCONF_IOP_MAX_SIZE);
70 
71  if(imgdrv_iop == NULL || udnl_iop == NULL || iopbtconf_img_iop == NULL)
72  return -1;
73 
74  iopbtconf_img_size = 0; //No support for IOPBTCONF manipulation
75 
76  imgdrv_img = (void**)&_imgdrv_irx[IMGDRV_IRX_PTRS];
77  imgdrv_img_size = (int*)&_imgdrv_irx[IMGDRV_IRX_SIZES];
78  dmat[0].src = _imgdrv_irx;
79  dmat[0].dest = imgdrv_iop;
80  dmat[0].size = IMGDRV_IRX_SIZE;
81  dmat[0].attr = 0;
82  dmat[1].src = (void*)udnl;
83  dmat[1].dest = udnl_iop;
84  dmat[1].size = size;
85  dmat[1].attr = 0;
86  dmat[2].src = iopbtconf_img;
87  dmat[2].dest = iopbtconf_img_iop;
88  dmat[2].size = iopbtconf_img_size;
89  dmat[2].attr = 0;
90  imgdrv_img[0] = udnl_iop;
91  imgdrv_img[1] = iopbtconf_img_iop;
92  imgdrv_img_size[0] = size;
93  imgdrv_img_size[1] = iopbtconf_img_size;
94  FlushCache(0);
95  SifSetDma(dmat, 3);
96 
98 
99  SifLoadModule("rom0:SYSCLIB", 0, NULL);
100  SifLoadModuleBuffer(imgdrv_iop, 0, NULL);
101  SifLoadModuleEncryptedSpecial("img0:", 0, NULL, 1);
102 
103  SifExitRpc();
104  SifLoadFileExit();
105 
111 
112  _iop_reboot_count++; //Not originally here: increment to allow RPC clients to detect unbinding.
113 
114  return 1;
115 }
116 #endif
117 
118 #ifdef F_SifIopRebootBuffer
119 static int generateIOPBTCONF_img(void *output, const void *ioprp);
120 
121 int SifIopRebootBuffer(const void *ioprp, int size)
122 {
123  int iopbtconf_img_size;
124  void *imgdrv_iop, *ioprp_iop, *iopbtconf_img_iop;
125  int *imgdrv_img_size;
126  void **imgdrv_img;
127  SifDmaTransfer_t dmat[3];
128 
129  SifInitRpc(0);
130  SifExitRpc();
131 
132  SifIopReset("", 0);
133  while(!SifIopSync()){};
134 
135  SifLoadFileInit();
136  SifInitIopHeap();
137 
138  imgdrv_iop = SifAllocIopHeap(IMGDRV_IRX_SIZE);
139  ioprp_iop = SifAllocIopHeap(size);
140  iopbtconf_img_iop = SifAllocIopHeap(IOPBTCONF_IOP_MAX_SIZE);
141 
142  if(imgdrv_iop == NULL || ioprp_iop == NULL || iopbtconf_img_iop == NULL)
143  return -1;
144 
145  iopbtconf_img_size = generateIOPBTCONF_img(iopbtconf_img, ioprp);
146 
147  imgdrv_img = (void**)&_imgdrv_irx[IMGDRV_IRX_PTRS];
148  imgdrv_img_size = (int*)&_imgdrv_irx[IMGDRV_IRX_SIZES];
149  dmat[0].src = _imgdrv_irx;
150  dmat[0].dest = imgdrv_iop;
151  dmat[0].size = IMGDRV_IRX_SIZE;
152  dmat[0].attr = 0;
153  dmat[1].src = (void*)ioprp;
154  dmat[1].dest = ioprp_iop;
155  dmat[1].size = size;
156  dmat[1].attr = 0;
157  dmat[2].src = iopbtconf_img;
158  dmat[2].dest = iopbtconf_img_iop;
159  dmat[2].size = iopbtconf_img_size;
160  dmat[2].attr = 0;
161  imgdrv_img[0] = ioprp_iop;
162  imgdrv_img[1] = iopbtconf_img_iop;
163  imgdrv_img_size[0] = size;
164  imgdrv_img_size[1] = iopbtconf_img_size;
165  FlushCache(0);
166  SifSetDma(dmat, 3);
167 
169 
170  SifLoadModule("rom0:SYSCLIB", 0, NULL);
171  SifLoadModuleBuffer(imgdrv_iop, 0, NULL);
172  SifLoadModuleSpecial("rom0:UDNL", 11, "img0:\0img1:", 1);
173 
174  SifExitRpc();
175  SifLoadFileExit();
176 
182 
183  _iop_reboot_count++; //Not originally here: increment to allow RPC clients to detect unbinding.
184 
185  return 1;
186 }
187 
188 typedef struct romdir{
189  char name[10];
190  u16 ExtInfoEntrySize;
191  u32 size;
192 } romdir_t;
193 
194 typedef struct extinfo{
195  u16 value; /* Only applicable for the version field type. */
196  u8 ExtLength; /* The length of data appended to the end of this entry. */
197  u8 type;
198 } extinfo_t;
199 
200 enum EXTINFO_TYPE{
201  EXTINFO_TYPE_DATE = 1,
202  EXTINFO_TYPE_VERSION,
203  EXTINFO_TYPE_COMMENT,
204  EXTINFO_TYPE_FIXED = 0x7F //Must exist at a fixed location.
205 };
206 
207 struct iopbtconf_img {
208  romdir_t romdir[5];
209  u32 extinfo[4];
210 };
211 
212 static const struct iopbtconf_img iopbtconf_img_base = {
213  {
214  {"RESET", 8, 0},
215  {"ROMDIR", 0, 0x50},
216  {"EXTINFO", 0, 0x10},
217  {"IOPBTCONF", 8, -1},
218  {"", 0, 0}
219  },
220  {
221  0x01040000, //EXTINFO {0x0000, 4, EXTINFO_TYPE_DATE},
222  0x20010406, //Date: 2001/04/06
223  0x01040000, //EXTINFO {0x0000, 4, EXTINFO_TYPE_DATE},
224  0x20010406, //Date: 2001/04/06
225  }
226 };
227 
228 /* Generate an IOPRP image that contains IOPBTCONF, if the original contains IOPBTCONF.
229  This is required because UDNL will only seach succeeding IOPRP images for modules specified within IOPBTCONF. */
230 static int generateIOPBTCONF_img(void *output, const void *ioprp)
231 {
232  int size, offset, fsize_rounded;
233  romdir_t *romdir;
234  const u8 *ptr_in;
235  u8 *ptr_out;
236 
237  romdir = (romdir_t*)ioprp;
238  if(strcmp(romdir[0].name, "RESET") || strcmp(romdir[1].name, "ROMDIR"))
239  return -1;
240 
241  //Now locate IOPBTCONF
242  size = 0;
243  offset = 0;
244  for(; romdir->name[0] != '\0'; romdir++,offset += fsize_rounded)
245  {
246  fsize_rounded = (romdir->size + 15) & ~15;
247  if(strcmp(romdir->name, "IOPBTCONF") == 0)
248  {
249  romdir->name[0] = 'X'; //Change 'IOPBTCONF' to 'XOPBTCONF', so that UDNL will not find the original.
250  //Copy IOPBTCONF into the new image.
251  size = romdir->size + sizeof(iopbtconf_img_base);
252  ptr_out = (u8*)output;
253  ptr_in = (const u8*)ioprp;
254  memcpy(ptr_out, &iopbtconf_img_base, sizeof(iopbtconf_img_base));
255  memcpy(ptr_out + sizeof(iopbtconf_img_base), &ptr_in[offset], romdir->size);
256  ((romdir_t*)ptr_out)[3].size = romdir->size; //Update the size of IOPBTCONF within the generated IOPRP image.
257  break;
258  }
259  }
260 
261  return size;
262 }
263 #endif
#define SifLoadModuleSpecial(path, arg_len, args, dontwait)
u8 iopbtconf_img[IOPBTCONF_IOP_MAX_SIZE]
#define SifLoadModuleEncryptedSpecial(path, arg_len, args, dontwait)
unsigned int size__imgdrv_irx
#define IMGDRV_IRX_SIZE
int _iop_reboot_count
#define IMGDRV_IRX_SIZES
#define IOPBTCONF_IOP_MAX_SIZE
unsigned char _imgdrv_irx[]
#define IMGDRV_IRX_PTRS
int SifLoadModule(const char *path, int arg_len, const char *args)
void SifLoadFileExit(void)
int SifLoadFileInit(void)
int SifLoadModuleBuffer(void *ptr, int arg_len, const char *args)
int SifIopReset(const char *arg, int mode)
int SifIopSync(void)
int SifIopRebootBuffer(const void *ioprp, int size)
int SifIopRebootBufferEncrypted(const void *udnl, int size)
void * SifAllocIopHeap(int size)
int SifInitIopHeap(void)
u32 SifSetDma(SifDmaTransfer_t *sdd, s32 len)
int SifSetReg(u32 register_num, int register_value)
void FlushCache(s32 operation)
int sbv_patch_enable_lmb(void)
#define SIF_STAT_CMDINIT
Definition: sifdma.h:48
#define SIF_STAT_BOOTEND
Definition: sifdma.h:50
@ SIF_SYSREG_SUBADDR
Definition: sifdma.h:39
@ SIF_SYSREG_RPCINIT
Definition: sifdma.h:41
@ SIF_REG_SMFLAG
Definition: sifdma.h:36
#define SIF_STAT_SIFINIT
Definition: sifdma.h:46
void SifInitRpc(int mode)
void SifExitRpc(void)
void * dest
Definition: sifdma.h:55
void * src
Definition: sifdma.h:54
#define NULL
Definition: tamtypes.h:91
unsigned int u32
Definition: tamtypes.h:30
unsigned short u16
Definition: tamtypes.h:24
unsigned char u8
Definition: tamtypes.h:23