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 -------------------------------------------------------------*/
35 #include "processor.h"
43 #define IOS_HEAP_SIZE 0x1000
44 #define MAX_IPC_RETRIES 200
48 #define IOS_MAX_VERSION 61
49 #define IOS_MIN_VERSION 3
51 static s32 __ios_hid
= -1;
52 extern void udelay(int us
);
54 s32
__IOS_InitHeap(void)
57 __ios_hid
= iosCreateHeap(IOS_HEAP_SIZE
);
58 if(__ios_hid
< 0) return __ios_hid
;
63 // These two functions deal with the "internal" IOS subsystems that are used by default by libogc
64 // Other stuff should be inited by the user and deinited by the exit callbacks. The user is also responsible
65 // for deiniting other stuff before an IOS reload and reiniting them after.
66 s32
__IOS_InitializeSubsystems(void)
71 printf("IOS Subsystem Init\n");
77 printf("ES Init failed: %d\n",ret
);
84 printf("STM Init failed: %d\n",ret
);
88 printf("IOS Subsystem Init Done: %d\n",ret
);
93 s32
__IOS_ShutdownSubsystems(void)
98 printf("IOS Subsystem Close\n");
101 if(res
< 0) ret
= res
;
103 if(res
< 0) ret
= res
;
105 printf("IOS Subsystem Close Done: %d\n",ret
);
110 s32
IOS_GetPreferredVersion()
112 int ver
= IOS_EBADVERSION
;
119 res
= __IOS_InitHeap();
120 if(res
<0) return res
;
122 res
= ES_GetNumTitles(&count
);
125 printf(" GetNumTitles failed: %d\n",res
);
130 printf(" %d titles on card:\n",count
);
132 titles
= iosAlloc(__ios_hid
, sizeof(u64
)*count
);
134 printf(" iosAlloc titles failed\n");
137 res
= ES_GetTitles(titles
, count
);
140 printf(" GetTitles failed: %d\n",res
);
142 iosFree(__ios_hid
, titles
);
146 for(i
=0; i
<count
; i
++) {
148 b
= titles
[i
]&0xFFFFFFFF;
150 if(b
< IOS_MIN_VERSION
) continue;
151 if(b
> IOS_MAX_VERSION
) continue;
152 if(((s32
)b
) > ((s32
)ver
)) ver
= b
;
155 printf(" Preferred verson: %d\n",ver
);
157 iosFree(__ios_hid
, titles
);
165 DCInvalidateRange((void*)0x80003140,8);
166 vercode
= *((u32
*)0x80003140);
167 version
= vercode
>> 16;
168 if(version
== 0) return IOS_EBADVERSION
;
169 if(version
> 0xff) return IOS_EBADVERSION
;
173 s32
IOS_GetRevision()
177 DCInvalidateRange((void*)0x80003140,8);
178 vercode
= *((u32
*)0x80003140);
179 rev
= vercode
& 0xFFFF;
180 if(vercode
== 0 || rev
== 0) return IOS_EBADVERSION
;
184 s32
IOS_GetRevisionMajor()
187 rev
= IOS_GetRevision();
188 if(rev
< 0) return rev
;
189 return (rev
>>8)&0xFF;
192 s32
IOS_GetRevisionMinor()
195 rev
= IOS_GetRevision();
196 if(rev
< 0) return rev
;
200 s32
__IOS_LaunchNewIOS(int version
)
204 u64 titleID
= 0x100000000LL
;
205 raw_irq_handler_t irq_handler
;
208 STACK_ALIGN(tikview
,views
,4,32);
214 if(version
< 3 || version
> 0xFF) {
215 return IOS_EBADVERSION
;
219 oldversion
= IOS_GetVersion();
220 if(oldversion
>0) printf("Current IOS Version: IOS%d\n",oldversion
);
225 printf("Launching IOS TitleID: %016llx\n",titleID
);
228 res
= ES_GetNumTicketViews(titleID
, &numviews
);
231 printf(" GetNumTicketViews failed: %d\n",res
);
236 printf(" GetNumTicketViews too many views: %u\n",numviews
);
237 return IOS_ETOOMANYVIEWS
;
239 res
= ES_GetTicketViews(titleID
, views
, numviews
);
242 printf(" GetTicketViews failed: %d\n",res
);
247 write32(0x80003140, 0);
249 res
= ES_LaunchTitleBackground(titleID
, &views
[0]);
252 printf(" LaunchTitleBackground failed: %d\n",res
);
259 // Mask IPC IRQ while we're busy reloading
260 __MaskIrq(IRQ_PI_ACR
);
261 irq_handler
= IRQ_Free(IRQ_PI_ACR
);
264 printf("Waiting for IOS ...\n");
266 while ((read32(0x80003140) >> 16) == 0)
270 u32 v
= read32(0x80003140);
271 printf("IOS loaded: IOS%d v%d.%d\n", v
>> 16, (v
>> 8) & 0xff, v
& 0xff);
275 printf("Waiting for IPC ...\n");
277 for (counter
= 0; !(read32(0x0d000004) & 2); counter
++) {
280 if (counter
>= MAX_IPC_RETRIES
)
285 printf("IPC started (%u)\n", counter
);
288 IRQ_Request(IRQ_PI_ACR
, irq_handler
, NULL
);
289 __UnmaskIrq(IRQ_PI_ACR
);
291 __IPC_Reinitialize();
293 newversion
= IOS_GetVersion();
295 if(newversion
!= version
) {
297 printf(" Version mismatch!\n");
299 return IOS_EMISMATCH
;
305 s32
__attribute__((weak
)) __IOS_LoadStartupIOS()
312 if(res
< 0) return res
;
313 version
= IOS_GetPreferredVersion();
316 printf("GetPreferredVersion failed: %d\n",version
);
322 printf("Loading startup IOS: %d\n",version
);
324 res
= __IOS_LaunchNewIOS(version
);
325 if(res
< 0) return res
;
331 s32
IOS_ReloadIOS(int version
)
337 printf("Reloading to IOS%d\n",version
);
340 res
= __IOS_ShutdownSubsystems();
343 printf("__IOS_ShutdownSubsystems failed: %d\n", res
);
351 printf("__ES_Init failed: %d\n", res
);
355 res
= __IOS_LaunchNewIOS(version
);
358 printf("__IOS_LaunchNewIOS failed: %d\n", res
);
365 res
= __IOS_InitializeSubsystems();
368 printf("__IOS_InitializeSubsystems failed: %d\n", res
);
376 #endif /* defined(HW_RVL) */