Skip to content

Commit 1a4b445

Browse files
committed
lighter rework
1 parent f5ea85d commit 1a4b445

File tree

2 files changed

+132
-49
lines changed

2 files changed

+132
-49
lines changed

gc/ogc/stm.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,32 @@ distribution.
4747
extern "C" {
4848
#endif /* __cplusplus */
4949

50+
enum {
51+
STM_LEDMODE_OFF,
52+
STM_LEDMODE_DIM,
53+
STM_LEDMODE_BRIGHT,
54+
};
55+
56+
enum {
57+
STM_MAX_LED_PATTERNS = 128,
58+
59+
STM_LEDFLASH_USER = (1 << 0),
60+
STM_LEDFLASH_NOEXEC = (1 << 1),
61+
};
62+
5063
typedef void (*stmcallback)(u32 event);
5164

5265
s32 __STM_Init(void);
5366
s32 __STM_Close(void);
67+
stmcallback STM_RegisterEventHandler(stmcallback newhandler);
68+
5469
s32 STM_ShutdownToStandby(void);
5570
s32 STM_ShutdownToIdle(void);
56-
s32 STM_SetLedMode(u32 mode);
5771
s32 STM_RebootSystem(void);
58-
stmcallback STM_RegisterEventHandler(stmcallback newhandler);
72+
73+
s32 STM_SetLedMode(u32 mode);
74+
s32 STM_StartLedFlashLoop(u8 pattern_id, u8 priority, u8 flags, const u16* patterns, u32 num_patterns);
75+
s32 STM_VIDimming(bool enable, u32 luma, u32 chroma);
5976

6077
#ifdef __cplusplus
6178
}

libogc/stm.c

Lines changed: 113 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,21 @@ distribution.
3030

3131
#if defined(HW_RVL)
3232

33-
#include <stdio.h>
33+
#include <string.h>
3434
#include "ipc.h"
3535
#include "system.h"
3636
#include "asm.h"
3737
#include "processor.h"
38+
#include "cache.h"
3839
#include "stm.h"
3940

4041
//#define DEBUG_STM
42+
#ifdef DEBUG_STM
43+
#include <stdio.h>
44+
#define STM_printf(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS)
45+
#else
46+
#define STM_printf(...) while (0) {}
47+
#endif
4148

4249
#define IOCTL_STM_EVENTHOOK 0x1000
4350
#define IOCTL_STM_GET_IDLEMODE 0x3001
@@ -63,8 +70,6 @@ static u32 __stm_ehclear= 0;
6370

6471
static u32 __stm_ehbufin[0x08] ATTRIBUTE_ALIGN(32) = {0,0,0,0,0,0,0,0};
6572
static u32 __stm_ehbufout[0x08] ATTRIBUTE_ALIGN(32) = {0,0,0,0,0,0,0,0};
66-
static u32 __stm_immbufin[0x08] ATTRIBUTE_ALIGN(32) = {0,0,0,0,0,0,0,0};
67-
static u32 __stm_immbufout[0x08] ATTRIBUTE_ALIGN(32) = {0,0,0,0,0,0,0,0};
6873

6974
static char __stm_eh_fs[] ATTRIBUTE_ALIGN(32) = "/dev/stm/eventhook";
7075
static char __stm_imm_fs[] ATTRIBUTE_ALIGN(32) = "/dev/stm/immediate";
@@ -80,9 +85,8 @@ static vu16* const _viReg = (u16*)0xCC002000;
8085
s32 __STM_Init(void)
8186
{
8287
if(__stm_initialized==1) return 1;
83-
#ifdef DEBUG_STM
84-
printf("STM Init\n");
85-
#endif
88+
89+
STM_printf("STM init");
8690

8791
__stm_vdinuse = 0;
8892
__stm_imm_fd = IOS_Open(__stm_imm_fs,0);
@@ -91,9 +95,7 @@ s32 __STM_Init(void)
9195
__stm_eh_fd = IOS_Open(__stm_eh_fs,0);
9296
if(__stm_eh_fd<0) return 0;
9397

94-
#ifdef DEBUG_STM
95-
printf("STM FDs: %d, %d\n",__stm_imm_fd, __stm_eh_fd);
96-
#endif
98+
STM_printf("STM FDs: %d, %d\n",__stm_imm_fd, __stm_eh_fd);
9799

98100
__stm_initialized = 1;
99101
__STM_SetEventHook();
@@ -120,6 +122,13 @@ s32 __STM_Close(void)
120122
return ret;
121123
}
122124

