@@ -34,13 +34,15 @@ distribution.
34
34
#include "ipc.h"
35
35
#include "system.h"
36
36
#include "irq.h"
37
+ #include "processor.h"
38
+ #include "cache.h"
37
39
#include "stm.h"
38
40
39
41
#define DEBUG_STM
40
42
41
43
#ifdef DEBUG_STM
42
44
#include <stdio.h>
43
- #define STM_printf (fmt , ...) fprintf(stderr, fmt, ##__VA_ARGS__)
45
+ #define STM_printf (fmt , ...) printf("%s():%i: " fmt, __FUNCTION__, __LINE__ , ##__VA_ARGS__)
44
46
#else
45
47
#define STM_printf (fmt , ...) while (0) {};
46
48
#endif
@@ -69,7 +71,8 @@ struct eventhook {
69
71
70
72
static struct eventhook __stm_eventhook ;
71
73
72
- static s32 __STMEventHandler (s32 result ,void * usrdata );
74
+ static s32 __STMEventCallback (s32 result ,void * usrdata );
75
+ s32 __STM_SetEventHook (void );
73
76
s32 __STM_ReleaseEventHook (void );
74
77
75
78
static vu16 * const _viReg = (u16 * )0xCC002000 ;
@@ -94,14 +97,15 @@ s32 __STM_SetEventHook(void)
94
97
95
98
if (__stm_eventhook .fd < 0 ) {
96
99
__stm_eventhook .fd = ret = IOS_Open ("/dev/stm/eventhook" , 0 );
97
- if (ret < 0 )
100
+ if (ret < 0 ) {
101
+ STM_printf ("Failed to open STM eventhook (%i)\n" , ret );
98
102
return ret ;
103
+ }
99
104
}
100
105
101
106
u32 level = IRQ_Disable ();
102
107
{
103
- __stm_eventhook .event_code = 0 ;
104
- ret = IOS_IoctlAsync (__stm_eventhook .fd , IOCTL_STM_EVENTHOOK , NULL , 0 , & __stm_eventhook .event_code , 0x4 , __STMEventHandler , & __stm_eventhook );
108
+ ret = IOS_IoctlAsync (__stm_eventhook .fd , IOCTL_STM_EVENTHOOK , NULL , 0 , & __stm_eventhook .event_code , sizeof (u32 ), __STMEventCallback , & __stm_eventhook );
105
109
if (ret == 0 )
106
110
__stm_eventhook .state = 1 ;
107
111
}
@@ -112,19 +116,30 @@ s32 __STM_SetEventHook(void)
112
116
113
117
s32 __STM_ReleaseEventHook (void )
114
118
{
115
- s32 ret , fd ;
119
+ s32 ret = STM_ENOHANDLER , fd ;
116
120
117
- ret = fd = IOS_Open ("/dev/stm/immediate" , 0 );
118
- if (ret >= 0 ) {
119
- __stm_eventhook .state = 2 ;
120
- ret = IOS_Ioctl (fd , IOCTL_STM_RELEASE_EH , NULL , 0 , NULL , 0 );
121
- IOS_Close (fd );
121
+ STM_printf ("Release\n" );
122
+
123
+ if (__stm_eventhook .state == 1 ) {
124
+ ret = fd = IOS_Open ("/dev/stm/immediate" , 0 );
125
+ if (ret >= 0 ) {
126
+ __stm_eventhook .state = 2 ;
127
+ ret = IOS_Ioctl (fd , IOCTL_STM_RELEASE_EH , NULL , 0 , NULL , 0 );
128
+ IOS_Close (fd );
129
+ } else {
130
+ STM_printf ("Open /dev/stm/immediate failed {%i}\n" , ret );
131
+ }
132
+ }
133
+ else if (__stm_eventhook .fd >= 0 ) {
134
+ ret = IOS_Close (__stm_eventhook .fd );
135
+ __stm_eventhook .fd = -1 ;
122
136
}
123
137
138
+
124
139
return ret ;
125
140
}
126
141
127
- static s32 __STMEventHandler (s32 result , void * usrdata )
142
+ static s32 __STMEventCallback (s32 result , void * usrdata )
128
143
{
129
144
__stm_eventhook .state = 0 ;
130
145
@@ -159,6 +174,13 @@ stmcallback STM_RegisterEventHandler(stmcallback new)
159
174
return old ;
160
175
}
161
176
177
+ __attribute__((noreturn ))
178
+ static void WaitForImpendingDoom (void ) {
179
+ IRQ_Disable ();
180
+ ICFlashInvalidate ();
181
+ ppchalt ();
182
+ }
183
+
162
184
s32 STM_ShutdownToStandby (void )
163
185
{
164
186
s32 ret , fd ;
@@ -167,14 +189,17 @@ s32 STM_ShutdownToStandby(void)
167
189
_viReg [1 ] = 0 ;
168
190
ret = fd = IOS_Open ("/dev/stm/immediate" , 0 );
169
191
if (ret >= 0 ) {
170
- ret = IOS_Ioctl (fd , IOCTL_STM_SHUTDOWN , & config , 0x4 , NULL , 0 );
192
+ ret = IOS_Ioctl (fd , IOCTL_STM_SHUTDOWN , & config , sizeof ( u32 ) , NULL , 0 );
171
193
if (ret == 0 ) {
172
- // *disable irq and spin here*
173
- // IOS_Close will lock us anyways, since STM is most definitely not going to pick up the 2nd message before the entire system turns off. Lol.
194
+ WaitForImpendingDoom ();
174
195
} else {
175
196
STM_printf ("STM Shutdown failed (%i). Why? It does not even check input size...\n" , ret );
176
197
}
198
+
199
+ /* Should we hang regardless? The Wii menu does, pulling OSHalt if STM was not ready by the time <function> was called */
177
200
IOS_Close (fd );
201
+ } else {
202
+ STM_printf ("Open /dev/stm/immediate failed {%i}\n" , ret );
178
203
}
179
204
180
205
return ret ;
@@ -191,12 +216,36 @@ s32 STM_ShutdownToIdle(void)
191
216
_viReg [1 ] = 0 ;
192
217
ret = fd = IOS_Open ("/dev/stm/immediate" , 0 );
193
218
if (ret >= 0 ) {
194
- ret = IOS_Ioctl (fd , IOCTL_STM_IDLEMODE , & config , 0x4 , NULL , 0 );
219
+ ret = IOS_Ioctl (fd , IOCTL_STM_IDLEMODE , & config , sizeof ( u32 ) , NULL , 0 );
195
220
if (ret == 0 ) {
196
- // *disable irq and spin here*
221
+ WaitForImpendingDoom ();
197
222
} else {
198
223
STM_printf ("STM IdleMode failed (%i).\n" , ret );
199
224
}
225
+ IOS_Close (fd );
226
+ } else {
227
+ STM_printf ("Open /dev/stm/immediate failed {%i}\n" , ret );
228
+ }
229
+
230
+ return ret ;
231
+ }
232
+
233
+ s32 STM_RebootSystem (void )
234
+ {
235
+ s32 ret , fd ;
236
+
237
+ _viReg [1 ] = 0 ;
238
+ ret = fd = IOS_Open ("/dev/stm/immediate" , 0 );
239
+ if (ret >= 0 ) {
240
+ ret = IOS_Ioctl (fd , IOCTL_STM_HOTRESET , NULL , 0 , NULL , 0 );
241
+ if (ret == 0 ) {
242
+ WaitForImpendingDoom ();
243
+ } else {
244
+ STM_printf ("STM HotReset failed. (%i)\n" , ret );
245
+ }
246
+ IOS_Close (fd );
247
+ } else {
248
+ STM_printf ("Open /dev/stm/immediate failed {%i}\n" , ret );
200
249
}
201
250
202
251
return ret ;
@@ -208,20 +257,23 @@ s32 STM_SetLedMode(u32 mode)
208
257
209
258
ret = fd = IOS_Open ("/dev/stm/immediate" , 0 );
210
259
if (ret >= 0 ) {
211
- ret = IOS_Ioctl (fd , IOCTL_STM_LEDMODE , & mode , 0x4 , NULL , 0 );
260
+ ret = IOS_Ioctl (fd , IOCTL_STM_LEDMODE , & mode , sizeof ( u32 ) , NULL , 0 );
212
261
if (ret < 0 ) {
213
262
STM_printf ("STM LEDMode failed (%i).\n" , ret );
214
263
} else if (mode == 0 ) {
215
264
STM_printf ("Forced led off.\n" );
216
265
}
217
266
218
267
IOS_Close (fd );
268
+ } else {
269
+ STM_printf ("Open /dev/stm/immediate failed {%i}\n" , ret );
219
270
}
220
271
221
272
return ret ;
222
273
}
223
274
224
- struct STM_LEDFlashConfig {
275
+ struct STM_LEDFlashConfig
276
+ {
225
277
u32 : 8 ;
226
278
u32 flags : 8 ;
227
279
u32 priority : 8 ;
@@ -231,14 +283,18 @@ struct STM_LEDFlashConfig {
231
283
};
232
284
_Static_assert (offsetof(struct STM_LEDFlashConfig , patterns ) == 0x4 , "?" );
233
285
234
- s32 STM_StartLEDFlashLoop (u8 id , u8 priority , u8 flags , const u16 * patterns , u32 num_patterns ) {
286
+ s32 STM_StartLEDFlashLoop (u8 id , u8 priority , u8 flags , const u16 * patterns , u32 num_patterns )
287
+ {
235
288
s32 ret , fd ;
236
289
237
290
ret = fd = IOS_Open ("/dev/stm/immediate" , 0 );
238
291
if (ret >= 0 ) {
239
- static struct STM_LEDFlashConfig config ;
292
+ struct STM_LEDFlashConfig config ;
240
293
241
294
if ((flags & STM_LEDFLASH_USER ) && patterns != NULL ) {
295
+ if (num_patterns >= STM_MAX_LED_PATTERNS )
296
+ num_patterns = STM_MAX_LED_PATTERNS ;
297
+
242
298
memcpy (config .patterns , patterns , sizeof (u16 [num_patterns ]));
243
299
} else {
244
300
num_patterns = 0 ;
@@ -255,25 +311,8 @@ s32 STM_StartLEDFlashLoop(u8 id, u8 priority, u8 flags, const u16* patterns, u32
255
311
}
256
312
257
313
IOS_Close (fd );
258
- }
259
-
260
- return ret ;
261
- }
262
-
263
- s32 STM_RebootSystem (void )
264
- {
265
- s32 ret , fd ;
266
-
267
- _viReg [1 ] = 0 ;
268
- ret = fd = IOS_Open ("/dev/stm/immediate" , 0 );
269
- if (ret >= 0 ) {
270
- ret = IOS_Ioctl (fd , IOCTL_STM_HOTRESET , NULL , 0 , NULL , 0 );
271
- if (ret == 0 ) {
272
- // *disable irq and spin here*
273
- } else {
274
- STM_printf ("STM HotReset failed. (%i)\n" , ret );
275
- }
276
- IOS_Close (fd );
314
+ } else {
315
+ STM_printf ("Open /dev/stm/immediate failed {%i}\n" , ret );
277
316
}
278
317
279
318
return ret ;
0 commit comments