pureikyubu/Docs/RE/OS.c
ogamespec c21147ccff Cumulative changes all around project, regarding Stage 1
Docs: New TODO moved to EMU, old renamed to old_todo
Docs: Old coding style is deprecated (old_style.txt)
Docs: Removed mention about CubeDocumented and fixed old emails
RE: boot.s, proved first asm line (lis instruction parameter)
RE: Added PAL and NTSC Boot and IPL IDA files
RE: Some work on NTSC IPL (identified many lib calls, including OS, GX)
RE: Added EXI Bootrom descrambler by segher
RE: GXInit
RE: Internal GX lib structures (GXPrivate.h)
RE: More details on lomem (OS versions)
RE: OSInit and OS.c
RE: OSAlloc (heap allocator)
RE: Very first code of Metrowerk runtime (__start.c)
Docs: Added copy of http://gcdev.narod.ru
Source\Utils: Command processor (Cmd.c)
Source\Utils: File wrapper
Source\Utils: Gekko disasm cleaned up and ported to plain C
Source\Utils: Double-linked lists
Source\Utils: Ported old Profiler code
Source\Utils: String utils
2015-09-04 19:45:10 +03:00

553 lines
11 KiB
C

// OS Init.
struct OSBootInfo_s
{
DVDDiskID diskID;
magic
version
memorySize; // 0x28
u32 consoleType; // 0x2C
arenaLo; // 0x30
arenaHi; // 0x34
FSTLocation;
FSTMaxLength;
} ;
OSBootInfo_s * BootInfo;
double ZeroF = 0.0;
BOOLEAN AreWeInitialized;
OSTime __OSStartTime;
u32 __OSExceptionLocations[] = {
0x100,
0x200,
0x300,
0x400,
0x500,
0x600,
0x700,
0x800,
0x900,
0xC00,
0xD00,
0xF00,
0x1300,
0x1400,
0x1700,
};
char * __OSExceptionNames[] = {
"System reset",
"MachineCheck",
"DSI",
"ISI",
"External Int.",
"Alignment",
"Program",
"FP Unavailable",
"Decrementer",
"System call",
"Trace",
"Perf mon",
"IABR",
"SMI",
"Thermal Int.",
"Protection error",
};
__OSExceptionHandler * OSExceptionTable;
u32 * BI2DebugFlag;
u32 BI2DebugFlagHolder;
BOOLEAN __OSInIPL;
//
// Procedures
//
__OSIsDebuggerPresent ()
{
u32 * flag = OSPhysicalToCached (0x40);
return *flag;
}
__OSInitFPRs ()
{
f0 = ZeroF;
f1...f31 = f0;
}
DisableWriteGatherPipe ()
{
PPCMthid2 (
PPCMfhid2 () & ~HID2_WPE );
}
u32 OSGetConsoleType ()
{
return (BootInfo->consoleType ) ? BootInfo->consoleType : OS_CONSOLE_ARTHUR;
}
ClearArena ()
{
void * regionStart
void * regionEnd;
if ( OSGetResetCode() == OS_RESETCODE_RESTART )
{
regionStart = *(0x81300000 - 0x2010);
regionEnd = *(0x81300000 - 0x2014);
if ( regionStart )
{
ASSERT ( regionEnd != NULL );
if ( OSGetArenaLo() < regionStart )
{
if ( OSGetArenaHi() > regionStart )
{
//
// Clear excluding Reset region.
//
memset ( OSGetArenaLo(),
0,
regionStart - OSGetArenaLo() );
memset ( regionEnd,
0,
OSGetArenaHi() - regionEnd );
return;
}
}
else return;
}
}
//
// Clear All
//
ClearAll:
memset ( OSGetArenaLo (),
0,
OSGetArenaHi () - OSGetArenaLo() );
}
OSInit ()
{
void * arenaLo;
void * arenaHi;
if ( AreWeInitialized )
return;
AreWeInitialized = TRUE;
__OSStartTime = __OSGetSystemTime ();
OSDisableInterrupts ();
BootInfo = OSPhysicalToCached (0);
BI2DebugFlag = NULL;
__DVDLongFileNameFlag = 0;
//
// BI2DebugFlag & __PADSpec
//
if ( *dword.OSPhysicalToCached(0xF4) == 0 )
{
if ( BootInfo->arenaHi )
{
BI2DebugFlagHolder = *byte.OSPhysicalToCached(0x30E8);
BI2DebugFlag = &BI2DebugFlagHolder;
__PADSpec = *byte.OSPhysicalToCached (0x30E9);
}
}
else
{
r29 = * dword.OSPhysicalToCached(0xF4);
BI2DebugFlag = r29 + 0xC;
__PADSpec = dword.[r29 + 0x24];
*byte.OSPhysicalToCached(0x30E8) = (*BI2DebugFlag) & 0xFF;
*byte.OSPhysicalToCached(0x30E8) = __PADSpec & 0xFF;
}
__DVDLongFileNameFlag = TRUE;
//
// Arena Lo
//
if ( BootInfo->arenaLo ) arenaLo = BootInfo->arenaLo;
else arenaLo = __ArenaLo;
OSSetArenaLo ( arenaLo );
if ( BI2DebugFlag ) // Set Arena Lo at stack
{
if ( *BI2DebugFlag < 2 )
OSSetArenaLo ( OSRoundUp32B(_stack_addr) );
}
//
// Arena Hi
//
if ( BootInfo->arenaHi ) arenaHi = BootInfo->arenaHi;
else arenaHi = __ArenaHi;
OSSetArenaHi ( arenaHi );
//
// OS Subsystems
//
OSExceptionInit ();
__OSInitSystemCall ();
OSInitAlarm ();
__OSModuleInit ();
__OSInterruptInit ();
__OSSetInterruptHandler ( __OS_INTERRUPT_PI_RSW,
__OSResetSWInterruptHandler );
__OSContextInit ();
__OSCacheInit ();
EXIInit ();
SIInit ();
__OSInitSram ();
__OSThreadInit ();
__OSInitAudioSystem ();
DisableWriteGatherPipe ();
//
// Console Type
//
ASSERT ( BootInfo );
if ( BootInfo->consoleType >> 28 )
BootInfo->consoleType = OS_CONSOLE_DEVHW1;
else
BootInfo->consoleType = OS_CONSOLE_RETAIL1;
BootInfo->consoleType += (dword.0xCC00302C >> 28);
if ( __OSInIPL == 0 )
__OSInitMemoryProtection ();
//
// Report OS Version
//
OSReport ( "\n"
"Dolphin OS $Revision: 49 $.\n" );
OSReport ( "Kernel built : %s %s\n", __DATE__, __TIME__ );
//
// Report console type
//
OSReport ( "Console Type : " );
consoleType = OSGetConsoleType ();
if ( consoleType & OS_CONSOLE_DEVELOPMENT )
{
switch (consoleType)
{
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:
OSReport ( "Development HW%d\n", consoleType & ~OS_CONSOLE_DEVELOPMENT );
break;
}
}
else OSReport ( "Retail %d\n", consoleType );
OSReport ( "Memory %d MB\n", BootInfo->memorySize / 1024*1024 );
OSReport ( "Arena : 0x%x - 0x%x\n", OSGetArenaLo(), OSGetArenaHi() );
if ( BI2DebugFlag )
{
if ( *BI2DebugFlag < 2 )
EnableMetroTRKInterrupts ();
}
ClearArena ();
OSEnableInterrupts ();
}
OSExceptionInit ()
{
__OSException exception;
void * destAddr;
u32 * opCodeAddr;
u32 oldOpCode;
void * handlerStart;
int handlerSize;
u32 * ops;
int cb;
handlerSize = __OSEVEnd - __OSEVStart;
ASSERTMSG ( handlerSize <= 0x100 , "OSExceptionInit(): too big exception vector code." );
opCodeAddr = __OSEVSetNumber;
oldOpCode = *opCodeAddr;
destAddr = OSPhysicalToCached ( 0x60 );
if ( *destAddr == 0 )
{
DBPrintf ( "Installing OSDBIntegrator\n" );
memcpy ( destAddr, __OSDBINTSTART, __OSDBJUMPSTART - __OSDBINTSTART );
DCFlushRangeNoSync ( destAddr, __OSDBJUMPSTART - __OSDBINTSTART );
__sync;
ICInvalidateRange ( destAddr, __OSDBJUMPSTART - __OSDBINTSTART );
}
//
// Redirect to Debugger.
//
for ( exception=0; exception<__OS_EXCEPTION_MAX; exception++ )
{
if ( BI2DebugFlag )
{
if ( ! ( *BI2DebugFlag < 2 && !__DBIsExceptionMarked(exception) ) )
{
DBPrintf ( ">>> OSINIT: exception %d commandeered by TRK\n", exception );
continue;
}
}
*opCodeAddr = oldOpCode | exception;
if ( !__DBIsExceptionMarked (exception) )
{
cb = 0;
ops = __DBVECTOR;
while ( cb < (__OSDBJUMPEND - __OSDBJUMPSTART) )
{
*ops = 0x60000000; // nop
ops++;
cb += 4;
}
}
else
{
DBPrintf ( ">>> OSINIT: exception %d vectored to debugger\n", exception );
memcpy ( __DBVECTOR,
__OSDBJUMPSTART,
__OSDBJUMPEND - __OSDBJUMPSTART );
}
handlerStart = OSPhysicalToCached ( __OSExceptionLocations[exception] );
memcpy ( handlerStart, __OSEVStart, handlerSize );
DCFlushRangeNoSync ( handlerStart, handlerSize );
__sync;
ICInvalidateRange ( handlerStart, handlerSize );
}
//
// Install default exception handlers.
//
OSExceptionTable = OSPhysicalToCached ( 0x3000 );
for ( exception=0; exception<0xF; exception++ )
{
__OSSetExceptionHandler ( exception, OSDefaultExceptionHandler );
}
*opCodeAddr = oldOpCode;
DBPrintf ( "Exceptions initialized...\n" );
}
__OSDBINTSTART:
li r5, 0x40
mflr r3
stw r3, 0xC(r5)
lwz r3, 8(r5)
oris r3, r3, 0x8000
mtlr r3
li r3, 0x30 # '0'
mtmsr r3
blr
__OSDBINTEND:
__OSDBJUMPSTART:
__OSDBJump:
bla 0x60
__OSDBJUMPEND:
//
// Updates OS exception table, NOT first-level exception vector.
//
__OSExceptionHandler __OSSetExceptionHandler(
__OSException exception,
__OSExceptionHandler handler )
{
__OSExceptionHandler oldHandler;
ASSERTMSG ( exception < __OS_EXCEPTION_MAX, "__OSSetExceptionHandler(): unknown exception." );
oldHandler = OSExceptionTable[exception];
OSExceptionTable[exception] = handler;
return oldHandler;
}
__OSExceptionHandler __OSGetExceptionHandler(
__OSException exception
)
{
ASSERTMSG ( exception < __OS_EXCEPTION_MAX, "__OSGetExceptionHandler(): unknown exception." );
return OSExceptionTable[exception];
}
__OSEVStart:
OSExceptionVector:
mtsprg0 r4
lwz r4, loc_C0
stw r3, 0xC(r4)
mfsprg0 r3
stw r3, 0x10(r4)
stw r5, 0x14(r4)
lhz r3, 0x1A2(r4)
ori r3, r3, 2
sth r3, 0x1A2(r4)
mfcr r3
stw r3, 0x80(r4)
mflr r3
stw r3, 0x84(r4)
mfctr r3
stw r3, 0x88(r4)
mfxer r3
stw r3, 0x8C(r4)
mfsrr0 r3
stw r3, 0x198(r4)
mfsrr1 r3
stw r3, 0x19C(r4)
mr r5, r3
__DBVECTOR:
nop
mfmsr r3
ori r3, r3, 0x30
mtsrr1 r3
__OSEVSetNumber:
li r3, 0
lwz r4, loc_D4
rlwinm. r5, r5, 0,30,30
bne loc_A44
lis r5, OSDefaultExceptionHandler@ha
addi r5, r5, OSDefaultExceptionHandler@l
mtsrr0 r5
rfi
loc_A44:
clrlslwi r5, r3, 24,2
lwz r5, 0x3000(r5)
mtsrr0 r5
rfi
__OSEVEnd:
nop
OSDefaultExceptionHandler:
stw r0, 0(r4)
stw r1, 4(r4)
stw r2, 8(r4)
stmw r6, 0x18(r4)
mfspr r0, 0x391 # GQR1
stw r0, 0x1A8(r4)
mfspr r0, 0x392
stw r0, 0x1AC(r4)
mfspr r0, 0x393
stw r0, 0x1B0(r4)
mfspr r0, 0x394
stw r0, 0x1B4(r4)
mfspr r0, 0x395
stw r0, 0x1B8(r4)
mfspr r0, 0x396
stw r0, 0x1BC(r4)
mfspr r0, 0x397 # GQR7
stw r0, 0x1C0(r4)
mfdsisr r5
mfdar r6
b __OSUnhandledException
__OSPSInit ()
{
PPCMthid2 (
PPCMfhid2 () | 0x80000000 | 0x20000000 );
ICFlashInvalidate ();
__sync;
mtspr 0x390, 0 // GQR0 = 0
}
u32 __OSGetDIConfig ()
{
return dword.0xCC006024 & 0xFF;
}