125+
s32 __STM_SendCommand(s32 ioctl, const void *inbuf, u32 inlen, void *outbuf, u32 outlen) {
126+
if (__stm_initialized == 0)
127+
return STM_ENOTINIT;
128+
129+
return IOS_Ioctl(__stm_imm_fd, ioctl, (void *)inbuf, inlen, outbuf, outlen);
130+
}
131+
123132
s32 __STM_SetEventHook(void)
124133
{
125134
s32 ret;
@@ -147,7 +156,7 @@ s32 __STM_ReleaseEventHook(void)
147156

148157
__stm_ehclear = 1;
149158

150-
ret = IOS_Ioctl(__stm_imm_fd,IOCTL_STM_RELEASE_EH,__stm_immbufin,0x20,__stm_immbufout,0x20);
159+
ret = __STM_SendCommand(IOCTL_STM_RELEASE_EH,NULL,0,NULL,0);
151160
if(ret>=0) __stm_ehregistered = 0;
152161

153162
return ret;
@@ -161,10 +170,8 @@ static s32 __STMEventHandler(s32 result,void *usrdata)
161170
return result;
162171
}
163172

164-
#ifdef DEBUG_STM
165-
printf("STM Event: %08x\n",__stm_ehbufout[0]);
166-
#endif
167-
173+
STM_printf("STM Event: %08x\n",__stm_ehbufout[0]);
174+
168175
if(__stm_ehclear) { //release
169176
return 0;
170177
}
@@ -186,71 +193,73 @@ stmcallback STM_RegisterEventHandler(stmcallback newhandler)
186193
return old;
187194
}
188195

196+
__attribute__((noreturn))
197+
static void WaitForImpendingDoom(void) {
198+
u32 level;
199+
_CPU_ISR_Disable(level);
200+
ICFlashInvalidate();
201+
ppchalt();
202+
}
203+
189204
s32 STM_ShutdownToStandby(void)
190205
{
191206
int res;
192207

193208
_viReg[1] = 0;
194209
if(__stm_initialized==0) {
195-
#ifdef DEBUG_STM
196-
printf("STM notinited\n");
197-
#endif
210+
STM_printf("STM notinited\n");
198211
return STM_ENOTINIT;
199212
}
200-
__stm_immbufin[0] = 0;
201-
res= IOS_Ioctl(__stm_imm_fd,IOCTL_STM_SHUTDOWN,__stm_immbufin,0x20,__stm_immbufout,0x20);
213+
u32 config = 0;
214+
res = __STM_SendCommand(IOCTL_STM_SHUTDOWN, &config, sizeof(u32), NULL, 0);
202215
if(res<0) {
203-
#ifdef DEBUG_STM
204-
printf("STM STBY failed: %d\n",res);
205-
#endif
216+
STM_printf("STM STBY failed: %d\n",res);
206217
}
218+
219+
WaitForImpendingDoom();
207220
return res;
208221
}
209222

223+
// idea: rename this to STM_ShutdownToIdleEx and give it some bitflags
210224
s32 STM_ShutdownToIdle(void)
211225
{
212226
int res;
227+
u32 config;
213228

214229
_viReg[1] = 0;
215230
if(__stm_initialized==0) {
216-
#ifdef DEBUG_STM
217-
printf("STM notinited\n");
218-
#endif
231+
STM_printf("STM notinited\n");
219232
return STM_ENOTINIT;
220233
}
221234
switch(SYS_GetHollywoodRevision()) {
222235
case 0:
223236
case 1:
224237
case 2:
225-
__stm_immbufin[0] = 0xFCA08280;
238+
config = 0xFCA08280;
226239
break;
227240
default:
228-
__stm_immbufin[0] = 0xFCE082C0;
241+
config = 0xFCE082C0;
242+
break;
229243
}
230-
res= IOS_Ioctl(__stm_imm_fd,IOCTL_STM_IDLE,__stm_immbufin,0x20,__stm_immbufout,0x20);
244+
res= __STM_SendCommand(IOCTL_STM_IDLE, &config, sizeof(u32), NULL, 0);
231245
if(res<0) {
232-
#ifdef DEBUG_STM
233-
printf("STM IDLE failed: %d\n",res);
234-
#endif
246+
STM_printf("STM IDLE failed: %d\n",res);
235247
}
248+
249+
WaitForImpendingDoom();
236250
return res;
237251
}
238252

