dvd devoptab for GC now works, GC mem cards now work in Wii mode. Patches from emukidid.
[libogc.git] / libdi / stubload.c
blob02b6cbda1e47b32857940b31513bc41d1fc94d1a
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <malloc.h>
6 #include <ogcsys.h>
7 #include <gccore.h>
8 #include <stdarg.h>
9 #include <ctype.h>
10 #include <unistd.h>
12 // haxhaxhax
13 #define _LANGUAGE_ASSEMBLY
14 #include <ogc/machine/asm.h>
15 #undef _LANGUAGE_ASSEMBLY
17 #include "stubasm.h"
19 #include <ogc/lwp_threads.h>
20 #include <ogc/machine/processor.h>
22 context_storage di_ctx;
24 #define IOS_HEAP_SIZE 0x1000
26 void __IPC_Reinitialize(void);
27 extern void __exi_init();
29 static vu16* const _viReg = (u16*)0xCC002000;
30 static vu32* const _piReg = (u32*)0xCC003000;
31 static vu16* const _memReg = (u16*)0xCC004000;
32 static vu16* const _dspReg = (u16*)0xCC005000;
34 //#define DEBUG_DVD_STUB
36 #ifdef DEBUG_DVD_STUB
37 #define dprintf printf
38 #else
39 #define dprintf(...)
40 #endif
42 void dumpregs(void)
44 dprintf(" MSR: %08x\n",mfmsr());
45 dprintf(" SPRGx: %08x %08x %08x %08x\n", mfspr(SPRG0), mfspr(SPRG1), mfspr(SPRG2), mfspr(SPRG3));
46 dprintf(" HID0124: %08x %08x %08x %08x\n", mfspr(HID0), mfspr(HID1), mfspr(HID2), mfspr(HID4));
47 dprintf(" L2CR: %08x\n", mfspr(L2CR));
48 dprintf(" WPAR: %08x\n", mfspr(WPAR));
49 dprintf(" PMCx: %08x %08x %08x %08x\n", mfspr(PMC1), mfspr(PMC2), mfspr(PMC3), mfspr(PMC4));
50 dprintf(" MMCRx: %08x %08x\n", mfspr(MMCR0), mfspr(MMCR1));
52 dprintf(" PI Regs: %08x %08x %08x %08x\n", _piReg[0], _piReg[1], _piReg[2], _piReg[3]);
53 dprintf(" %08x %08x %08x %08x\n", _piReg[4], _piReg[5], _piReg[6], _piReg[7]);
54 dprintf(" %08x %08x %08x %08x\n", _piReg[8], _piReg[9], _piReg[10], _piReg[11]);
57 dprintf(" MI Regs: %04x %04x %04x %04x %04x %04x %04x %04x\n", _memReg[0], _memReg[1], _memReg[2], _memReg[3], _memReg[4], _memReg[5], _memReg[6], _memReg[7]);
58 dprintf(" %04x %04x %04x %04x %04x %04x %04x %04x\n", _memReg[8], _memReg[9], _memReg[10], _memReg[11], _memReg[12], _memReg[13], _memReg[14], _memReg[15]);
59 dprintf(" %04x %04x %04x %04x %04x %04x %04x %04x\n", _memReg[16], _memReg[17], _memReg[18], _memReg[19], _memReg[20], _memReg[21], _memReg[22], _memReg[23]);
60 dprintf(" %04x %04x %04x %04x %04x %04x %04x %04x\n", _memReg[24], _memReg[25], _memReg[26], _memReg[27], _memReg[28], _memReg[29], _memReg[30], _memReg[31]);
61 dprintf(" %04x %04x %04x %04x %04x %04x %04x %04x\n", _memReg[32], _memReg[33], _memReg[34], _memReg[35], _memReg[36], _memReg[37], _memReg[38], _memReg[39]);
62 dprintf(" %04x %04x %04x %04x %04x %04x %04x %04x\n", _memReg[40], _memReg[41], _memReg[42], _memReg[43], _memReg[44], _memReg[45], _memReg[46], _memReg[47]);
66 register_storage di_regs;
68 void __distub_saveregs(void)
70 int i;
71 di_regs.timebase = gettime();
72 for(i=1;i<6;i++)
73 di_regs.piReg[i] = _piReg[i];
76 void __distub_restregs(void)
78 int i;
79 for(i=1;i<6;i++)
80 _piReg[i] = di_regs.piReg[i];
81 //i = _piReg[0]; //clear all interrupts
82 settime(di_regs.timebase);
85 static u32 __di_find_stub(u64 *title_id) {
86 s32 ios_hid, res;
87 u32 count, i, tmd_view_size;
88 u64 *titles;
89 u16 rev_highest, rev_this;
90 STACK_ALIGN(u8, tmdbuf, 1024, 32);
92 *title_id = 0;
93 rev_highest = 0;
95 ios_hid = iosCreateHeap(IOS_HEAP_SIZE);
96 if (ios_hid < 0) {
97 dprintf("iosCreateHeap() failed: %d\n", ios_hid);
98 return ios_hid;
101 dprintf("Initializing ES\n");
102 __ES_Init();
104 res = ES_GetNumTitles(&count);
105 if (res < 0) {
106 iosDestroyHeap(ios_hid);
107 dprintf("ES_GetNumTitles() failed: %d\n", res);
108 return res;
111 dprintf("%u titles are installed\n", count);
113 titles = iosAlloc(ios_hid, sizeof(u64) * count);
114 if (!titles) {
115 iosDestroyHeap(ios_hid);
116 dprintf("iosAlloc() failed\n");
117 return -1;
120 res = ES_GetTitles(titles, count);
121 if (res < 0) {
122 iosFree(ios_hid, titles);
123 iosDestroyHeap(ios_hid);
124 dprintf("ES_GetTitles() failed: %d\n", res);
125 return res;
128 for (i = 0; i < count; i++) {
129 if ((titles[i] >> 32) != 0x00010008)
130 continue;
132 dprintf("found hidden title 0x%llx\n", titles[i]);
134 res = ES_GetTMDViewSize(titles[i], &tmd_view_size);
135 if (res < 0) {
136 dprintf("ES_GetTMDViewSize() failed: %d\n", res);
137 continue;
140 if (tmd_view_size < 90) {
141 dprintf("TMD too small: %d\n", tmd_view_size);
142 continue;
145 if (tmd_view_size > 1024) {
146 dprintf("TMD too big: %d\n", tmd_view_size);
147 continue;
150 res = ES_GetTMDView(titles[i], tmdbuf, tmd_view_size);
151 if (res < 0) {
152 dprintf("ES_GetTMDView() failed: %d\n", res);
153 continue;
156 // check the gid
157 if ((tmdbuf[0x18] == 'D') && (tmdbuf[0x19] == 'V')) {
158 rev_this = (tmdbuf[88] << 8) | tmdbuf[89];
159 dprintf("found stub with revision 0x%x\n", rev_this);
161 if (rev_this > rev_highest) {
162 *title_id = titles[i];
163 rev_highest = rev_this;
168 iosFree(ios_hid, titles);
169 iosDestroyHeap(ios_hid);
171 if (*title_id) {
172 dprintf("we have a winner: 0x%llx\n", *title_id);
173 return 0;
176 return -1;
179 s32 __DI_StubLaunch(void)
181 u64 titleID = 0;
182 static tikview views[4] ATTRIBUTE_ALIGN(32);
183 u32 numviews;
184 s32 res;
185 u32 ints;
187 res =__di_find_stub(&titleID);
188 if (res < 0) {
189 dprintf("stub not installed\n");
190 return res;
193 dprintf("Stopping thread timeslice ticker\n");
194 __lwp_thread_stoptimeslice();
196 dprintf("Shutting down IOS subsystems\n");
197 res = __IOS_ShutdownSubsystems();
198 if (res < 0)
199 dprintf("Shutdown failed: %d\n",res);
201 dprintf("Initializing ES\n");
202 __ES_Init();
204 dprintf("Launching TitleID: %016llx\n",titleID);
206 res = ES_GetNumTicketViews(titleID, &numviews);
207 if(res < 0) {
208 dprintf(" GetNumTicketViews failed: %d\n",res);
209 __IOS_InitializeSubsystems();
210 __lwp_thread_starttimeslice();
211 return res;
213 if(numviews > 4) {
214 dprintf(" GetNumTicketViews too many views: %u\n",numviews);
215 __IOS_InitializeSubsystems();
216 __lwp_thread_starttimeslice();
217 return IOS_ETOOMANYVIEWS;
219 res = ES_GetTicketViews(titleID, views, numviews);
220 if(res < 0) {
221 dprintf(" GetTicketViews failed: %d\n",res);
222 __IOS_InitializeSubsystems();
223 __lwp_thread_starttimeslice();
224 return res;
226 dprintf("Ready to launch channel\n");
227 res = ES_LaunchTitleBackground(titleID, &views[0]);
228 if(res<0) {
229 dprintf("Launch failed: %d\n",res);
230 __IOS_InitializeSubsystems();
231 __lwp_thread_starttimeslice();
232 return res;
235 dprintf("Channel launching in the background\n");
236 dprintf("Pre-stub status:\n");
237 dumpregs();
238 dprintf("ISR Disable...\n");
239 _CPU_ISR_Disable( ints );
240 dprintf("Saving regs...\n");
241 __distub_saveregs();
242 dprintf("Taking the plunge...\n");
243 __distub_take_plunge(&di_ctx);
245 dprintf("We're back!\n");
246 dprintf("Restoring regs...\n");
247 __distub_restregs();
248 dprintf("ISR Enable...\n");
249 _CPU_ISR_Restore( ints );
251 dprintf("Post-stub status:\n");
252 dumpregs();
254 __IPC_Reinitialize();
255 __ES_Reset();
257 dprintf("IPC reinitialized\n");
258 sleep(1);
259 dprintf("Restarting IOS subsystems\n");
261 res = __IOS_InitializeSubsystems();
263 dprintf("Subsystems running!\n");
265 res = ES_GetNumTicketViews(titleID, &numviews);
266 if(res < 0)
267 dprintf(" GetNumTicketViews failed: %d\n",res);
268 else
269 dprintf(" GetNumTicketViews: %d",numviews);
271 dprintf("Restarting threads timeslice ticker\n");
272 __lwp_thread_starttimeslice();
274 return 0;
278 s32 __DI_LoadStub(void)
280 int ret = 0;
281 int res;
283 res = __IOS_ShutdownSubsystems();
284 if(res < 0) ret = res;
285 res = __ES_Init();
286 if(res < 0) ret = res;
287 else {
288 res = __DI_StubLaunch();
289 if(res < 0) {
290 ret = res;
291 __ES_Close();
294 res = __IOS_InitializeSubsystems();
295 if(res < 0) ret = res;
296 return ret;