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_IOS_RETRIES 2000
45 #define MAX_IPC_RETRIES 2000
49 #define IOS_MAX_VERSION 61
50 #define IOS_MIN_VERSION 3
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
;
120 res
= __IOS_InitHeap();
121 if(res
<0) return res
;
123 res
= ES_GetNumTitles(&count
);
126 printf(" GetNumTitles failed: %d\n",res
);
131 printf(" %d titles on card:\n",count
);
133 titles
= iosAlloc(__ios_hid
, sizeof(u64
)*count
);
135 printf(" iosAlloc titles failed\n");
138 res
= ES_GetTitles(titles
, count
);
141 printf(" GetTitles failed: %d\n",res
);
143 iosFree(__ios_hid
, titles
);
147 for(i
=0; i
<count
; i
++) {
149 b
= titles
[i
]&0xFFFFFFFF;
151 if(b
< IOS_MIN_VERSION
) continue;
152 if(b
> IOS_MAX_VERSION
) continue;
153 if(((s32
)b
) > ((s32
)ver
)) ver
= b
;
156 printf(" Preferred verson: %d\n",ver
);
158 iosFree(__ios_hid
, titles
);
166 DCInvalidateRange((void*)0x80003140,8);
167 vercode
= *((u32
*)0x80003140);
168 version
= vercode
>> 16;
169 if(version
== 0) return IOS_EBADVERSION
;
170 if(version
> 0xff) return IOS_EBADVERSION
;
174 s32
IOS_GetRevision()
178 DCInvalidateRange((void*)0x80003140,8);
179 vercode
= *((u32
*)0x80003140);
180 rev
= vercode
& 0xFFFF;
181 if(vercode
== 0 || rev
== 0) return IOS_EBADVERSION
;
185 s32
IOS_GetRevisionMajor()
188 rev
= IOS_GetRevision();
189 if(rev
< 0) return rev
;
190 return (rev
>>8)&0xFF;
193 s32
IOS_GetRevisionMinor()
196 rev
= IOS_GetRevision();
197 if(rev
< 0) return rev
;
201 s32
__IOS_LaunchNewIOS(int version
)
205 u64 titleID
= 0x100000000LL
;
206 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 res
= ES_LaunchTitleBackground(titleID
, &views
[0]);
250 printf(" LaunchTitleBackground failed: %d\n",res
);
256 // Mask IPC IRQ while we're busy reloading
257 __MaskIrq(IRQ_PI_ACR
);
258 irq_handler
= IRQ_Free(IRQ_PI_ACR
);
260 // Wait for old IOS to change version number before reloading
261 for (retries
= 0; retries
< MAX_IOS_RETRIES
; retries
++)
263 newversion
= IOS_GetVersion();
265 printf(" IOS Version: IOS%d %d.%d\n",newversion
,IOS_GetRevisionMajor(),IOS_GetRevisionMinor());
267 if (newversion
!= version
) udelay(1000);
270 if(newversion
!= version
)
273 printf(" Version mismatch!\n");
275 return IOS_EMISMATCH
;
278 // Wait for new IOS to signal IPC is ready
279 for (retries
= 0; retries
< MAX_IPC_RETRIES
; retries
++)
281 if(IPC_ReadReg(1) & 2) break;
285 IRQ_Request(IRQ_PI_ACR
, irq_handler
, NULL
);
286 __UnmaskIrq(IRQ_PI_ACR
);
288 __IPC_Reinitialize();
293 s32
__attribute__((weak
)) __IOS_LoadStartupIOS()
300 if(res
< 0) return res
;
301 version
= IOS_GetPreferredVersion();
304 printf("GetPreferredVersion failed: %d\n",version
);
310 printf("Loading startup IOS: %d\n",version
);
312 res
= __IOS_LaunchNewIOS(version
);
313 if(res
< 0) return res
;
318 s32
IOS_ReloadIOS(int version
)
323 printf("Reloading to IOS%d\n",version
);
325 res
= __IOS_ShutdownSubsystems();
326 if(res
< 0) ret
= res
;
328 if(res
< 0) ret
= res
;
330 res
= __IOS_LaunchNewIOS(version
);
336 res
= __IOS_InitializeSubsystems();
337 if(res
< 0) ret
= res
;
341 #endif /* defined(HW_RVL) */