239253
s32 STM_SetLedMode(u32 mode)
240254
{
241255
int res;
242256
if(__stm_initialized==0) {
243-
#ifdef DEBUG_STM
244-
printf("STM notinited\n");
245-
#endif
257+
STM_printf("STM notinited\n");
246258
return STM_ENOTINIT;
247259
}
248-
__stm_immbufin[0] = mode;
249-
res= IOS_Ioctl(__stm_imm_fd,IOCTL_STM_LEDMODE,__stm_immbufin,0x20,__stm_immbufout,0x20);
260+
res= __STM_SendCommand(IOCTL_STM_LEDMODE, &mode, sizeof(u32), NULL, 0);
250261
if(res<0) {
251-
#ifdef DEBUG_STM
252-
printf("STM LEDMODE failed: %d\n",res);
253-
#endif
262+
STM_printf("STM LEDMODE failed: %d\n",res);
254263
}
255264
return res;
256265
}
@@ -261,21 +270,78 @@ s32 STM_RebootSystem(void)
261270

262271
_viReg[1] = 0;
263272
if(__stm_initialized==0) {
264-
#ifdef DEBUG_STM
265-
printf("STM notinited\n");
266-
#endif
273+
STM_printf("STM notinited\n");
267274
return STM_ENOTINIT;
268275
}
269-
__stm_immbufin[0] = 0;
270-
res= IOS_Ioctl(__stm_imm_fd,IOCTL_STM_HOTRESET,__stm_immbufin,0x20,__stm_immbufout,0x20);
276+
res= __STM_SendCommand(IOCTL_STM_HOTRESET, NULL, 0, NULL, 0);
271277
if(res<0) {
272-
#ifdef DEBUG_STM
273-
printf("STM HRST failed: %d\n",res);
274-
#endif
278+
STM_printf("STM HRST failed: %d\n",res);
275279
}
280+
281+
WaitForImpendingDoom();
276282
return res;
277283
}
278284

285+
struct STM_LedFlashConfig
286+
{
287+
u32 : 8;
288+
u32 flags : 8;
289+
u32 priority : 8;
290+
u32 pattern_id : 8;
291+
292+
u16 patterns[STM_MAX_LED_PATTERNS];
293+
};
294+
295+
// capitalization of LED is debatable. libogc currently has STM_SetLedMode, meanwhile this function is internally called ISTM_StartLEDFlashLoop
296+
s32 STM_StartLedFlashLoop(u8 pattern_id, u8 priority, u8 flags, const u16* patterns, u32 num_patterns)
297+
{
298+
s32 ret;
299+
struct STM_LedFlashConfig config = {};
300+
if ((flags & STM_LEDFLASH_USER) && patterns != NULL) {
301+
if (num_patterns > STM_MAX_LED_PATTERNS)
302+
num_patterns = STM_MAX_LED_PATTERNS;
303+
304+
memcpy(config.patterns, patterns, sizeof(u16[num_patterns]));
305+
} else {
306+
num_patterns = 0;
307+
flags &= ~STM_LEDFLASH_USER;
308+
}
279309

310+
config.pattern_id = pattern_id;
311+
config.priority = priority;
312+
config.flags = flags;
313+
314+
ret = __STM_SendCommand(IOCTL_STM_LEDFLASH, &config, offsetof(struct STM_LedFlashConfig, patterns[num_patterns]), NULL, 0);
315+
if (ret < 0) {
316+
STM_printf("STM LEDFLASH failed: %d\n", ret);
317+
}
318+
319+
return ret;
320+
}
321+
322+
// This is where __stm_vdinuse would come into play
323+
// https://github.com/koopthekoopa/wii-ipl/blob/main/libs/RVL_SDK/src/os/OSStateTM.c#L176
324+
// I guess it's to prevent the function from being called 0ms after it was called the first time. Not sure why.
325+
s32 STM_VIDimming(bool enable, u32 luma, u32 chroma)
326+
{
327+
s32 ret;
328+
u32 inbuf[8];
329+
u32 outbuf[8];
330+
331+
inbuf[0] = (enable << 7) | (luma & 0x7) << 3 | (chroma & 0x7);
332+
inbuf[1] = 0;
333+
inbuf[2] = 0;
334+
335+
inbuf[4] = 0; // keep nothing
336+
inbuf[5] = ~0; // keep everything
337+
inbuf[6] = ~0; // <official software> uses 0xFFFF0000 here, but, what is the register even for....
338+
339+
ret = __STM_SendCommand(IOCTL_STM_VIDIMMING, inbuf, sizeof inbuf, outbuf, sizeof outbuf);
340+
if (ret < 0) {
341+
STM_printf("STM VIDIM failed: %d\n", ret);
342+
}
343+
344+
return ret;
345+
}
280346

281347
#endif /* defined(HW_RVL) */

0 commit comments

Comments
 (0)