@@ -34,13 +34,15 @@ distribution.
3434#include "ipc.h"
3535#include "system.h"
3636#include "irq.h"
37+ #include "processor.h"
38+ #include "cache.h"
3739#include "stm.h"
3840
3941#define DEBUG_STM
4042
4143#ifdef DEBUG_STM
4244#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__)
4446#else
4547#define STM_printf (fmt , ...) while (0) {};
4648#endif
@@ -69,7 +71,8 @@ struct eventhook {
6971
7072static struct eventhook __stm_eventhook ;
7173
72- static s32 __STMEventHandler (s32 result ,void * usrdata );
74+ static s32 __STMEventCallback (s32 result ,void * usrdata );
75+ s32 __STM_SetEventHook (void );
7376s32 __STM_ReleaseEventHook (void );
7477
7578static vu16 * const _viReg = (u16 * )0xCC002000 ;
@@ -94,14 +97,15 @@ s32 __STM_SetEventHook(void)
9497
9598 if (__stm_eventhook .fd < 0 ) {
9699 __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 );
98102 return ret ;
103+ }
99104 }
100105
101106 u32 level = IRQ_Disable ();
102107 {
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 );
105109 if (ret == 0 )
106110 __stm_eventhook .state = 1 ;
107111 }
@@ -112,19 +116,30 @@ s32 __STM_SetEventHook(void)
112116
113117s32 __STM_ReleaseEventHook (void )
114118{
115- s32 ret , fd ;
119+ s32 ret = STM_ENOHANDLER , fd ;
116120
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 ;
122136 }
123137
138+
124139 return ret ;
125140}
126141
127- static s32 __STMEventHandler (s32 result , void * usrdata )
142+ static s32 __STMEventCallback (s32 result , void * usrdata )
128143{
129144 __stm_eventhook .state = 0 ;
130145
@@ -159,6 +174,13 @@ stmcallback STM_RegisterEventHandler(stmcallback new)
159174 return old ;
160175}
161176
177+ __attribute__((noreturn ))
178+ static void WaitForImpendingDoom (void ) {
179+ IRQ_Disable ();
180+ ICFlashInvalidate ();
181+ ppchalt ();
182+ }
183+
162184s32 STM_ShutdownToStandby (void )
163185{
164186 s32 ret , fd ;
@@ -167,14 +189,17 @@ s32 STM_ShutdownToStandby(void)
167189 _viReg [1 ] = 0 ;
168190 ret = fd = IOS_Open ("/dev/stm/immediate" , 0 );
169191 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 );
171193 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 ();
174195 } else {
175196 STM_printf ("STM Shutdown failed (%i). Why? It does not even check input size...\n" , ret );
176197 }
198+
199+ /* Should we hang regardless? The Wii menu does, pulling OSHalt if STM was not ready by the time <function> was called */
177200 IOS_Close (fd );
201+ } else {
202+ STM_printf ("Open /dev/stm/immediate failed {%i}\n" , ret );
178203 }
179204
180205 return ret ;
@@ -191,12 +216,36 @@ s32 STM_ShutdownToIdle(void)
191216 _viReg [1 ] = 0 ;
192217 ret = fd = IOS_Open ("/dev/stm/immediate" , 0 );
193218 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 );
195220 if (ret == 0 ) {
196- // *disable irq and spin here*
221+ WaitForImpendingDoom ();
197222 } else {
198223 STM_printf ("STM IdleMode failed (%i).\n" , ret );
199224 }
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 );
200249 }
201250
202251 return ret ;
@@ -208,20 +257,23 @@ s32 STM_SetLedMode(u32 mode)
208257
209258 ret = fd = IOS_Open ("/dev/stm/immediate" , 0 );
210259 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 );
212261 if (ret < 0 ) {
213262 STM_printf ("STM LEDMode failed (%i).\n" , ret );
214263 } else if (mode == 0 ) {
215264 STM_printf ("Forced led off.\n" );
216265 }
217266
218267 IOS_Close (fd );
268+ } else {
269+ STM_printf ("Open /dev/stm/immediate failed {%i}\n" , ret );
219270 }
220271
221272 return ret ;
222273}
223274
224- struct STM_LEDFlashConfig {
275+ struct STM_LEDFlashConfig
276+ {
225277 u32 : 8 ;
226278 u32 flags : 8 ;
227279 u32 priority : 8 ;
@@ -231,14 +283,18 @@ struct STM_LEDFlashConfig {
231283};
232284_Static_assert (offsetof(struct STM_LEDFlashConfig , patterns ) == 0x4 , "?" );
233285
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+ {
235288 s32 ret , fd ;
236289
237290 ret = fd = IOS_Open ("/dev/stm/immediate" , 0 );
238291 if (ret >= 0 ) {
239- static struct STM_LEDFlashConfig config ;
292+ struct STM_LEDFlashConfig config ;
240293
241294 if ((flags & STM_LEDFLASH_USER ) && patterns != NULL ) {
295+ if (num_patterns >= STM_MAX_LED_PATTERNS )
296+ num_patterns = STM_MAX_LED_PATTERNS ;
297+
242298 memcpy (config .patterns , patterns , sizeof (u16 [num_patterns ]));
243299 } else {
244300 num_patterns = 0 ;
@@ -255,25 +311,8 @@ s32 STM_StartLEDFlashLoop(u8 id, u8 priority, u8 flags, const u16* patterns, u32
255311 }
256312
257313 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 );
277316 }
278317
279318 return ret ;
0 commit comments