boot.c
4.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*---------------------------------------------------------------------*
Copyright (C) 1998 Nintendo. (Originated by SGI)
$RCSfile: boot.c,v $
$Revision: 1.1.1.1 $
$Date: 2002/05/02 03:27:17 $
*---------------------------------------------------------------------*/
#include <ultra64.h>
#include <bstring.h>
#include "gng.h"
#include "rdramTest_data.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[];
/*
* 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;
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.
*/
rdramDiagStatus = pstatus->rdram_diag_status;
/*
* 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)
*/
if ( ( osResetType == 0 ) && (rdramDiagStatus != 0xdeadbeef) ) {
/*
* Halt the SP.
*/
__osSpSetStatus(SP_SET_HALT);
/*
* Disable interrupts, flush caches.
*/
osSetIntMask(OS_IM_NONE);
osInvalICache(_codeSegmentTextStart,
_codeSegmentTextEnd-_codeSegmentTextStart);
osInvalDCache(_codeSegmentDataStart,
_codeSegmentDataEnd-_codeSegmentDataStart);
/*
* Copy the rdramTest program from a global array into dmem.
*/
for (wordCount = 0, pTest = (unsigned int *)rdramTest_data,
pDmem = ( (unsigned int *)( PHYS_TO_K1(SP_DMEM_START) ) );
wordCount < (rdramTest_data_size >> 2); wordCount++) {
*pDmem++ = *pTest++;
}
func = (void (*)(void))( PHYS_TO_K1(SP_DMEM_START) );
osInvalICache(func, rdramTest_data_size);
func();
/* never reached */
#ifndef _FINALROM
osExit();
#endif
} else {
/*
* Save the rdram test reserved memory variables, as both osInitialize()
* Save the rdram test reserved memory variables, as both handler = osCartRomInit();
* 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.
*/
osPiRawStartDma(OS_READ, (u32)_codeSegmentRomStart, _codeSegmentStart,
_codeSegmentRomEnd-_codeSegmentRomStart);
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;
func = (void (*)(void))_codeSegmentStart;
func();
}