mirror of https://github.com/PrimeDecomp/prime.git
Match and link OS.c (steal code from pikmin2)
Former-commit-id: 008b7f848d
This commit is contained in:
parent
35b9861a1e
commit
ccc0eb32d2
|
@ -50,7 +50,8 @@
|
||||||
"dsp_regs.h": "c",
|
"dsp_regs.h": "c",
|
||||||
"dsp.h": "c",
|
"dsp.h": "c",
|
||||||
"ar.h": "c",
|
"ar.h": "c",
|
||||||
"osrtcpriv.h": "c"
|
"osrtcpriv.h": "c",
|
||||||
|
"osbootinfo.h": "c"
|
||||||
},
|
},
|
||||||
"files.autoSave": "onFocusChange",
|
"files.autoSave": "onFocusChange",
|
||||||
"files.insertFinalNewline": true,
|
"files.insertFinalNewline": true,
|
||||||
|
|
|
@ -17,8 +17,8 @@ lbl_805A97BC:
|
||||||
.global lbl_805A97C0
|
.global lbl_805A97C0
|
||||||
lbl_805A97C0:
|
lbl_805A97C0:
|
||||||
.skip 0x4
|
.skip 0x4
|
||||||
.global lbl_805A97C4
|
.global __DVDLongFileNameFlag
|
||||||
lbl_805A97C4:
|
__DVDLongFileNameFlag:
|
||||||
.skip 0x4
|
.skip 0x4
|
||||||
.global __DVDThreadQueue
|
.global __DVDThreadQueue
|
||||||
__DVDThreadQueue:
|
__DVDThreadQueue:
|
||||||
|
@ -139,7 +139,7 @@ lbl_803713D4:
|
||||||
/* 803713DC 0036E33C 7F 43 D3 78 */ mr r3, r26
|
/* 803713DC 0036E33C 7F 43 D3 78 */ mr r3, r26
|
||||||
/* 803713E0 0036E340 48 00 02 1C */ b lbl_803715FC
|
/* 803713E0 0036E340 48 00 02 1C */ b lbl_803715FC
|
||||||
lbl_803713E4:
|
lbl_803713E4:
|
||||||
/* 803713E4 0036E344 80 0D AC 04 */ lwz r0, lbl_805A97C4@sda21(r13)
|
/* 803713E4 0036E344 80 0D AC 04 */ lwz r0, __DVDLongFileNameFlag@sda21(r13)
|
||||||
/* 803713E8 0036E348 28 00 00 00 */ cmplwi r0, 0
|
/* 803713E8 0036E348 28 00 00 00 */ cmplwi r0, 0
|
||||||
/* 803713EC 0036E34C 40 82 00 AC */ bne lbl_80371498
|
/* 803713EC 0036E34C 40 82 00 AC */ bne lbl_80371498
|
||||||
/* 803713F0 0036E350 3B 97 00 00 */ addi r28, r23, 0
|
/* 803713F0 0036E350 3B 97 00 00 */ addi r28, r23, 0
|
||||||
|
@ -731,4 +731,3 @@ lbl_80371B90:
|
||||||
/* 80371B94 0036EAF4 38 21 00 08 */ addi r1, r1, 8
|
/* 80371B94 0036EAF4 38 21 00 08 */ addi r1, r1, 8
|
||||||
/* 80371B98 0036EAF8 7C 08 03 A6 */ mtlr r0
|
/* 80371B98 0036EAF8 7C 08 03 A6 */ mtlr r0
|
||||||
/* 80371B9C 0036EAFC 4E 80 00 20 */ blr
|
/* 80371B9C 0036EAFC 4E 80 00 20 */ blr
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
.balign 8
|
.balign 8
|
||||||
.global DriveInfo
|
.global DriveInfo
|
||||||
DriveInfo:
|
DriveInfo:
|
||||||
.skip 0x50
|
.skip 0x20
|
||||||
|
DriveBlock:
|
||||||
|
.skip 0x30
|
||||||
|
|
||||||
.section .sbss
|
.section .sbss
|
||||||
.balign 8
|
.balign 8
|
||||||
|
@ -256,7 +258,7 @@ OSInit:
|
||||||
/* 8037D900 0037A860 3C 80 80 00 */ lis r4, 0x800000F4@ha
|
/* 8037D900 0037A860 3C 80 80 00 */ lis r4, 0x800000F4@ha
|
||||||
/* 8037D904 0037A864 90 0D AC C4 */ stw r0, BI2DebugFlag@sda21(r13)
|
/* 8037D904 0037A864 90 0D AC C4 */ stw r0, BI2DebugFlag@sda21(r13)
|
||||||
/* 8037D908 0037A868 90 8D AC C0 */ stw r4, BootInfo@sda21(r13)
|
/* 8037D908 0037A868 90 8D AC C0 */ stw r4, BootInfo@sda21(r13)
|
||||||
/* 8037D90C 0037A86C 90 0D AC 04 */ stw r0, lbl_805A97C4@sda21(r13)
|
/* 8037D90C 0037A86C 90 0D AC 04 */ stw r0, __DVDLongFileNameFlag@sda21(r13)
|
||||||
/* 8037D910 0037A870 80 64 00 F4 */ lwz r3, 0x800000F4@l(r4)
|
/* 8037D910 0037A870 80 64 00 F4 */ lwz r3, 0x800000F4@l(r4)
|
||||||
/* 8037D914 0037A874 28 03 00 00 */ cmplwi r3, 0
|
/* 8037D914 0037A874 28 03 00 00 */ cmplwi r3, 0
|
||||||
/* 8037D918 0037A878 41 82 00 34 */ beq lbl_8037D94C
|
/* 8037D918 0037A878 41 82 00 34 */ beq lbl_8037D94C
|
||||||
|
@ -285,7 +287,7 @@ lbl_8037D94C:
|
||||||
lbl_8037D970:
|
lbl_8037D970:
|
||||||
/* 8037D970 0037A8D0 38 00 00 01 */ li r0, 1
|
/* 8037D970 0037A8D0 38 00 00 01 */ li r0, 1
|
||||||
/* 8037D974 0037A8D4 80 6D AC C0 */ lwz r3, BootInfo@sda21(r13)
|
/* 8037D974 0037A8D4 80 6D AC C0 */ lwz r3, BootInfo@sda21(r13)
|
||||||
/* 8037D978 0037A8D8 90 0D AC 04 */ stw r0, lbl_805A97C4@sda21(r13)
|
/* 8037D978 0037A8D8 90 0D AC 04 */ stw r0, __DVDLongFileNameFlag@sda21(r13)
|
||||||
/* 8037D97C 0037A8DC 80 63 00 30 */ lwz r3, 0x30(r3)
|
/* 8037D97C 0037A8DC 80 63 00 30 */ lwz r3, 0x30(r3)
|
||||||
/* 8037D980 0037A8E0 28 03 00 00 */ cmplwi r3, 0
|
/* 8037D980 0037A8E0 28 03 00 00 */ cmplwi r3, 0
|
||||||
/* 8037D984 0037A8E4 40 82 00 10 */ bne lbl_8037D994
|
/* 8037D984 0037A8E4 40 82 00 10 */ bne lbl_8037D994
|
||||||
|
@ -304,8 +306,8 @@ lbl_8037D994:
|
||||||
/* 8037D9B4 0037A914 80 03 00 00 */ lwz r0, 0(r3)
|
/* 8037D9B4 0037A914 80 03 00 00 */ lwz r0, 0(r3)
|
||||||
/* 8037D9B8 0037A918 28 00 00 02 */ cmplwi r0, 2
|
/* 8037D9B8 0037A918 28 00 00 02 */ cmplwi r0, 2
|
||||||
/* 8037D9BC 0037A91C 40 80 00 18 */ bge lbl_8037D9D4
|
/* 8037D9BC 0037A91C 40 80 00 18 */ bge lbl_8037D9D4
|
||||||
/* 8037D9C0 0037A920 3C 60 80 5C */ lis r3, _stack_addr@ha
|
/* 8037D9C0 0037A920 3C 60 80 5C */ lis r3, _db_stack_end@ha
|
||||||
/* 8037D9C4 0037A924 38 63 00 C8 */ addi r3, r3, _stack_addr@l
|
/* 8037D9C4 0037A924 38 63 00 C8 */ addi r3, r3, _db_stack_end@l
|
||||||
/* 8037D9C8 0037A928 38 03 00 1F */ addi r0, r3, 0x1f
|
/* 8037D9C8 0037A928 38 03 00 1F */ addi r0, r3, 0x1f
|
||||||
/* 8037D9CC 0037A92C 54 03 00 34 */ rlwinm r3, r0, 0, 0, 0x1a
|
/* 8037D9CC 0037A92C 54 03 00 34 */ rlwinm r3, r0, 0, 0, 0x1a
|
||||||
/* 8037D9D0 0037A930 48 00 0D D9 */ bl OSSetArenaLo
|
/* 8037D9D0 0037A930 48 00 0D D9 */ bl OSSetArenaLo
|
||||||
|
|
|
@ -804,7 +804,7 @@ LIBS = [
|
||||||
"host": False,
|
"host": False,
|
||||||
"objects": [
|
"objects": [
|
||||||
["Dolphin/os/__start", True],
|
["Dolphin/os/__start", True],
|
||||||
"Dolphin/os/OS",
|
["Dolphin/os/OS", True],
|
||||||
["Dolphin/os/OSAlarm", True],
|
["Dolphin/os/OSAlarm", True],
|
||||||
["Dolphin/os/OSArena", True],
|
["Dolphin/os/OSArena", True],
|
||||||
["Dolphin/os/OSAudioSystem", True],
|
["Dolphin/os/OSAudioSystem", True],
|
||||||
|
|
|
@ -13,4 +13,27 @@ typedef struct OSBootInfo {
|
||||||
u32 FSTMaxLength;
|
u32 FSTMaxLength;
|
||||||
} OSBootInfo;
|
} OSBootInfo;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
BOOL valid;
|
||||||
|
u32 restartCode;
|
||||||
|
u32 bootDol;
|
||||||
|
void* regionStart;
|
||||||
|
void* regionEnd;
|
||||||
|
BOOL argsUseDefault;
|
||||||
|
void* argsAddr; // valid only when argsUseDefault = FALSE
|
||||||
|
|
||||||
|
} OSExecParams;
|
||||||
|
|
||||||
|
typedef struct BI2Debug {
|
||||||
|
s32 debugMonSize; // 0x0
|
||||||
|
s32 simMemSize; // 0x4
|
||||||
|
u32 argOffset; // 0x8
|
||||||
|
u32 debugFlag; // 0xC
|
||||||
|
int trackLocation; // 0x10
|
||||||
|
int trackSize; // 0x14
|
||||||
|
u32 countryCode; // 0x18
|
||||||
|
u8 unk[8]; // 0x1C
|
||||||
|
u32 padSpec; // 0x24
|
||||||
|
} BI2Debug;
|
||||||
|
|
||||||
#endif // _DOLPHIN_OSBOOTINFO
|
#endif // _DOLPHIN_OSBOOTINFO
|
||||||
|
|
|
@ -0,0 +1,611 @@
|
||||||
|
#include "dolphin/os.h"
|
||||||
|
#include "dolphin/DVDPriv.h"
|
||||||
|
#include "dolphin/db.h"
|
||||||
|
#include "dolphin/os/OSBootInfo.h"
|
||||||
|
|
||||||
|
extern OSTime __OSGetSystemTime();
|
||||||
|
static const char* __OSVersion =
|
||||||
|
"<< Dolphin SDK - OS\trelease build: Sep 5 2002 05:32:39 (0x2301) >>";
|
||||||
|
extern char _db_stack_end[];
|
||||||
|
|
||||||
|
#define OS_BI2_DEBUG_ADDRESS 0x800000F4
|
||||||
|
#define DEBUGFLAG_ADDR 0x800030E8
|
||||||
|
#define OS_DEBUG_ADDRESS_2 0x800030E9
|
||||||
|
#define OS_CURRENTCONTEXT_PADDR 0x00C0
|
||||||
|
|
||||||
|
extern char* __OSResetSWInterruptHandler[];
|
||||||
|
|
||||||
|
vu16 __OSDeviceCode : (OS_BASE_CACHED | 0x30E6);
|
||||||
|
static DVDDriveInfo DriveInfo ATTRIBUTE_ALIGN(32);
|
||||||
|
static DVDCommandBlock DriveBlock;
|
||||||
|
|
||||||
|
static OSBootInfo* BootInfo;
|
||||||
|
static u32* BI2DebugFlag;
|
||||||
|
static u32* BI2DebugFlagHolder;
|
||||||
|
__declspec(weak) BOOL __OSIsGcam = FALSE;
|
||||||
|
static f64 ZeroF;
|
||||||
|
static f32 ZeroPS[2];
|
||||||
|
static BOOL AreWeInitialized = FALSE;
|
||||||
|
static __OSExceptionHandler* OSExceptionTable;
|
||||||
|
OSTime __OSStartTime;
|
||||||
|
BOOL __OSInIPL;
|
||||||
|
|
||||||
|
extern u8 __ArenaHi[];
|
||||||
|
extern u8 __ArenaLo[];
|
||||||
|
extern u32 __DVDLongFileNameFlag;
|
||||||
|
extern u32 __PADSpec;
|
||||||
|
|
||||||
|
#define OS_EXCEPTIONTABLE_ADDR 0x3000
|
||||||
|
#define OS_DBJUMPPOINT_ADDR 0x60
|
||||||
|
// memory locations for important stuff
|
||||||
|
#define OS_CACHED_REGION_PREFIX 0x8000
|
||||||
|
#define OS_BI2_DEBUG_ADDRESS 0x800000F4
|
||||||
|
#define OS_BI2_DEBUGFLAG_OFFSET 0xC
|
||||||
|
#define PAD3_BUTTON_ADDR 0x800030E4
|
||||||
|
#define OS_DVD_DEVICECODE 0x800030E6
|
||||||
|
#define DEBUGFLAG_ADDR 0x800030E8
|
||||||
|
#define OS_DEBUG_ADDRESS_2 0x800030E9
|
||||||
|
#define DB_EXCEPTIONRET_OFFSET 0xC
|
||||||
|
#define DB_EXCEPTIONDEST_OFFSET 0x8
|
||||||
|
#define MSR_RI_BIT 0x1E
|
||||||
|
|
||||||
|
void OSDefaultExceptionHandler(__OSException exception, OSContext* context);
|
||||||
|
extern BOOL __DBIsExceptionMarked(__OSException);
|
||||||
|
static void OSExceptionInit(void);
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
asm void __OSFPRInit(void)
|
||||||
|
{
|
||||||
|
nofralloc
|
||||||
|
|
||||||
|
mfmsr r3
|
||||||
|
ori r3, r3, 0x2000
|
||||||
|
mtmsr r3
|
||||||
|
|
||||||
|
mfspr r3, 0x398
|
||||||
|
rlwinm. r3, r3, 3, 31, 31
|
||||||
|
beq SkipPairedSingles
|
||||||
|
|
||||||
|
lis r3, ZeroPS@ha
|
||||||
|
addi r3, r3, ZeroPS@l
|
||||||
|
psq_l fp0, 0(r3), 0, 0
|
||||||
|
ps_mr fp1, fp0
|
||||||
|
ps_mr fp2, fp0
|
||||||
|
ps_mr fp3, fp0
|
||||||
|
ps_mr fp4, fp0
|
||||||
|
ps_mr fp5, fp0
|
||||||
|
ps_mr fp6, fp0
|
||||||
|
ps_mr fp7, fp0
|
||||||
|
ps_mr fp8, fp0
|
||||||
|
ps_mr fp9, fp0
|
||||||
|
ps_mr fp10, fp0
|
||||||
|
ps_mr fp11, fp0
|
||||||
|
ps_mr fp12, fp0
|
||||||
|
ps_mr fp13, fp0
|
||||||
|
ps_mr fp14, fp0
|
||||||
|
ps_mr fp15, fp0
|
||||||
|
ps_mr fp16, fp0
|
||||||
|
ps_mr fp17, fp0
|
||||||
|
ps_mr fp18, fp0
|
||||||
|
ps_mr fp19, fp0
|
||||||
|
ps_mr fp20, fp0
|
||||||
|
ps_mr fp21, fp0
|
||||||
|
ps_mr fp22, fp0
|
||||||
|
ps_mr fp23, fp0
|
||||||
|
ps_mr fp24, fp0
|
||||||
|
ps_mr fp25, fp0
|
||||||
|
ps_mr fp26, fp0
|
||||||
|
ps_mr fp27, fp0
|
||||||
|
ps_mr fp28, fp0
|
||||||
|
ps_mr fp29, fp0
|
||||||
|
ps_mr fp30, fp0
|
||||||
|
ps_mr fp31, fp0
|
||||||
|
|
||||||
|
SkipPairedSingles:
|
||||||
|
lfd fp0, ZeroF
|
||||||
|
fmr fp1, fp0
|
||||||
|
fmr fp2, fp0
|
||||||
|
fmr fp3, fp0
|
||||||
|
fmr fp4, fp0
|
||||||
|
fmr fp5, fp0
|
||||||
|
fmr fp6, fp0
|
||||||
|
fmr fp7, fp0
|
||||||
|
fmr fp8, fp0
|
||||||
|
fmr fp9, fp0
|
||||||
|
fmr fp10, fp0
|
||||||
|
fmr fp11, fp0
|
||||||
|
fmr fp12, fp0
|
||||||
|
fmr fp13, fp0
|
||||||
|
fmr fp14, fp0
|
||||||
|
fmr fp15, fp0
|
||||||
|
fmr fp16, fp0
|
||||||
|
fmr fp17, fp0
|
||||||
|
fmr fp18, fp0
|
||||||
|
fmr fp19, fp0
|
||||||
|
fmr fp20, fp0
|
||||||
|
fmr fp21, fp0
|
||||||
|
fmr fp22, fp0
|
||||||
|
fmr fp23, fp0
|
||||||
|
fmr fp24, fp0
|
||||||
|
fmr fp25, fp0
|
||||||
|
fmr fp26, fp0
|
||||||
|
fmr fp27, fp0
|
||||||
|
fmr fp28, fp0
|
||||||
|
fmr fp29, fp0
|
||||||
|
fmr fp30, fp0
|
||||||
|
fmr fp31, fp0
|
||||||
|
|
||||||
|
mtfsf 0xFF, fp0
|
||||||
|
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
|
u32 OSGetConsoleType() {
|
||||||
|
if (BootInfo == NULL || BootInfo->consoleType == 0) {
|
||||||
|
return OS_CONSOLE_ARTHUR;
|
||||||
|
}
|
||||||
|
return BootInfo->consoleType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* __OSSavedRegionStart;
|
||||||
|
void* __OSSavedRegionEnd;
|
||||||
|
|
||||||
|
extern u32 BOOT_REGION_START : 0x812FDFF0; //(*(u32 *)0x812fdff0)
|
||||||
|
extern u32 BOOT_REGION_END : 0x812FDFEC; //(*(u32 *)0x812fdfec)
|
||||||
|
|
||||||
|
void ClearArena(void) {
|
||||||
|
if ((u32)(OSGetResetCode() + 0x80000000) != 0U) {
|
||||||
|
__OSSavedRegionStart = 0U;
|
||||||
|
__OSSavedRegionEnd = 0U;
|
||||||
|
memset(OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__OSSavedRegionStart = (void*)BOOT_REGION_START;
|
||||||
|
__OSSavedRegionEnd = (void*)BOOT_REGION_END;
|
||||||
|
if (BOOT_REGION_START == 0U) {
|
||||||
|
memset(OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((u32)OSGetArenaLo() < (u32)__OSSavedRegionStart) {
|
||||||
|
if ((u32)OSGetArenaHi() <= (u32)__OSSavedRegionStart) {
|
||||||
|
memset((u32)OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memset(OSGetArenaLo(), 0U, (u32)__OSSavedRegionStart - (u32)OSGetArenaLo());
|
||||||
|
if ((u32)OSGetArenaHi() > (u32)__OSSavedRegionEnd) {
|
||||||
|
memset((u32)__OSSavedRegionEnd, 0, (u32)OSGetArenaHi() - (u32)__OSSavedRegionEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InquiryCallback(s32 result, DVDCommandBlock* block) {
|
||||||
|
switch (block->state) {
|
||||||
|
case 0:
|
||||||
|
__OSDeviceCode = (u16)(0x8000 | DriveInfo.deviceCode);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
__OSDeviceCode = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSInit(void) {
|
||||||
|
/*
|
||||||
|
Initializes the Dolphin operating system.
|
||||||
|
- most of the main operations get farmed out to other functions
|
||||||
|
- loading debug info and setting up heap bounds largely happen here
|
||||||
|
- a lot of OS reporting also gets controlled here
|
||||||
|
*/
|
||||||
|
// pretty sure this is the min(/max) amount of pointers etc for the stack to match
|
||||||
|
BI2Debug* DebugInfo;
|
||||||
|
void* debugArenaLo;
|
||||||
|
u32 inputConsoleType;
|
||||||
|
u32 tdev;
|
||||||
|
|
||||||
|
// check if we've already done all this or not
|
||||||
|
if ((BOOL)AreWeInitialized == FALSE) { // fantastic name
|
||||||
|
AreWeInitialized = TRUE; // flag to make sure we don't have to do this again
|
||||||
|
|
||||||
|
// SYSTEM //
|
||||||
|
__OSStartTime = __OSGetSystemTime();
|
||||||
|
OSDisableInterrupts();
|
||||||
|
|
||||||
|
// set some PPC things
|
||||||
|
PPCDisableSpeculation();
|
||||||
|
PPCSetFpNonIEEEMode();
|
||||||
|
|
||||||
|
// DEBUG //
|
||||||
|
// load some DVD stuff
|
||||||
|
BI2DebugFlag = 0; // debug flag from the DVD BI2 header
|
||||||
|
BootInfo = (OSBootInfo*)OS_BASE_CACHED; // set pointer to BootInfo
|
||||||
|
|
||||||
|
__DVDLongFileNameFlag = (u32)0; // flag to tell us whether we make it through the debug loading
|
||||||
|
|
||||||
|
// time to grab a bunch of debug info from the DVD
|
||||||
|
// the address for where the BI2 debug info is, is stored at OS_BI2_DEBUG_ADDRESS
|
||||||
|
DebugInfo = (BI2Debug*)*((u32*)OS_BI2_DEBUG_ADDRESS);
|
||||||
|
|
||||||
|
// if the debug info address exists, grab some debug info
|
||||||
|
if (DebugInfo != NULL) {
|
||||||
|
BI2DebugFlag = &DebugInfo->debugFlag; // debug flag from DVD BI2
|
||||||
|
__PADSpec = (u32)DebugInfo->padSpec; // some other info from DVD BI2
|
||||||
|
*((u8*)DEBUGFLAG_ADDR) = (u8)*BI2DebugFlag; // store flag in mem
|
||||||
|
*((u8*)OS_DEBUG_ADDRESS_2) = (u8)__PADSpec; // store other info in mem
|
||||||
|
} else if (BootInfo->arenaHi) { // if the top of the heap is already set
|
||||||
|
BI2DebugFlagHolder = (u32*)*((u8*)DEBUGFLAG_ADDR); // grab whatever's stored at 0x800030E8
|
||||||
|
BI2DebugFlag = (u32*)&BI2DebugFlagHolder; // flag is then address of flag holder
|
||||||
|
__PADSpec = (u32) * ((u8*)OS_DEBUG_ADDRESS_2); // pad spec is whatever's at 0x800030E9
|
||||||
|
}
|
||||||
|
|
||||||
|
__DVDLongFileNameFlag = 1; // we made it through debug!
|
||||||
|
|
||||||
|
// HEAP //
|
||||||
|
// set up bottom of heap (ArenaLo)
|
||||||
|
// grab address from BootInfo if it exists, otherwise use default __ArenaLo
|
||||||
|
OSSetArenaLo((BootInfo->arenaLo == NULL) ? __ArenaLo : BootInfo->arenaLo);
|
||||||
|
|
||||||
|
// if the input arenaLo is null, and debug flag location exists (and flag is < 2),
|
||||||
|
// set arenaLo to just past the end of the db stack
|
||||||
|
if ((BootInfo->arenaLo == NULL) && (BI2DebugFlag != 0) && (*BI2DebugFlag < 2)) {
|
||||||
|
debugArenaLo = (char*)(((u32)_db_stack_end + 0x1f) & ~0x1f);
|
||||||
|
OSSetArenaLo(debugArenaLo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up top of heap (ArenaHi)
|
||||||
|
// grab address from BootInfo if it exists, otherwise use default __ArenaHi
|
||||||
|
OSSetArenaHi((BootInfo->arenaHi == NULL) ? __ArenaHi : BootInfo->arenaHi);
|
||||||
|
|
||||||
|
// OS INIT AND REPORT //
|
||||||
|
// initialise a whole bunch of OS stuff
|
||||||
|
OSExceptionInit();
|
||||||
|
__OSInitSystemCall();
|
||||||
|
OSInitAlarm();
|
||||||
|
__OSModuleInit();
|
||||||
|
__OSInterruptInit();
|
||||||
|
__OSSetInterruptHandler(__OS_INTERRUPT_PI_RSW, (void*)__OSResetSWInterruptHandler);
|
||||||
|
__OSContextInit();
|
||||||
|
__OSCacheInit();
|
||||||
|
EXIInit();
|
||||||
|
SIInit();
|
||||||
|
__OSInitSram();
|
||||||
|
__OSThreadInit();
|
||||||
|
__OSInitAudioSystem();
|
||||||
|
PPCMthid2(PPCMfhid2() & 0xBFFFFFFF);
|
||||||
|
if ((BOOL)__OSInIPL == FALSE) {
|
||||||
|
__OSInitMemoryProtection();
|
||||||
|
}
|
||||||
|
|
||||||
|
// begin OS reporting
|
||||||
|
OSReport("\nDolphin OS $Revision: 58 $.\n");
|
||||||
|
OSReport("Kernel built : %s %s\n", "Sep 5 2002", "05:32:39");
|
||||||
|
OSReport("Console Type : ");
|
||||||
|
|
||||||
|
// this is a function in the same file, but it doesn't seem to match
|
||||||
|
// inputConsoleType = OSGetConsoleType();
|
||||||
|
|
||||||
|
// inputConsoleType = (BootInfo == NULL || (inputConsoleType = BootInfo->consoleType) == 0) ?
|
||||||
|
// 0x10000002 : BootInfo->consoleType;
|
||||||
|
if (BootInfo == NULL || (inputConsoleType = BootInfo->consoleType) == 0) {
|
||||||
|
inputConsoleType = OS_CONSOLE_ARTHUR; // default console type
|
||||||
|
} else {
|
||||||
|
inputConsoleType = BootInfo->consoleType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// work out what console type this corresponds to and report it
|
||||||
|
// consoleTypeSwitchHi = inputConsoleType & 0xF0000000;
|
||||||
|
switch (inputConsoleType & 0xffff0000) { // check "first" byte
|
||||||
|
case OS_CONSOLE_RETAIL:
|
||||||
|
OSReport("Retail %d\n", inputConsoleType);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
switch (inputConsoleType & 0x0000ffff) { // if "first" byte is 2, check "the rest"
|
||||||
|
case OS_CONSOLE_EMULATOR:
|
||||||
|
OSReport("Mac Emulator\n");
|
||||||
|
break;
|
||||||
|
case OS_CONSOLE_PC_EMULATOR:
|
||||||
|
OSReport("PC Emulator\n");
|
||||||
|
break;
|
||||||
|
case OS_CONSOLE_ARTHUR:
|
||||||
|
OSReport("EPPC Arthur\n");
|
||||||
|
break;
|
||||||
|
case OS_CONSOLE_MINNOW:
|
||||||
|
OSReport("EPPC Minnow\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
tdev = ((u32)inputConsoleType & 0x0000ffff);
|
||||||
|
OSReport("Development HW%d (%08x)\n", tdev - 3, inputConsoleType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// report memory size
|
||||||
|
OSReport("Memory %d MB\n", (u32)BootInfo->memorySize >> 0x14U);
|
||||||
|
// report heap bounds
|
||||||
|
OSReport("Arena : 0x%x - 0x%x\n", OSGetArenaLo(), OSGetArenaHi());
|
||||||
|
// report OS version
|
||||||
|
OSRegisterVersion(__OSVersion);
|
||||||
|
|
||||||
|
// if location of debug flag exists, and flag is >= 2, enable MetroTRKInterrupts
|
||||||
|
if (BI2DebugFlag && ((*BI2DebugFlag) >= 2)) {
|
||||||
|
EnableMetroTRKInterrupts();
|
||||||
|
}
|
||||||
|
|
||||||
|
// free up memory and re-enable things
|
||||||
|
ClearArena();
|
||||||
|
OSEnableInterrupts();
|
||||||
|
|
||||||
|
// check if we can load OS from IPL; if not, grab it from DVD (?)
|
||||||
|
if ((BOOL)__OSInIPL == FALSE) {
|
||||||
|
DVDInit();
|
||||||
|
if ((BOOL)__OSIsGcam) {
|
||||||
|
__OSDeviceCode = 0x9000;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DCInvalidateRange(&DriveInfo, sizeof(DriveInfo));
|
||||||
|
DVDInquiryAsync((char*)&DriveBlock, &DriveInfo, InquiryCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static u32 __OSExceptionLocations[] = {
|
||||||
|
0x00000100, 0x00000200, 0x00000300, 0x00000400, 0x00000500, 0x00000600, 0x00000700, 0x00000800,
|
||||||
|
0x00000900, 0x00000C00, 0x00000D00, 0x00000F00, 0x00001300, 0x00001400, 0x00001700,
|
||||||
|
};
|
||||||
|
|
||||||
|
// dummy entry points to the OS Exception vector
|
||||||
|
void __OSEVStart(void);
|
||||||
|
void __OSEVEnd(void);
|
||||||
|
void __OSEVSetNumber(void);
|
||||||
|
void __OSExceptionVector(void);
|
||||||
|
|
||||||
|
void __DBVECTOR(void);
|
||||||
|
void __OSDBINTSTART(void);
|
||||||
|
void __OSDBINTEND(void);
|
||||||
|
void __OSDBJUMPSTART(void);
|
||||||
|
void __OSDBJUMPEND(void);
|
||||||
|
|
||||||
|
#define NOP 0x60000000
|
||||||
|
|
||||||
|
__OSExceptionHandler __OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --INFO--
|
||||||
|
* Address: 800EB654
|
||||||
|
* Size: 000280
|
||||||
|
*/
|
||||||
|
static void OSExceptionInit(void) {
|
||||||
|
__OSException exception;
|
||||||
|
void* destAddr;
|
||||||
|
|
||||||
|
// These two vars help us change the exception number embedded
|
||||||
|
// in the exception handler code.
|
||||||
|
u32* opCodeAddr;
|
||||||
|
u32 oldOpCode;
|
||||||
|
|
||||||
|
// Address range of the actual code to be copied.
|
||||||
|
u8* handlerStart;
|
||||||
|
u32 handlerSize;
|
||||||
|
|
||||||
|
// Install the first level exception vector.
|
||||||
|
opCodeAddr = (u32*)__OSEVSetNumber;
|
||||||
|
oldOpCode = *opCodeAddr;
|
||||||
|
handlerStart = (u8*)__OSEVStart;
|
||||||
|
handlerSize = (u32)((u8*)__OSEVEnd - (u8*)__OSEVStart);
|
||||||
|
|
||||||
|
// Install the DB integrator, only if we are the first OSInit to be run
|
||||||
|
destAddr = (void*)OSPhysicalToCached(OS_DBJUMPPOINT_ADDR);
|
||||||
|
if (*(u32*)destAddr == 0) // Lomem should be zero cleared only once by BS2
|
||||||
|
{
|
||||||
|
DBPrintf("Installing OSDBIntegrator\n");
|
||||||
|
memcpy(destAddr, (void*)__OSDBINTSTART, (u32)__OSDBINTEND - (u32)__OSDBINTSTART);
|
||||||
|
DCFlushRangeNoSync(destAddr, (u32)__OSDBINTEND - (u32)__OSDBINTSTART);
|
||||||
|
__sync();
|
||||||
|
ICInvalidateRange(destAddr, (u32)__OSDBINTEND - (u32)__OSDBINTSTART);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the right vector into the table
|
||||||
|
for (exception = 0; exception < __OS_EXCEPTION_MAX; exception++) {
|
||||||
|
if (BI2DebugFlag && (*BI2DebugFlag >= 2) && __DBIsExceptionMarked(exception)) {
|
||||||
|
// this DBPrintf is suspicious.
|
||||||
|
DBPrintf(">>> OSINIT: exception %d commandeered by TRK\n", exception);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modify the copy of code in text before transferring
|
||||||
|
// to the exception table.
|
||||||
|
*opCodeAddr = oldOpCode | exception;
|
||||||
|
|
||||||
|
// Modify opcodes at __DBVECTOR if necessary
|
||||||
|
if (__DBIsExceptionMarked(exception)) {
|
||||||
|
DBPrintf(">>> OSINIT: exception %d vectored to debugger\n", exception);
|
||||||
|
memcpy((void*)__DBVECTOR, (void*)__OSDBJUMPSTART, (u32)__OSDBJUMPEND - (u32)__OSDBJUMPSTART);
|
||||||
|
} else {
|
||||||
|
// make sure the opcodes are still nop
|
||||||
|
u32* ops = (u32*)__DBVECTOR;
|
||||||
|
int cb;
|
||||||
|
|
||||||
|
for (cb = 0; cb < (u32)__OSDBJUMPEND - (u32)__OSDBJUMPSTART; cb += sizeof(u32)) {
|
||||||
|
*ops++ = NOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install the modified handler.
|
||||||
|
destAddr = (void*)OSPhysicalToCached(__OSExceptionLocations[(u32)exception]);
|
||||||
|
memcpy(destAddr, handlerStart, handlerSize);
|
||||||
|
DCFlushRangeNoSync(destAddr, handlerSize);
|
||||||
|
__sync();
|
||||||
|
ICInvalidateRange(destAddr, handlerSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize pointer to exception table
|
||||||
|
OSExceptionTable = OSPhysicalToCached(OS_EXCEPTIONTABLE_ADDR);
|
||||||
|
|
||||||
|
// install default exception handlers
|
||||||
|
for (exception = 0; exception < __OS_EXCEPTION_MAX; exception++) {
|
||||||
|
__OSSetExceptionHandler(exception, OSDefaultExceptionHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore the old opcode, so that we can re-start an application without
|
||||||
|
// downloading the text segments
|
||||||
|
*opCodeAddr = oldOpCode;
|
||||||
|
|
||||||
|
DBPrintf("Exceptions initialized...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static asm void __OSDBIntegrator(void) {
|
||||||
|
/* clang-format off */
|
||||||
|
nofralloc
|
||||||
|
entry __OSDBINTSTART
|
||||||
|
li r5, OS_DBINTERFACE_ADDR
|
||||||
|
mflr r3
|
||||||
|
stw r3, DB_EXCEPTIONRET_OFFSET(r5)
|
||||||
|
lwz r3, DB_EXCEPTIONDEST_OFFSET(r5)
|
||||||
|
oris r3, r3, OS_CACHED_REGION_PREFIX
|
||||||
|
mtlr r3
|
||||||
|
li r3, 0x30 // MSR_IR | MSR_DR // turn on memory addressing
|
||||||
|
mtmsr r3
|
||||||
|
blr
|
||||||
|
entry __OSDBINTEND
|
||||||
|
/* clang-format on */
|
||||||
|
}
|
||||||
|
|
||||||
|
static asm void __OSDBJump(void){
|
||||||
|
/* clang-format off */
|
||||||
|
|
||||||
|
nofralloc
|
||||||
|
entry __OSDBJUMPSTART
|
||||||
|
bla OS_DBJUMPPOINT_ADDR
|
||||||
|
entry __OSDBJUMPEND
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
|
} __OSExceptionHandler
|
||||||
|
__OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler) {
|
||||||
|
__OSExceptionHandler oldHandler;
|
||||||
|
oldHandler = OSExceptionTable[exception];
|
||||||
|
OSExceptionTable[exception] = handler;
|
||||||
|
return oldHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
__OSExceptionHandler __OSGetExceptionHandler(__OSException exception) {
|
||||||
|
return OSExceptionTable[exception];
|
||||||
|
}
|
||||||
|
|
||||||
|
static asm void OSExceptionVector(void) {
|
||||||
|
/* clang-format off */
|
||||||
|
nofralloc
|
||||||
|
|
||||||
|
entry __OSEVStart
|
||||||
|
// Save r4 into SPRG0
|
||||||
|
mtsprg 0, r4
|
||||||
|
|
||||||
|
// Load current context physical address into r4
|
||||||
|
lwz r4, OS_CURRENTCONTEXT_PADDR
|
||||||
|
|
||||||
|
// Save r3 - r5 into the current context
|
||||||
|
stw r3, OS_CONTEXT_R3(r4)
|
||||||
|
mfsprg r3, 0
|
||||||
|
stw r3, OS_CONTEXT_R4(r4)
|
||||||
|
stw r5, OS_CONTEXT_R5(r4)
|
||||||
|
|
||||||
|
lhz r3, OS_CONTEXT_STATE(r4)
|
||||||
|
ori r3, r3, OS_CONTEXT_STATE_EXC
|
||||||
|
sth r3, OS_CONTEXT_STATE(r4)
|
||||||
|
|
||||||
|
// Save misc registers
|
||||||
|
mfcr r3
|
||||||
|
stw r3, OS_CONTEXT_CR(r4)
|
||||||
|
mflr r3
|
||||||
|
stw r3, OS_CONTEXT_LR(r4)
|
||||||
|
mfctr r3
|
||||||
|
stw r3, OS_CONTEXT_CTR(r4)
|
||||||
|
mfxer r3
|
||||||
|
stw r3, OS_CONTEXT_XER(r4)
|
||||||
|
mfsrr0 r3
|
||||||
|
stw r3, OS_CONTEXT_SRR0(r4)
|
||||||
|
mfsrr1 r3
|
||||||
|
stw r3, OS_CONTEXT_SRR1(r4)
|
||||||
|
mr r5, r3
|
||||||
|
|
||||||
|
entry __DBVECTOR
|
||||||
|
nop
|
||||||
|
|
||||||
|
// Set SRR1[IR|DR] to turn on address
|
||||||
|
// translation at the next RFI
|
||||||
|
mfmsr r3
|
||||||
|
ori r3, r3, 0x30
|
||||||
|
mtsrr1 r3
|
||||||
|
|
||||||
|
// This lets us change the exception number based on the
|
||||||
|
// exception we're installing.
|
||||||
|
entry __OSEVSetNumber
|
||||||
|
addi r3, 0, 0x0000
|
||||||
|
|
||||||
|
// Load current context virtual address into r4
|
||||||
|
lwz r4, 0xD4
|
||||||
|
|
||||||
|
// Check non-recoverable interrupt
|
||||||
|
rlwinm. r5, r5, 0, MSR_RI_BIT, MSR_RI_BIT
|
||||||
|
bne recoverable
|
||||||
|
addis r5, 0, OSDefaultExceptionHandler@ha
|
||||||
|
addi r5, r5, OSDefaultExceptionHandler@l
|
||||||
|
mtsrr0 r5
|
||||||
|
rfi
|
||||||
|
// NOT REACHED HERE
|
||||||
|
|
||||||
|
recoverable:
|
||||||
|
// Locate exception handler.
|
||||||
|
rlwinm r5, r3, 2, 22, 29 // r5 contains exception*4
|
||||||
|
lwz r5, OS_EXCEPTIONTABLE_ADDR(r5)
|
||||||
|
mtsrr0 r5
|
||||||
|
|
||||||
|
// Final state
|
||||||
|
// r3 - exception number
|
||||||
|
// r4 - pointer to context
|
||||||
|
// r5 - garbage
|
||||||
|
// srr0 - exception handler
|
||||||
|
// srr1 - address translation enalbed, not yet recoverable
|
||||||
|
|
||||||
|
rfi
|
||||||
|
// NOT REACHED HERE
|
||||||
|
// The handler will restore state
|
||||||
|
|
||||||
|
entry __OSEVEnd
|
||||||
|
nop
|
||||||
|
/* clang-format on */
|
||||||
|
}
|
||||||
|
|
||||||
|
void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar);
|
||||||
|
asm void OSDefaultExceptionHandler(register __OSException exception, register OSContext* context) {
|
||||||
|
/* clang-format off */
|
||||||
|
nofralloc
|
||||||
|
OS_EXCEPTION_SAVE_GPRS(context)
|
||||||
|
mfdsisr r5
|
||||||
|
mfdar r6
|
||||||
|
|
||||||
|
stwu r1,-8(r1)
|
||||||
|
b __OSUnhandledException
|
||||||
|
/* clang-foramt on */
|
||||||
|
}
|
||||||
|
|
||||||
|
void __OSPSInit(void)
|
||||||
|
{
|
||||||
|
PPCMthid2(PPCMfhid2() | 0xA0000000);
|
||||||
|
ICFlashInvalidate();
|
||||||
|
__sync();
|
||||||
|
// clang-format off
|
||||||
|
asm
|
||||||
|
{
|
||||||
|
li r3, 0
|
||||||
|
mtspr GQR0, r3
|
||||||
|
}
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
|
||||||
|
vu32 __DIRegs[16] : 0xCC006000;
|
||||||
|
#define DI_CONFIG_IDX 0x9
|
||||||
|
#define DI_CONFIG_CONFIG_MASK 0xFF
|
||||||
|
u32 __OSGetDIConfig(void) { return (__DIRegs[DI_CONFIG_IDX] & DI_CONFIG_CONFIG_MASK); }
|
||||||
|
|
||||||
|
void OSRegisterVersion(const char* id) { OSReport("%s\n", id); }
|
Loading…
Reference in New Issue