tp/libs/dolphin/os/OSReset.c

221 lines
5.5 KiB
C

#include "dolphin/os/OSReset.h"
#include "dolphin/os.h"
vu16 __VIRegs[59] : 0xCC002000;
OSThreadQueue __OSActiveThreadQueue : (OS_BASE_CACHED | 0x00DC);
extern OSExecParams __OSRebootParams;
/* 80451690-80451698 000B90 0008+00 2/2 0/0 0/0 .sbss ResetFunctionQueue */
static OSResetQueue ResetFunctionQueue;
/* 8033F660-8033F6E4 339FA0 0084+00 0/0 5/5 0/0 .text OSRegisterResetFunction */
void OSRegisterResetFunction(OSResetFunctionInfo* func) {
OSResetFunctionInfo* tmp;
OSResetFunctionInfo* iter;
for (iter = ResetFunctionQueue.first; iter && iter->priority <= func->priority;
iter = iter->next)
;
if (iter == NULL) {
tmp = ResetFunctionQueue.last;
if (tmp == NULL) {
ResetFunctionQueue.first = func;
} else {
tmp->next = func;
}
func->prev = tmp;
func->next = NULL;
ResetFunctionQueue.last = func;
return;
}
func->next = iter;
tmp = iter->prev;
iter->prev = func;
func->prev = tmp;
if (tmp == NULL) {
ResetFunctionQueue.first = func;
return;
}
tmp->next = func;
}
/* 8033F6E4-8033F78C 33A024 00A8+00 1/1 0/0 0/0 .text __OSCallResetFunctions */
BOOL __OSCallResetFunctions(u32 arg0) {
OSResetFunctionInfo* iter;
s32 retCode = 0;
u32 priority = 0;
s32 temp;
for (iter = ResetFunctionQueue.first; iter != NULL;) {
if (retCode != 0 && priority != iter->priority)
break;
temp = !iter->func(arg0);
priority = iter->priority;
iter = iter->next;
retCode |= temp;
}
retCode |= !__OSSyncSram();
if (retCode) {
return 0;
}
return 1;
}
/* 8033F78C-8033F7FC 33A0CC 0070+00 2/2 0/0 0/0 .text Reset */
static asm void Reset(register s32 param_0) {
// clang-format off
nofralloc
b lbl_8033F7AC
lbl_8033F790:
mfspr r8, 0x3f0
ori r8, r8, 8
mtspr 0x3f0, r8
isync
sync
nop
b lbl_8033F7B0
lbl_8033F7AC:
b lbl_8033F7CC
lbl_8033F7B0:
mftb r5, 0x10c
lbl_8033F7B4:
mftb r6, 0x10c
subf r7, r5, r6
cmplwi r7, 0x1124
blt lbl_8033F7B4
nop
b lbl_8033F7D0
lbl_8033F7CC:
b lbl_8033F7EC
lbl_8033F7D0:
lis r8, 0xCC00
ori r8, r8, 0x3000
li r4, 3
stw r4, 0x24(r8)
stw param_0, 0x24(r8)
nop
b lbl_8033F7F0
lbl_8033F7EC:
b lbl_8033F7F8
lbl_8033F7F0:
nop
b lbl_8033F7F0
lbl_8033F7F8:
b lbl_8033F790
// clang-format on
}
/* 8033F7FC-8033F864 33A13C 0068+00 1/1 0/0 0/0 .text KillThreads */
#pragma dont_inline on
static void KillThreads(void) {
OSThread* thread;
OSThread* next;
for (thread = __OSActiveThreadQueue.head; thread; thread = next) {
next = thread->active_threads_link.next;
switch (thread->state) {
case 1:
case 4:
OSCancelThread(thread);
continue;
default:
continue;
}
}
}
#pragma dont_inline reset
/* 8033F864-8033F8AC 33A1A4 0048+00 0/0 3/3 0/0 .text __OSDoHotReset */
void __OSDoHotReset(s32 arg0) {
OSDisableInterrupts();
__VIRegs[1] = 0;
ICFlashInvalidate();
Reset(arg0 * 8);
}
/* ############################################################################################## */
/* 80451698-804516A0 000B98 0004+04 1/1 0/0 0/0 .sbss bootThisDol */
static u32 bootThisDol;
/* 8033F8AC-8033FAAC 33A1EC 0200+00 0/0 5/5 0/0 .text OSResetSystem */
void OSResetSystem(int reset, u32 resetCode, BOOL forceMenu) {
BOOL rc;
BOOL disableRecalibration;
u32 unk;
OSDisableScheduler();
if (reset == OS_RESET_HOTRESET && forceMenu) {
OSSram* sram;
sram = __OSLockSram();
sram->flags |= 0x40;
__OSUnlockSram(TRUE);
resetCode = 0;
}
if (reset == OS_RESET_SHUTDOWN ||
(reset == OS_RESET_RESTART && (bootThisDol || resetCode + 0x3fff0000 == 0)))
{
__OSStopAudioSystem();
disableRecalibration = __PADDisableRecalibration(TRUE);
while (!__OSCallResetFunctions(FALSE))
;
while (!__OSSyncSram())
;
OSDisableInterrupts();
__OSCallResetFunctions(TRUE);
LCDisable();
__PADDisableRecalibration(disableRecalibration);
KillThreads();
} else {
__OSStopAudioSystem();
while (!__OSCallResetFunctions(FALSE))
;
while (!__OSSyncSram())
;
OSDisableInterrupts();
__OSCallResetFunctions(TRUE);
LCDisable();
KillThreads();
}
if (reset == OS_RESET_HOTRESET) {
__OSDoHotReset(resetCode);
} else if (reset == OS_RESET_RESTART) {
if (forceMenu == TRUE) {
OSReport(
"OSResetSystem(): You can't specify TRUE to forceMenu if you restart. Ignored\n");
}
OSEnableScheduler();
__OSReboot(resetCode, bootThisDol);
}
memset(OSPhysicalToCached(0x40), 0, 0xcc - 0x40);
memset(OSPhysicalToCached(0xd4), 0, 0xe8 - 0xd4);
memset(OSPhysicalToCached(0xf4), 0, 0xf8 - 0xf4);
memset(OSPhysicalToCached(0x3000), 0, 0xc0);
memset(OSPhysicalToCached(0x30c8), 0, 0xd4 - 0xc8);
memset(OSPhysicalToCached(0x30e2), 0, 1);
}
/* 8033FAAC-8033FAE4 33A3EC 0038+00 0/0 3/3 0/0 .text OSGetResetCode */
u32 OSGetResetCode(void) {
if (__OSRebootParams.valid)
return 0x80000000 | __OSRebootParams.restartCode;
return ((__PIRegs[9] & ~7) >> 3);
}