00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
#include "copyright.h"
00011
#include "machine.h"
00012
#include "system.h"
00013
00014
00015
00016
static char* exceptionNames[] = {
"no exception",
"syscall",
00017
"page fault/no TLB entry",
"page read only",
00018
"bus error",
"address error",
"overflow",
00019
"illegal instruction" };
00020
00021
00022
00023
00024
00025
00026
00027
static
00028
void CheckEndian()
00029 {
00030
union checkit {
00031
char charword[4];
00032
unsigned int intword;
00033 } check;
00034
00035 check.charword[0] = 1;
00036 check.charword[1] = 2;
00037 check.charword[2] = 3;
00038 check.charword[3] = 4;
00039
00040
#ifdef HOST_IS_BIG_ENDIAN
00041
ASSERT (check.intword == 0x01020304);
00042
#else
00043
ASSERT (check.intword == 0x04030201);
00044
#endif
00045
}
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 Machine::Machine(
bool debug)
00056 {
00057
int i;
00058
00059
for (i = 0; i <
NumTotalRegs; i++)
00060
registers[i] = 0;
00061
mainMemory =
new char[
MemorySize];
00062
for (i = 0; i <
MemorySize; i++)
00063
mainMemory[i] = 0;
00064
#ifdef USE_TLB
00065
tlb =
new TranslationEntry[
TLBSize];
00066
for (i = 0; i <
TLBSize; i++)
00067
tlb[i].
valid =
FALSE;
00068
pageTable = NULL;
00069
#else // use linear page table
00070
tlb = NULL;
00071
pageTable = NULL;
00072
#endif
00073
00074 singleStep = debug;
00075 CheckEndian();
00076 }
00077
00078
00079
00080
00081
00082
00083 Machine::~Machine()
00084 {
00085
delete []
mainMemory;
00086
if (
tlb != NULL)
00087
delete []
tlb;
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
void
00101 Machine::RaiseException(ExceptionType which,
int badVAddr)
00102 {
00103
DEBUG(
'm',
"Exception: %s\n", exceptionNames[which]);
00104
00105
00106
registers[
BadVAddrReg] = badVAddr;
00107
DelayedLoad(0, 0);
00108
interrupt->
setStatus(
SystemMode);
00109
ExceptionHandler(which);
00110
interrupt->
setStatus(
UserMode);
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 void Machine::Debugger()
00124 {
00125
char *buf =
new char[80];
00126
int num;
00127
00128
interrupt->
DumpState();
00129
DumpState();
00130 printf(
"%d> ",
stats->
totalTicks);
00131 fflush(stdout);
00132 fgets(buf, 80, stdin);
00133
if (sscanf(buf,
"%d", &num) == 1)
00134 runUntilTime = num;
00135
else {
00136 runUntilTime = 0;
00137
switch (*buf) {
00138
case '\n':
00139
break;
00140
00141
case 'c':
00142 singleStep =
FALSE;
00143
break;
00144
00145
case '?':
00146 printf(
"Machine commands:\n");
00147 printf(
" <return> execute one instruction\n");
00148 printf(
" <number> run until the given timer tick\n");
00149 printf(
" c run until completion\n");
00150 printf(
" ? print help message\n");
00151
break;
00152 }
00153 }
00154
delete [] buf;
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
void
00164 Machine::DumpState()
00165 {
00166
int i;
00167
00168 printf(
"Machine registers:\n");
00169
for (i = 0; i <
NumGPRegs; i++)
00170
switch (i) {
00171
case StackReg:
00172 printf(
"\tSP(%d):\t0x%x%s", i,
registers[i],
00173 ((i % 4) == 3) ?
"\n" :
"");
00174
break;
00175
00176
case RetAddrReg:
00177 printf(
"\tRA(%d):\t0x%x%s", i,
registers[i],
00178 ((i % 4) == 3) ?
"\n" :
"");
00179
break;
00180
00181
default:
00182 printf(
"\t%d:\t0x%x%s", i,
registers[i],
00183 ((i % 4) == 3) ?
"\n" :
"");
00184
break;
00185 }
00186
00187 printf(
"\tHi:\t0x%x",
registers[
HiReg]);
00188 printf(
"\tLo:\t0x%x\n",
registers[
LoReg]);
00189 printf(
"\tPC:\t0x%x",
registers[
PCReg]);
00190 printf(
"\tNextPC:\t0x%x",
registers[
NextPCReg]);
00191 printf(
"\tPrevPC:\t0x%x\n",
registers[
PrevPCReg]);
00192 printf(
"\tLoad:\t0x%x",
registers[
LoadReg]);
00193 printf(
"\tLoadV:\t0x%x\n",
registers[
LoadValueReg]);
00194 printf(
"\n");
00195 }
00196
00197
00198
00199
00200
00201
00202 int Machine::ReadRegister(
int num)
00203 {
00204
ASSERT((num >= 0) && (num <
NumTotalRegs));
00205
return registers[num];
00206 }
00207
00208 void Machine::WriteRegister(
int num,
int value)
00209 {
00210
ASSERT((num >= 0) && (num <
NumTotalRegs));
00211
00212
registers[num] = value;
00213 }
00214