PS2SDK
PS2 Homebrew Libraries
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 IOPBTCONF_IOP_MAX_SIZE 0x400
26 
27 extern int _iop_reboot_count;
28 
29 extern u8 iopbtconf_img[IOPBTCONF_IOP_MAX_SIZE];
30 
31 extern int send_romdrv_rom1_payloads(void *payload1, int payload1_size, void *payload2, int payload2_size);
32 
33 typedef struct romdir
34 {
35  char name[10];
36  u16 ExtInfoEntrySize;
37  u32 size;
38 } romdir_t;
39 
40 typedef struct extinfo
41 {
42  u16 value; /* Only applicable for the version field type. */
43  u8 ExtLength; /* The length of data appended to the end of this entry. */
44  u8 type;
45 } extinfo_t;
46 
47 enum EXTINFO_TYPE {
48  EXTINFO_TYPE_DATE = 1,
49  EXTINFO_TYPE_VERSION,
50  EXTINFO_TYPE_COMMENT,
51  EXTINFO_TYPE_FIXED = 0x7F // Must exist at a fixed location.
52 };
53 
54 #ifdef F__iopcontrol_special_internals
55 u8 iopbtconf_img[IOPBTCONF_IOP_MAX_SIZE] __attribute__((aligned(64)));
56 
57 struct payload_img
58 {
59  romdir_t romdir[5];
60 };
61 
62 static const struct payload_img g_payload_img_base = {
63  {{"RESET", 0, 0},
64  {"ROMDIR", 0, 0x50},
65  {"0", 0, 0},
66  {"1", 0, 0},
67  {"", 0, 0}},
68  };
69 
70 int send_romdrv_rom1_payloads(void *payload1, int payload1_size, void *payload2, int payload2_size)
71 {
72  unsigned int i;
73  unsigned int size_total;
74  struct payload_img cur_payload_img __attribute__((__aligned__(64)));
75  SifDmaTransfer_t dmat[3];
76  int trid;
77 
78  cur_payload_img = g_payload_img_base;
79  dmat[0].src = &cur_payload_img;
80  dmat[0].size = sizeof(cur_payload_img);
81  dmat[1].src = payload1;
82  dmat[1].size = (payload1_size + 15) & -16;
83  dmat[2].src = payload2;
84  dmat[2].size = (payload2_size + 15) & -16;
85  for (i = 0; i < (sizeof(dmat)/sizeof(dmat[0])); i += 1)
86  dmat[i].attr = 0;
87  cur_payload_img.romdir[1].size = dmat[0].size;
88  cur_payload_img.romdir[2].size = dmat[1].size;
89  cur_payload_img.romdir[3].size = dmat[2].size;
90  size_total = 0;
91  for (i = 0; i < (sizeof(dmat)/sizeof(dmat[0])); i += 1)
92  size_total += dmat[i].size;
93  dmat[0].dest = SifAllocIopHeap(size_total);
94  if (!dmat[0].dest)
95  return -1;
96  for (i = 1; i < (sizeof(dmat)/sizeof(dmat[0])); i += 1)
97  dmat[i].dest = ((u8 *)dmat[i - 1].dest) + dmat[i - 1].size;
98  for (i = 0; i < (sizeof(dmat)/sizeof(dmat[0])); i += 1)
99  sceSifWriteBackDCache(dmat[i].src, dmat[i].size);
100  while (!(trid = sceSifSetDma(dmat, sizeof(dmat) / sizeof(dmat[0]))));
101  while (sceSifDmaStat(trid) >= 0);
102  return sbv_patch_romdrv_set_rom1_info(dmat[0].dest, dmat[0].size) ? 1 : 0;
103 }
104 #endif
105 
106 // Our LOADFILE functions are slightly different.
107 #define SifLoadModuleSpecial(path, arg_len, args, dontwait) \
108  _SifLoadModule(path, arg_len, args, NULL, LF_F_MOD_LOAD, dontwait)
109 
110 #define SifLoadModuleEncryptedSpecial(path, arg_len, args, dontwait) \
111  _SifLoadModule(path, arg_len, args, NULL, LF_F_MG_MOD_LOAD, dontwait)
112 
113 #ifdef F_SifIopRebootBufferEncrypted
114 int SifIopRebootBufferEncrypted(const void *udnl, int size)
115 {
116  int iopbtconf_img_size;
117 
118  sceSifInitRpc(0);
119  sceSifExitRpc();
120 
121  SifIopReset("", 0);
122  while (!SifIopSync());
123 
124  iopbtconf_img_size = 0; // No support for IOPBTCONF manipulation
125 
126  /* Unofficial: Use following instead of patching LoadModuleBuffer and using embedded imgdrv */
127  if (send_romdrv_rom1_payloads((void *)udnl, size, iopbtconf_img, iopbtconf_img_size))
128  return -1;
129 
130  /* Unofficial: do not load rom:SYSCLIB (DMA end checking is done above) */
131  /* If ELF header detected, load UDNL as unencrypted module */
132  (void)((((u32 *)udnl)[0] == 0x464c457f) ? SifLoadModuleSpecial("rom1:0", 0, NULL, 1) : SifLoadModuleEncryptedSpecial("rom1:0", 0, NULL, 1));
133 
134  sceSifExitRpc();
135  SifLoadFileExit();
136 
137  sceSifSetReg(SIF_REG_SMFLAG, SIF_STAT_SIFINIT);
138  sceSifSetReg(SIF_REG_SMFLAG, SIF_STAT_CMDINIT);
139  sceSifSetReg(SIF_REG_SMFLAG, SIF_STAT_BOOTEND);
140  sceSifSetReg(SIF_SYSREG_RPCINIT, 0);
141  sceSifSetReg(SIF_SYSREG_SUBADDR, 0);
142 
143  _iop_reboot_count++; // Not originally here: increment to allow RPC clients to detect unbinding.
144 
145  return 1;
146 }
147 #endif
148 
149 #ifdef F_SifIopRebootBuffer
150 static int generateIOPBTCONF_img(void *output, void *ioprp);
151 
152 int SifIopRebootBuffer(void *ioprp, int size)
153 {
154  int iopbtconf_img_size;
155 
156  sceSifInitRpc(0);
157  sceSifExitRpc();
158 
159  SifIopReset("", 0);
160  while (!SifIopSync());
161 
162  iopbtconf_img_size = generateIOPBTCONF_img(iopbtconf_img, ioprp);
163 
164  /* Unofficial: Use following instead of patching LoadModuleBuffer and using embedded imgdrv */
165  if (send_romdrv_rom1_payloads((void *)ioprp, size, iopbtconf_img, iopbtconf_img_size))
166  return -1;
167 
168  /* Unofficial: do not load rom:SYSCLIB (DMA end checking is done above) */
169  SifLoadModuleSpecial("rom:UDNL", 13, "rom1:0\x00rom1:1", 1);
170 
171  sceSifExitRpc();
172  SifLoadFileExit();
173 
174  sceSifSetReg(SIF_REG_SMFLAG, SIF_STAT_SIFINIT);
175  sceSifSetReg(SIF_REG_SMFLAG, SIF_STAT_CMDINIT);
176  sceSifSetReg(SIF_REG_SMFLAG, SIF_STAT_BOOTEND);
177  sceSifSetReg(SIF_SYSREG_RPCINIT, 0);
178  sceSifSetReg(SIF_SYSREG_SUBADDR, 0);
179 
180  _iop_reboot_count++; // Not originally here: increment to allow RPC clients to detect unbinding.
181 
182  return 1;
183 }
184 
185 struct iopbtconf_img
186 {
187  romdir_t romdir[5];
188  u32 extinfo[4];
189 };
190 
191 static const struct iopbtconf_img iopbtconf_img_base = {
192  {{"RESET", 8, 0},
193  {"ROMDIR", 0, 0x50},
194  {"EXTINFO", 0, 0x10},
195  {"IOPBTCONF", 8, -1},
196  {"", 0, 0}},
197  {
198  0x01040000, // EXTINFO {0x0000, 4, EXTINFO_TYPE_DATE},
199  0x20010406, // Date: 2001/04/06
200  0x01040000, // EXTINFO {0x0000, 4, EXTINFO_TYPE_DATE},
201  0x20010406, // Date: 2001/04/06
202  }};
203 
204 /* Generate an IOPRP image that contains IOPBTCONF, if the original contains IOPBTCONF.
205  This is required because UDNL will only seach succeeding IOPRP images for modules specified within IOPBTCONF. */
206 static int generateIOPBTCONF_img(void *output, void *ioprp)
207 {
208  int offset, fsize_rounded;
209  romdir_t *romdir;
210  u8 *ptr_in;
211  u8 *ptr_out;
212 
213  romdir = (romdir_t *)ioprp;
214  if (strcmp(romdir[0].name, "RESET") || strcmp(romdir[1].name, "ROMDIR"))
215  return -1;
216 
217  // Now locate IOPBTCONF
218  for (offset = 0; romdir->name[0] != '\0'; romdir++, offset += fsize_rounded) {
219  fsize_rounded = (romdir->size + 15) & ~15;
220  /* Unofficial: Check for already-patched image */
221  if (!strcmp(romdir->name, "IOPBTCONF") || !strcmp(romdir->name, "XOPBTCONF")) {
222  romdir->name[0] = 'X'; // Change 'IOPBTCONF' to 'XOPBTCONF', so that UDNL will not find the original.
223  // Copy IOPBTCONF into the new image.
224  ptr_out = (u8 *)output;
225  ptr_in = (u8 *)ioprp;
226  memcpy(ptr_out, &iopbtconf_img_base, sizeof(iopbtconf_img_base));
227  memcpy(ptr_out + sizeof(iopbtconf_img_base), &ptr_in[offset], romdir->size);
228  ((romdir_t *)ptr_out)[3].size = romdir->size; // Update the size of IOPBTCONF within the generated IOPRP image.
229  return romdir->size + sizeof(iopbtconf_img_base);
230  }
231  }
232 
233  return 0;
234 }
235 #endif
kernel.h
SIF_STAT_CMDINIT
#define SIF_STAT_CMDINIT
Definition: sifdma.h:48
SifIopSync
int SifIopSync(void)
sifdma.h
loadfile.h
SifIopRebootBufferEncrypted
int SifIopRebootBufferEncrypted(const void *udnl, int size)
romdir
Definition: SifIopRebootBuffer.c:33
iopcontrol.h
SIF_REG_SMFLAG
@ SIF_REG_SMFLAG
Definition: sifdma.h:36
iopheap.h
SifIopRebootBuffer
int SifIopRebootBuffer(void *ioprp, int size)
__attribute__
typedef __attribute__
Definition: tlbfunc.c:60
sbv_patches.h
sbv_patch_romdrv_set_rom1_info
int sbv_patch_romdrv_set_rom1_info(void *iop_reset_addr, int romdir_size)
Definition: patch_romdrv_set_rom1_info.c:29
t_SifDmaTransfer
Definition: sifdma.h:52
SifLoadFileExit
void SifLoadFileExit(void)
SifIopReset
int SifIopReset(const char *arg, int mode)
SIF_STAT_BOOTEND
#define SIF_STAT_BOOTEND
Definition: sifdma.h:50
extinfo
Definition: SifIopRebootBuffer.c:40
SIF_STAT_SIFINIT
#define SIF_STAT_SIFINIT
Definition: sifdma.h:46
__attribute__
Definition: gif_registers.h:38
iopcontrol_special.h