tinysmb devoptab fix - allow fread sizes > 7236
[libogc.git] / libogc / ios.c
blobeca0e2bd929d1b0166abd41ec05d0a02d987f53e
1 /*-------------------------------------------------------------
3 ios.c -- IOS control
5 Copyright (C) 2008
6 Michael Wiedenbauer (shagkur)
7 Dave Murphy (WinterMute)
8 Hector Martin (marcan)
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
27 distribution.
29 -------------------------------------------------------------*/
31 #if defined(HW_RVL)
33 #include <stdio.h>
34 #include "asm.h"
35 #include "processor.h"
36 #include "cache.h"
37 #include "ipc.h"
38 #include "stm.h"
39 #include "es.h"
40 #include "ios.h"
42 #define IOS_HEAP_SIZE 0x1000
44 //#define DEBUG_IOS
46 #define IOS_MAX_VERSION 36
47 #define IOS_MIN_VERSION 3
49 static s32 __ios_hid = -1;
51 s32 __IOS_InitHeap(void)
53 if(__ios_hid <0 ) {
54 __ios_hid = iosCreateHeap(IOS_HEAP_SIZE);
55 if(__ios_hid < 0) return __ios_hid;
57 return 0;
60 // These two functions deal with the "internal" IOS subsystems that are used by default by libogc
61 // Other stuff should be inited by the user and deinited by the exit callbacks. The user is also responsible
62 // for deiniting other stuff before an IOS reload and reiniting them after.
63 s32 __IOS_InitializeSubsystems(void)
65 s32 res;
66 s32 ret = 0;
67 #ifdef DEBUG_IOS
68 printf("IOS Subsystem Init\n");
69 #endif
70 res = __ES_Init();
71 if(res < 0) {
72 ret = res;
73 #ifdef DEBUG_IOS
74 printf("ES Init failed: %d\n",ret);
75 #endif
77 res = __STM_Init();
78 if(res < 0) {
79 ret = res;
80 #ifdef DEBUG_IOS
81 printf("STM Init failed: %d\n",ret);
82 #endif
84 #ifdef DEBUG_IOS
85 printf("IOS Subsystem Init Done: %d\n",ret);
86 #endif
87 return ret;
90 s32 __IOS_ShutdownSubsystems(void)
92 s32 res;
93 s32 ret = 0;
94 #ifdef DEBUG_IOS
95 printf("IOS Subsystem Close\n");
96 #endif
97 res = __STM_Close();
98 if(res < 0) ret = res;
99 res = __ES_Close();
100 if(res < 0) ret = res;
101 #ifdef DEBUG_IOS
102 printf("IOS Subsystem Close Done: %d\n",ret);
103 #endif
104 return ret;
107 s32 IOS_GetPreferredVersion()
109 int ver = IOS_EBADVERSION;
110 s32 res;
111 u32 count;
112 u64 *titles;
113 u32 i;
114 u32 a,b;
116 res = __IOS_InitHeap();
117 if(res<0) return res;
119 res = ES_GetNumTitles(&count);
120 if(res < 0) {
121 #ifdef DEBUG_IOS
122 printf(" GetNumTitles failed: %d\n",res);
123 #endif
124 return res;
126 #ifdef DEBUG_IOS
127 printf(" %d titles on card:\n",count);
128 #endif
129 titles = iosAlloc(__ios_hid, sizeof(u64)*count);
130 if(!titles) {
131 printf(" iosAlloc titles failed\n");
132 return -1;
134 res = ES_GetTitles(titles, count);
135 if(res < 0) {
136 #ifdef DEBUG_IOS
137 printf(" GetTitles failed: %d\n",res);
138 #endif
139 iosFree(__ios_hid, titles);
140 return res;
143 for(i=0; i<count; i++) {
144 a = titles[i]>>32;
145 b = titles[i]&0xFFFFFFFF;
146 if(a != 1) continue;
147 if(b < IOS_MIN_VERSION) continue;
148 if(b > IOS_MAX_VERSION) continue;
149 if(((s32)b) > ((s32)ver)) ver = b;
151 #ifdef DEBUG_IOS
152 printf(" Preferred verson: %d\n",ver);
153 #endif
154 iosFree(__ios_hid, titles);
155 return ver;
158 s32 IOS_GetVersion()
160 u32 vercode;
161 u16 version;
162 DCInvalidateRange((void*)0x80003140,8);
163 vercode = *((u32*)0x80003140);
164 version = vercode >> 16;
165 if(version == 0) return IOS_EBADVERSION;
166 if(version > 0xff) return IOS_EBADVERSION;
167 return version;
170 s32 IOS_GetRevision()
172 u32 vercode;
173 u16 rev;
174 DCInvalidateRange((void*)0x80003140,8);
175 vercode = *((u32*)0x80003140);
176 rev = vercode & 0xFFFF;
177 if(vercode == 0 || rev == 0) return IOS_EBADVERSION;
178 return rev;
181 s32 IOS_GetRevisionMajor()
183 s32 rev;
184 rev = IOS_GetRevision();
185 if(rev < 0) return rev;
186 return (rev>>8)&0xFF;
189 s32 IOS_GetRevisionMinor()
191 s32 rev;
192 rev = IOS_GetRevision();
193 if(rev < 0) return rev;
194 return rev&0xFF;
197 s32 __IOS_LaunchNewIOS(int version)
199 u32 numviews;
200 s32 res;
201 u64 titleID = 0x100000000LL;
202 STACK_ALIGN(tikview,views,4,32);
203 #ifdef DEBUG_IOS
204 s32 oldversion;
205 #endif
206 s32 newversion;
208 if(version < 3 || version > 0xFF) {
209 return IOS_EBADVERSION;
212 #ifdef DEBUG_IOS
213 oldversion = IOS_GetVersion();
214 if(oldversion>0) printf("Current IOS Version: IOS%d\n",oldversion);
215 #endif
217 titleID |= version;
218 #ifdef DEBUG_IOS
219 printf("Launching IOS TitleID: %016llx\n",titleID);
220 #endif
222 res = ES_GetNumTicketViews(titleID, &numviews);
223 if(res < 0) {
224 #ifdef DEBUG_IOS
225 printf(" GetNumTicketViews failed: %d\n",res);
226 #endif
227 return res;
229 if(numviews > 4) {
230 printf(" GetNumTicketViews too many views: %u\n",numviews);
231 return IOS_ETOOMANYVIEWS;
233 res = ES_GetTicketViews(titleID, views, numviews);
234 if(res < 0) {
235 #ifdef DEBUG_IOS
236 printf(" GetTicketViews failed: %d\n",res);
237 #endif
238 return res;
240 res = ES_LaunchTitle(titleID, &views[0]);
241 if(res < 0) {
242 #ifdef DEBUG_IOS
243 printf(" LaunchTitle failed: %d\n",res);
244 #endif
245 return res;
247 __ES_Reset();
248 newversion = IOS_GetVersion();
249 #ifdef DEBUG_IOS
250 printf(" IOS Version: IOS%d %d.%d\n",newversion,IOS_GetRevisionMajor(),IOS_GetRevisionMinor());
251 #endif
252 if(newversion != version) {
253 #ifdef DEBUG_IOS
254 printf(" Version mismatch!\n");
255 #endif
256 return IOS_EMISMATCH;
258 return version;
261 s32 __attribute__((weak)) __IOS_LoadStartupIOS()
263 int version;
264 int res;
266 res = __ES_Init();
267 if(res < 0) return res;
268 version = IOS_GetPreferredVersion();
269 if(version < 0) {
270 #ifdef DEBUG_IOS
271 printf("GetPreferredVersion failed: %d\n",version);
272 #endif
273 __ES_Close();
274 return version;
276 #ifdef DEBUG_IOS
277 printf("Loading startup IOS: %d\n",version);
278 #endif
279 res = __IOS_LaunchNewIOS(version);
280 if(res < 0) return res;
281 return 0;
284 s32 IOS_ReloadIOS(int version)
286 int ret = 0;
287 int res;
288 #ifdef DEBUG_IOS
289 printf("Reloading to IOS%d\n",version);
290 #endif
291 res = __IOS_ShutdownSubsystems();
292 if(res < 0) ret = res;
293 res = __ES_Init();
294 if(res < 0) ret = res;
295 else {
296 res = __IOS_LaunchNewIOS(version);
297 if(res < 0) {
298 ret = res;
299 __ES_Close();
302 res = __IOS_InitializeSubsystems();
303 if(res < 0) ret = res;
304 return ret;
307 #endif /* defined(HW_RVL) */