1 /*-------------------------------------------------------------
6 Michael Wiedenbauer (shagkur)
7 Dave Murphy (WinterMute)
10 This software is provided 'as-is', without any express or implied
11 warranty. In no event will the authors be held liable for any
12 damages arising from the use of this software.
14 Permission is granted to anyone to use this software for any
15 purpose, including commercial applications, and to alter it and
16 redistribute it freely, subject to the following restrictions:
18 1. The origin of this software must not be misrepresented; you
19 must not claim that you wrote the original software. If you use
20 this software in a product, an acknowledgment in the product
21 documentation would be appreciated but is not required.
23 2. Altered source versions must be plainly marked as such, and
24 must not be misrepresented as being the original software.
26 3. This notice may not be removed or altered from any source
29 -------------------------------------------------------------*/
36 #include "processor.h"
44 #define IOS_HEAP_SIZE 0x1000
45 #define MAX_IPC_RETRIES 400
49 #define IOS_MAX_VERSION 61
50 #define IOS_MIN_VERSION 28
52 static s32 __ios_hid
= -1;
53 extern void udelay(int us
);
55 s32
__IOS_InitHeap(void)
58 __ios_hid
= iosCreateHeap(IOS_HEAP_SIZE
);
59 if(__ios_hid
< 0) return __ios_hid
;
64 // These two functions deal with the "internal" IOS subsystems that are used by default by libogc
65 // Other stuff should be inited by the user and deinited by the exit callbacks. The user is also responsible
66 // for deiniting other stuff before an IOS reload and reiniting them after.
67 s32
__IOS_InitializeSubsystems(void)
72 printf("IOS Subsystem Init\n");
78 printf("ES Init failed: %d\n",ret
);
85 printf("STM Init failed: %d\n",ret
);
89 printf("IOS Subsystem Init Done: %d\n",ret
);
94 s32
__IOS_ShutdownSubsystems(void)
99 printf("IOS Subsystem Close\n");
102 if(res
< 0) ret
= res
;
104 if(res
< 0) ret
= res
;
106 printf("IOS Subsystem Close Done: %d\n",ret
);
111 s32
IOS_GetPreferredVersion()
113 int ver
= IOS_EBADVERSION
;
121 res
= __IOS_InitHeap();
122 if(res
<0) return res
;
124 res
= ES_GetNumTitles(&count
);
127 printf(" GetNumTitles failed: %d\n",res
);
132 printf(" %d titles on card:\n",count
);
134 titles
= iosAlloc(__ios_hid
, sizeof(u64
)*count
);
136 printf(" iosAlloc titles failed\n");
139 res
= ES_GetTitles(titles
, count
);
142 printf(" GetTitles failed: %d\n",res
);
144 iosFree(__ios_hid
, titles
);
148 u32
*tmdbuffer
= memalign(32, MAX_SIGNED_TMD_SIZE
);
152 iosFree(__ios_hid
, titles
);
156 for(i
=0; i
<count
; i
++) {
158 b
= titles
[i
]&0xFFFFFFFF;
160 if(b
< IOS_MIN_VERSION
) continue;
161 if(b
> IOS_MAX_VERSION
) continue;
163 if (ES_GetStoredTMDSize(titles
[i
], &tmd_size
) < 0)
166 if (tmd_size
< 0 || tmd_size
> 4096)
169 if(ES_GetStoredTMD(titles
[i
], (signed_blob
*)tmdbuffer
, tmd_size
) < 0)
172 if (!tmdbuffer
[1] && !tmdbuffer
[2])
175 if((((s32
)b
) > ((s32
)ver
) && ver
!= 58) || b
== 58) ver
= b
;
178 printf(" Preferred verson: %d\n",ver
);
180 iosFree(__ios_hid
, titles
);
189 DCInvalidateRange((void*)0x80003140,8);
190 vercode
= *((u32
*)0x80003140);
191 version
= vercode
>> 16;
192 if(version
== 0) return IOS_EBADVERSION
;
193 if(version
> 0xff) return IOS_EBADVERSION
;
197 s32
IOS_GetRevision()
201 DCInvalidateRange((void*)0x80003140,8);
202 vercode
= *((u32
*)0x80003140);
203 rev
= vercode
& 0xFFFF;
204 if(vercode
== 0 || rev
== 0) return IOS_EBADVERSION
;
208 s32
IOS_GetRevisionMajor()
211 rev
= IOS_GetRevision();
212 if(rev
< 0) return rev
;
213 return (rev
>>8)&0xFF;
216 s32
IOS_GetRevisionMinor()
219 rev
= IOS_GetRevision();
220 if(rev
< 0) return rev
;
224 s32
__IOS_LaunchNewIOS(int version
)
228 u64 titleID
= 0x100000000LL
;
229 raw_irq_handler_t irq_handler
;
232 STACK_ALIGN(tikview
,views
,4,32);
238 if(version
< 3 || version
> 0xFF) {
239 return IOS_EBADVERSION
;
243 oldversion
= IOS_GetVersion();
244 if(oldversion
>0) printf("Current IOS Version: IOS%d\n",oldversion
);
249 printf("Launching IOS TitleID: %016llx\n",titleID
);
252 res
= ES_GetNumTicketViews(titleID
, &numviews
);
255 printf(" GetNumTicketViews failed: %d\n",res
);
260 printf(" GetNumTicketViews too many views: %u\n",numviews
);
261 return IOS_ETOOMANYVIEWS
;
263 res
= ES_GetTicketViews(titleID
, views
, numviews
);
266 printf(" GetTicketViews failed: %d\n",res
);
271 write32(0x80003140, 0);
273 res
= ES_LaunchTitleBackground(titleID
, &views
[0]);
276 printf(" LaunchTitleBackground failed: %d\n",res
);
283 // Mask IPC IRQ while we're busy reloading
284 __MaskIrq(IRQ_PI_ACR
);
285 irq_handler
= IRQ_Free(IRQ_PI_ACR
);
288 printf("Waiting for IOS ...\n");
290 while ((read32(0x80003140) >> 16) == 0)
294 u32 v
= read32(0x80003140);
295 printf("IOS loaded: IOS%d v%d.%d\n", v
>> 16, (v
>> 8) & 0xff, v
& 0xff);
299 printf("Waiting for IPC ...\n");
301 for (counter
= 0; !(read32(0x0d000004) & 2); counter
++) {
304 if (counter
>= MAX_IPC_RETRIES
)
309 printf("IPC started (%u)\n", counter
);
312 IRQ_Request(IRQ_PI_ACR
, irq_handler
, NULL
);
313 __UnmaskIrq(IRQ_PI_ACR
);
315 __IPC_Reinitialize();
317 newversion
= IOS_GetVersion();
319 if(newversion
!= version
) {
321 printf(" Version mismatch!\n");
323 return IOS_EMISMATCH
;
329 s32
__attribute__((weak
)) __IOS_LoadStartupIOS()
336 if(res
< 0) return res
;
337 version
= IOS_GetPreferredVersion();
340 printf("GetPreferredVersion failed: %d\n",version
);
346 printf("Loading startup IOS: %d\n",version
);
348 res
= __IOS_LaunchNewIOS(version
);
349 if(res
< 0) return res
;
355 s32
IOS_ReloadIOS(int version
)
361 printf("Reloading to IOS%d\n",version
);
364 res
= __IOS_ShutdownSubsystems();
367 printf("__IOS_ShutdownSubsystems failed: %d\n", res
);
375 printf("__ES_Init failed: %d\n", res
);
379 res
= __IOS_LaunchNewIOS(version
);
382 printf("__IOS_LaunchNewIOS failed: %d\n", res
);
389 res
= __IOS_InitializeSubsystems();
392 printf("__IOS_InitializeSubsystems failed: %d\n", res
);
400 #endif /* defined(HW_RVL) */