13 #define _LANGUAGE_ASSEMBLY
14 #include <ogc/machine/asm.h>
15 #undef _LANGUAGE_ASSEMBLY
19 #include <ogc/lwp_threads.h>
20 #include <ogc/machine/processor.h>
22 static context_storage di_ctx
;
24 #define IOS_HEAP_SIZE 0x1000
26 void __IPC_Reinitialize(void);
28 static vu32
* const _piReg
= (u32
*)0xCC003000;
29 static vu16
* const _memReg
= (u16
*)0xCC004000;
31 //#define DEBUG_DVD_STUB
34 #define dprintf printf
39 static void dumpregs(void)
41 dprintf(" MSR: %08x\n",mfmsr());
42 dprintf(" SPRGx: %08x %08x %08x %08x\n", mfspr(SPRG0
), mfspr(SPRG1
), mfspr(SPRG2
), mfspr(SPRG3
));
43 dprintf(" HID0124: %08x %08x %08x %08x\n", mfspr(HID0
), mfspr(HID1
), mfspr(HID2
), mfspr(HID4
));
44 dprintf(" L2CR: %08x\n", mfspr(L2CR
));
45 dprintf(" WPAR: %08x\n", mfspr(WPAR
));
46 dprintf(" PMCx: %08x %08x %08x %08x\n", mfspr(PMC1
), mfspr(PMC2
), mfspr(PMC3
), mfspr(PMC4
));
47 dprintf(" MMCRx: %08x %08x\n", mfspr(MMCR0
), mfspr(MMCR1
));
49 dprintf(" PI Regs: %08x %08x %08x %08x\n", _piReg[0], _piReg[1], _piReg[2], _piReg[3]);
50 dprintf(" %08x %08x %08x %08x\n", _piReg[4], _piReg[5], _piReg[6], _piReg[7]);
51 dprintf(" %08x %08x %08x %08x\n", _piReg[8], _piReg[9], _piReg[10], _piReg[11]);
54 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]);
55 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]);
56 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]);
57 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]);
58 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]);
59 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]);
63 static register_storage di_regs
;
65 static void __distub_saveregs(void)
68 di_regs
.timebase
= gettime();
70 di_regs
.piReg
[i
] = _piReg
[i
];
73 static void __distub_restregs(void)
77 _piReg
[i
] = di_regs
.piReg
[i
];
78 //i = _piReg[0]; //clear all interrupts
79 settime(di_regs
.timebase
);
82 u32
__di_check_ahbprot(void) {
86 STACK_ALIGN(u32
, tmdbuf
, 1024, 32);
91 dprintf("ES failed to initialize\n");
95 res
= ES_GetTitleID(&title_id
);
97 dprintf("ES_GetTitleID() failed: %d\n", res
);
101 res
= ES_GetStoredTMDSize(title_id
, &tmd_size
);
103 dprintf("ES_GetStoredTMDSize() failed: %d\n", res
);
107 if (tmd_size
> 4096) {
108 dprintf("TMD too big: %d\n", tmd_size
);
112 res
= ES_GetStoredTMD(title_id
, tmdbuf
, tmd_size
);
114 dprintf("ES_GetStoredTMD() failed: %d\n", res
);
118 if ((tmdbuf
[0x76] & 3) == 3) {
119 dprintf("ahbprot flags are set!\n");
123 dprintf("ahbprot flags are not set!\n");
127 static u32
__di_find_stub(u64
*title_id
) {
129 u32 count
, i
, tmd_view_size
;
131 u16 rev_highest
, rev_this
;
132 STACK_ALIGN(u8
, tmdbuf
, 1024, 32);
137 ios_hid
= iosCreateHeap(IOS_HEAP_SIZE
);
139 dprintf("iosCreateHeap() failed: %d\n", ios_hid
);
143 res
= ES_GetNumTitles(&count
);
145 iosDestroyHeap(ios_hid
);
146 dprintf("ES_GetNumTitles() failed: %d\n", res
);
150 dprintf("%u titles are installed\n", count
);
152 titles
= iosAlloc(ios_hid
, sizeof(u64
) * count
);
154 iosDestroyHeap(ios_hid
);
155 dprintf("iosAlloc() failed\n");
159 res
= ES_GetTitles(titles
, count
);
161 iosFree(ios_hid
, titles
);
162 iosDestroyHeap(ios_hid
);
163 dprintf("ES_GetTitles() failed: %d\n", res
);
167 for (i
= 0; i
< count
; i
++) {
168 if ((titles
[i
] >> 32) != 0x00010008)
171 dprintf("found hidden title 0x%llx\n", titles
[i
]);
173 res
= ES_GetTMDViewSize(titles
[i
], &tmd_view_size
);
175 dprintf("ES_GetTMDViewSize() failed: %d\n", res
);
179 if (tmd_view_size
< 90) {
180 dprintf("TMD too small: %d\n", tmd_view_size
);
184 if (tmd_view_size
> 1024) {
185 dprintf("TMD too big: %d\n", tmd_view_size
);
189 res
= ES_GetTMDView(titles
[i
], tmdbuf
, tmd_view_size
);
191 dprintf("ES_GetTMDView() failed: %d\n", res
);
195 if ((tmdbuf
[0x18] == 'D') && (tmdbuf
[0x19] == 'V')) {
196 rev_this
= (tmdbuf
[88] << 8) | tmdbuf
[89];
197 dprintf("found stub with revision 0x%x\n", rev_this
);
199 if (rev_this
> rev_highest
) {
200 *title_id
= titles
[i
];
201 rev_highest
= rev_this
;
206 iosFree(ios_hid
, titles
);
207 iosDestroyHeap(ios_hid
);
210 dprintf("we have a winner: 0x%llx\n", *title_id
);
217 s32
__DI_StubLaunch(void)
220 static tikview views
[4] ATTRIBUTE_ALIGN(32);
225 res
= __di_find_stub(&titleID
);
227 dprintf("stub not installed\n");
231 dprintf("Stopping thread timeslice ticker\n");
232 __lwp_thread_stoptimeslice();
234 dprintf("Shutting down IOS subsystems\n");
235 res
= __IOS_ShutdownSubsystems();
237 dprintf("Shutdown failed: %d\n",res
);
239 dprintf("Initializing ES\n");
242 dprintf("Launching TitleID: %016llx\n",titleID
);
244 res
= ES_GetNumTicketViews(titleID
, &numviews
);
246 dprintf(" GetNumTicketViews failed: %d\n",res
);
247 __IOS_InitializeSubsystems();
248 __lwp_thread_starttimeslice();
252 dprintf(" GetNumTicketViews too many views: %u\n",numviews
);
253 __IOS_InitializeSubsystems();
254 __lwp_thread_starttimeslice();
255 return IOS_ETOOMANYVIEWS
;
257 res
= ES_GetTicketViews(titleID
, views
, numviews
);
259 dprintf(" GetTicketViews failed: %d\n",res
);
260 __IOS_InitializeSubsystems();
261 __lwp_thread_starttimeslice();
264 dprintf("Ready to launch channel\n");
265 res
= ES_LaunchTitleBackground(titleID
, &views
[0]);
267 dprintf("Launch failed: %d\n",res
);
268 __IOS_InitializeSubsystems();
269 __lwp_thread_starttimeslice();
273 dprintf("Channel launching in the background\n");
274 dprintf("Pre-stub status:\n");
276 dprintf("ISR Disable...\n");
277 _CPU_ISR_Disable( ints
);
278 dprintf("Saving regs...\n");
280 dprintf("Taking the plunge...\n");
281 __distub_take_plunge(&di_ctx
);
283 dprintf("We're back!\n");
284 dprintf("Restoring regs...\n");
286 dprintf("ISR Enable...\n");
287 _CPU_ISR_Restore( ints
);
289 dprintf("Post-stub status:\n");
292 __IPC_Reinitialize();
295 dprintf("IPC reinitialized\n");
297 dprintf("Restarting IOS subsystems\n");
299 res
= __IOS_InitializeSubsystems();
301 dprintf("Subsystems running!\n");
303 res
= ES_GetNumTicketViews(titleID
, &numviews
);
305 dprintf(" GetNumTicketViews failed: %d\n",res
);
307 dprintf(" GetNumTicketViews: %d\n",numviews
);
309 dprintf("Restarting threads timeslice ticker\n");
310 __lwp_thread_starttimeslice();