boot.c 4.11 KB
#include <ultra64.h>
#ifdef __sgi__
#include <bstring.h>
#endif
#include "gng.h"

char	bootStack[STACKSIZE];

extern char _codeSegmentRomStart[];
extern char _codeSegmentRomEnd[];
extern char _codeSegmentStart[];
extern char _codeSegmentTextStart[];
extern char _codeSegmentTextEnd[];
extern char _codeSegmentDataStart[];
extern char _codeSegmentDataEnd[];
extern char _codeSegmentBssStart[];
extern char _codeSegmentBssEnd[];

#ifndef __sgi__
/* exports from libultra/nintendo/pi/pirawdma.c */
extern s32 __osPiRawStartDma(s32, u32, void *, u32);
#endif


/*
 * The boot() function MUST be the first function in this module, otherwise
 * the original boot thread (loaded at 2MB in rdram) will be unable to invoke 
 * this secondary boot procedure, which loads the program low in rdram.
 *
 * The FIRST thing the boot program does is run the rdram diagnostic, if it
 * has not been run already.  That way we minimize the amount of time we spend
 * executing instructions from rdram (the test itself runs in dmem).
 */
boot(void *arg)
{
    void (*func)(void);
    unsigned volatile int *pDmem, *pTest;
    int wordCount, rdramDiagErrors, rdramDiagStatus;
    u32 rdramDiagSasano,rdramDiagExpect,rdramDiagReaddt;
    gngstatus	*pstatus;

    /*
     * osAppNMIBuffer == 0x8000031c in locore rdram
     */
    pstatus = (gngstatus *)osAppNMIBuffer;

    /*
     * Save the rdram diagnostic status in a global variable, as it will be
     * cleared by osInitialize.
     */
		if (pstatus->rdram_diag_status != 0xdeadbeef) pstatus->rdram_diag_status=0x0;

    rdramDiagStatus = pstatus->rdram_diag_status;
    rdramDiagSasano = pstatus->rdram_diag_sasano;
    rdramDiagExpect = pstatus->rdram_diag_expect;
    rdramDiagReaddt = pstatus->rdram_diag_readdt;

    /*
     * Check to see if this is a cold reset.  If so, load the
     * rdram diagnostic into dmem and jump to it; when the rdram diagnostic
     * completes, it will reload, then invoke this boot function again.
     *
     * osResetType will be set to 1 whenever an nmi is induced by the reset 
     * button.
     *
     * (we don't want to run the memory test after an nmi interrupt brings 
     * us here)
     */
/*DLE*/    if(0) {
//DLE if ( ( osResetType == 0 ) && (rdramDiagStatus != 0xdeadbeef) ) {
    /* deadbeefを初期化しないと、RDRAMのテストにいかない可能性があるので
       testDriver.cの一番最初の部分でステータスをクリアする。 sasano */
	/*
	 * Halt the SP.
	 */
	__osSpSetStatus(SP_SET_HALT);

	/*
	 * Disable interrupts, flush caches.
	 */
	osSetIntMask(OS_IM_NONE);

	osInvalICache(_codeSegmentTextStart,
	    _codeSegmentTextEnd-_codeSegmentTextStart);
	osInvalDCache(_codeSegmentDataStart,
	    _codeSegmentDataEnd-_codeSegmentDataStart);
#ifndef _FINALROM
	osExit();
#endif
    } else {
	/*
	 * Save the rdram test reserved memory variables, as both osInitialize()
	 * and bzero() below will clobber the reserved memory locations used 
	 * by the rdram test.
	 */
	rdramDiagErrors = pstatus->rdram_diag_errors;
    }
    
    osInitialize();

    /*
     * Load in the code segment.  The "boot" portion of the code segment
     * will load in the texture segment and the static segment.
     */
#ifdef __sgi__
    osPiRawStartDma(OS_READ, (u32)_codeSegmentRomStart, _codeSegmentStart, 
		   _codeSegmentRomEnd-_codeSegmentRomStart);
#else
    __osPiRawStartDma(OS_READ, (u32)_codeSegmentRomStart, _codeSegmentStart,
		   _codeSegmentRomEnd-_codeSegmentRomStart);
#endif
    while(osPiGetStatus() & PI_STATUS_DMA_BUSY);

    osInvalICache(_codeSegmentTextStart,
		  _codeSegmentTextEnd-_codeSegmentTextStart);
    osInvalDCache(_codeSegmentDataStart,
		  _codeSegmentDataEnd-_codeSegmentDataStart);

    bzero(_codeSegmentBssStart, _codeSegmentBssEnd-_codeSegmentBssStart);

    /*
     * Restore the reserved memory locations used by the rdram test, so that
     * they can be queried by functions in the codeSegment.
     */
    pstatus->rdram_diag_status = rdramDiagStatus;
    pstatus->rdram_diag_errors = rdramDiagErrors;
		pstatus->rdram_diag_sasano = rdramDiagSasano;
		pstatus->rdram_diag_expect = rdramDiagExpect;
		pstatus->rdram_diag_readdt = rdramDiagReaddt;

    func = (void (*)(void))_codeSegmentStart;
    func();
}