#include <machine.h>
Public Methods | |
| Machine (bool debug) | |
| ~Machine () | |
| void | Run () |
| int | ReadRegister (int num) |
| void | WriteRegister (int num, int value) |
| void | OneInstruction (Instruction *instr) |
| void | DelayedLoad (int nextReg, int nextVal) |
| bool | ReadMem (int addr, int size, int *value) |
| bool | WriteMem (int addr, int size, int value) |
| ExceptionType | Translate (int virtAddr, int *physAddr, int size, bool writing) |
| void | RaiseException (ExceptionType which, int badVAddr) |
| void | Debugger () |
| void | DumpState () |
Public Attributes | |
| char * | mainMemory |
| int | registers [NumTotalRegs] |
| TranslationEntry * | tlb |
| TranslationEntry * | pageTable |
| unsigned int | pageTableSize |
Private Attributes | |
| bool | singleStep |
| int | runUntilTime |
|
|
Definition at line 55 of file machine.cc. References CheckEndian, FALSE, mainMemory, MemorySize, NULL, NumTotalRegs, pageTable, registers, singleStep, tlb, TLBSize, and TranslationEntry::valid.
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 }
|
|
|
Definition at line 83 of file machine.cc. References mainMemory, NULL, and tlb.
00084 {
00085 delete [] mainMemory;
00086 if (tlb != NULL)
00087 delete [] tlb;
00088 }
|
|
|
Definition at line 123 of file machine.cc. References DumpState, FALSE, runUntilTime, and singleStep. Referenced by Run.
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 }
|
|
||||||||||||
|
Definition at line 576 of file mipssim.cc. References LoadReg, LoadValueReg, and registers. Referenced by OneInstruction, and RaiseException.
00577 {
00578 registers[registers[LoadReg]] = registers[LoadValueReg];
00579 registers[LoadReg] = nextReg;
00580 registers[LoadValueReg] = nextValue;
00581 registers[0] = 0; // and always make sure R0 stays zero.
00582 }
|
|
|
Definition at line 164 of file machine.cc. References HiReg, LoadReg, LoadValueReg, LoReg, NextPCReg, NumGPRegs, PCReg, PrevPCReg, registers, RetAddrReg, and StackReg. Referenced by Debugger.
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 }
|
|
|
Definition at line 94 of file mipssim.cc. References AddressErrorException, OpString::args, ASSERT, DEBUG, DebugIsEnabled, Instruction::Decode, DelayedLoad, Instruction::extra, FALSE, HiReg, IllegalInstrException, IndexToAddr, LoadReg, LoadValueReg, LoReg, MaxOpcode, Mult, NextPCReg, OP_ADD, OP_ADDI, OP_ADDIU, OP_ADDU, OP_AND, OP_ANDI, OP_BEQ, OP_BGEZ, OP_BGEZAL, OP_BGTZ, OP_BLEZ, OP_BLTZ, OP_BLTZAL, OP_BNE, OP_DIV, OP_DIVU, OP_J, OP_JAL, OP_JALR, OP_JR, OP_LB, OP_LBU, OP_LH, OP_LHU, OP_LUI, OP_LW, OP_LWL, OP_LWR, OP_MFHI, OP_MFLO, OP_MTHI, OP_MTLO, OP_MULT, OP_MULTU, OP_NOR, OP_OR, OP_ORI, OP_RES, OP_SB, OP_SH, OP_SLL, OP_SLLV, OP_SLT, OP_SLTI, OP_SLTIU, OP_SLTU, OP_SRA, OP_SRAV, OP_SRL, OP_SRLV, OP_SUB, OP_SUBU, OP_SW, OP_SWL, OP_SWR, OP_SYSCALL, OP_UNIMP, OP_XOR, OP_XORI, Instruction::opCode, OverflowException, PCReg, PrevPCReg, R31, RaiseException, Instruction::rd, registers, Instruction::rs, rs, Instruction::rt, rt, SIGN_BIT, OpString::string, SyscallException, TRUE, TypeToReg, and Instruction::value. Referenced by Run.
00095 {
00096 int raw;
00097 int nextLoadReg = 0;
00098 int nextLoadValue = 0; // record delayed load operation, to apply
00099 // in the future
00100
00101 // Fetch instruction
00102 if (!machine->ReadMem(registers[PCReg], 4, &raw))
00103 return; // exception occurred
00104 instr->value = raw;
00105 instr->Decode();
00106
00107 if (DebugIsEnabled('m')) {
00108 struct OpString *str = &opStrings[instr->opCode];
00109
00110 ASSERT(instr->opCode <= MaxOpcode);
00111 printf("At PC = 0x%x: ", registers[PCReg]);
00112 printf(str->string, TypeToReg(str->args[0], instr),
00113 TypeToReg(str->args[1], instr), TypeToReg(str->args[2], instr));
00114 printf("\n");
00115 }
00116
00117 // Compute next pc, but don't install in case there's an error or branch.
00118 int pcAfter = registers[NextPCReg] + 4;
00119 int sum, diff, tmp, value;
00120 unsigned int rs, rt, imm;
00121
00122 // Execute the instruction (cf. Kane's book)
00123 switch (instr->opCode) {
00124
00125 case OP_ADD:
00126 sum = registers[instr->rs] + registers[instr->rt];
00127 if (!((registers[instr->rs] ^ registers[instr->rt]) & SIGN_BIT) &&
00128 ((registers[instr->rs] ^ sum) & SIGN_BIT)) {
00129 RaiseException(OverflowException, 0);
00130 return;
00131 }
00132 registers[instr->rd] = sum;
00133 break;
00134
00135 case OP_ADDI:
00136 sum = registers[instr->rs] + instr->extra;
00137 if (!((registers[instr->rs] ^ instr->extra) & SIGN_BIT) &&
00138 ((instr->extra ^ sum) & SIGN_BIT)) {
00139 RaiseException(OverflowException, 0);
00140 return;
00141 }
00142 registers[instr->rt] = sum;
00143 break;
00144
00145 case OP_ADDIU:
00146 registers[instr->rt] = registers[instr->rs] + instr->extra;
00147 break;
00148
00149 case OP_ADDU:
00150 registers[instr->rd] = registers[instr->rs] + registers[instr->rt];
00151 break;
00152
00153 case OP_AND:
00154 registers[instr->rd] = registers[instr->rs] & registers[instr->rt];
00155 break;
00156
00157 case OP_ANDI:
00158 registers[instr->rt] = registers[instr->rs] & (instr->extra & 0xffff);
00159 break;
00160
00161 case OP_BEQ:
00162 if (registers[instr->rs] == registers[instr->rt])
00163 pcAfter = registers[NextPCReg] + IndexToAddr(instr->extra);
00164 break;
00165
00166 case OP_BGEZAL:
00167 registers[R31] = registers[NextPCReg] + 4;
00168 case OP_BGEZ:
00169 if (!(registers[instr->rs] & SIGN_BIT))
00170 pcAfter = registers[NextPCReg] + IndexToAddr(instr->extra);
00171 break;
00172
00173 case OP_BGTZ:
00174 if (registers[instr->rs] > 0)
00175 pcAfter = registers[NextPCReg] + IndexToAddr(instr->extra);
00176 break;
00177
00178 case OP_BLEZ:
00179 if (registers[instr->rs] <= 0)
00180 pcAfter = registers[NextPCReg] + IndexToAddr(instr->extra);
00181 break;
00182
00183 case OP_BLTZAL:
00184 registers[R31] = registers[NextPCReg] + 4;
00185 case OP_BLTZ:
00186 if (registers[instr->rs] & SIGN_BIT)
00187 pcAfter = registers[NextPCReg] + IndexToAddr(instr->extra);
00188 break;
00189
00190 case OP_BNE:
00191 if (registers[instr->rs] != registers[instr->rt])
00192 pcAfter = registers[NextPCReg] + IndexToAddr(instr->extra);
00193 break;
00194
00195 case OP_DIV:
00196 if (registers[instr->rt] == 0) {
00197 registers[LoReg] = 0;
00198 registers[HiReg] = 0;
00199 } else {
00200 registers[LoReg] = registers[instr->rs] / registers[instr->rt];
00201 registers[HiReg] = registers[instr->rs] % registers[instr->rt];
00202 }
00203 break;
00204
00205 case OP_DIVU:
00206 rs = (unsigned int) registers[instr->rs];
00207 rt = (unsigned int) registers[instr->rt];
00208 if (rt == 0) {
00209 registers[LoReg] = 0;
00210 registers[HiReg] = 0;
00211 } else {
00212 tmp = rs / rt;
00213 registers[LoReg] = (int) tmp;
00214 tmp = rs % rt;
00215 registers[HiReg] = (int) tmp;
00216 }
00217 break;
00218
00219 case OP_JAL:
00220 registers[R31] = registers[NextPCReg] + 4;
00221 case OP_J:
00222 pcAfter = (pcAfter & 0xf0000000) | IndexToAddr(instr->extra);
00223 break;
00224
00225 case OP_JALR:
00226 registers[instr->rd] = registers[NextPCReg] + 4;
00227 case OP_JR:
00228 pcAfter = registers[instr->rs];
00229 break;
00230
00231 case OP_LB:
00232 case OP_LBU:
00233 tmp = registers[instr->rs] + instr->extra;
00234 if (!machine->ReadMem(tmp, 1, &value))
00235 return;
00236
00237 if ((value & 0x80) && (instr->opCode == OP_LB))
00238 value |= 0xffffff00;
00239 else
00240 value &= 0xff;
00241 nextLoadReg = instr->rt;
00242 nextLoadValue = value;
00243 break;
00244
00245 case OP_LH:
00246 case OP_LHU:
00247 tmp = registers[instr->rs] + instr->extra;
00248 if (tmp & 0x1) {
00249 RaiseException(AddressErrorException, tmp);
00250 return;
00251 }
00252 if (!machine->ReadMem(tmp, 2, &value))
00253 return;
00254
00255 if ((value & 0x8000) && (instr->opCode == OP_LH))
00256 value |= 0xffff0000;
00257 else
00258 value &= 0xffff;
00259 nextLoadReg = instr->rt;
00260 nextLoadValue = value;
00261 break;
00262
00263 case OP_LUI:
00264 DEBUG('m', "Executing: LUI r%d,%d\n", instr->rt, instr->extra);
00265 registers[instr->rt] = instr->extra << 16;
00266 break;
00267
00268 case OP_LW:
00269 tmp = registers[instr->rs] + instr->extra;
00270 if (tmp & 0x3) {
00271 RaiseException(AddressErrorException, tmp);
00272 return;
00273 }
00274 if (!machine->ReadMem(tmp, 4, &value))
00275 return;
00276 nextLoadReg = instr->rt;
00277 nextLoadValue = value;
00278 break;
00279
00280 case OP_LWL:
00281 tmp = registers[instr->rs] + instr->extra;
00282
00283 // ReadMem assumes all 4 byte requests are aligned on an even
00284 // word boundary. Also, the little endian/big endian swap code would
00285 // fail (I think) if the other cases are ever exercised.
00286 ASSERT((tmp & 0x3) == 0);
00287
00288 if (!machine->ReadMem(tmp, 4, &value))
00289 return;
00290 if (registers[LoadReg] == instr->rt)
00291 nextLoadValue = registers[LoadValueReg];
00292 else
00293 nextLoadValue = registers[instr->rt];
00294 switch (tmp & 0x3) {
00295 case 0:
00296 nextLoadValue = value;
00297 break;
00298 case 1:
00299 nextLoadValue = (nextLoadValue & 0xff) | (value << 8);
00300 break;
00301 case 2:
00302 nextLoadValue = (nextLoadValue & 0xffff) | (value << 16);
00303 break;
00304 case 3:
00305 nextLoadValue = (nextLoadValue & 0xffffff) | (value << 24);
00306 break;
00307 }
00308 nextLoadReg = instr->rt;
00309 break;
00310
00311 case OP_LWR:
00312 tmp = registers[instr->rs] + instr->extra;
00313
00314 // ReadMem assumes all 4 byte requests are aligned on an even
00315 // word boundary. Also, the little endian/big endian swap code would
00316 // fail (I think) if the other cases are ever exercised.
00317 ASSERT((tmp & 0x3) == 0);
00318
00319 if (!machine->ReadMem(tmp, 4, &value))
00320 return;
00321 if (registers[LoadReg] == instr->rt)
00322 nextLoadValue = registers[LoadValueReg];
00323 else
00324 nextLoadValue = registers[instr->rt];
00325 switch (tmp & 0x3) {
00326 case 0:
00327 nextLoadValue = (nextLoadValue & 0xffffff00) |
00328 ((value >> 24) & 0xff);
00329 break;
00330 case 1:
00331 nextLoadValue = (nextLoadValue & 0xffff0000) |
00332 ((value >> 16) & 0xffff);
00333 break;
00334 case 2:
00335 nextLoadValue = (nextLoadValue & 0xff000000)
00336 | ((value >> 8) & 0xffffff);
00337 break;
00338 case 3:
00339 nextLoadValue = value;
00340 break;
00341 }
00342 nextLoadReg = instr->rt;
00343 break;
00344
00345 case OP_MFHI:
00346 registers[instr->rd] = registers[HiReg];
00347 break;
00348
00349 case OP_MFLO:
00350 registers[instr->rd] = registers[LoReg];
00351 break;
00352
00353 case OP_MTHI:
00354 registers[HiReg] = registers[instr->rs];
00355 break;
00356
00357 case OP_MTLO:
00358 registers[LoReg] = registers[instr->rs];
00359 break;
00360
00361 case OP_MULT:
00362 Mult(registers[instr->rs], registers[instr->rt], TRUE,
00363 ®isters[HiReg], ®isters[LoReg]);
00364 break;
00365
00366 case OP_MULTU:
00367 Mult(registers[instr->rs], registers[instr->rt], FALSE,
00368 ®isters[HiReg], ®isters[LoReg]);
00369 break;
00370
00371 case OP_NOR:
00372 registers[instr->rd] = ~(registers[instr->rs] | registers[instr->rt]);
00373 break;
00374
00375 case OP_OR:
00376 registers[instr->rd] = registers[instr->rs] | registers[instr->rs];
00377 break;
00378
00379 case OP_ORI:
00380 registers[instr->rt] = registers[instr->rs] | (instr->extra & 0xffff);
00381 break;
00382
00383 case OP_SB:
00384 if (!machine->WriteMem((unsigned)
00385 (registers[instr->rs] + instr->extra), 1, registers[instr->rt]))
00386 return;
00387 break;
00388
00389 case OP_SH:
00390 if (!machine->WriteMem((unsigned)
00391 (registers[instr->rs] + instr->extra), 2, registers[instr->rt]))
00392 return;
00393 break;
00394
00395 case OP_SLL:
00396 registers[instr->rd] = registers[instr->rt] << instr->extra;
00397 break;
00398
00399 case OP_SLLV:
00400 registers[instr->rd] = registers[instr->rt] <<
00401 (registers[instr->rs] & 0x1f);
00402 break;
00403
00404 case OP_SLT:
00405 if (registers[instr->rs] < registers[instr->rt])
00406 registers[instr->rd] = 1;
00407 else
00408 registers[instr->rd] = 0;
00409 break;
00410
00411 case OP_SLTI:
00412 if (registers[instr->rs] < instr->extra)
00413 registers[instr->rt] = 1;
00414 else
00415 registers[instr->rt] = 0;
00416 break;
00417
00418 case OP_SLTIU:
00419 rs = registers[instr->rs];
00420 imm = instr->extra;
00421 if (rs < imm)
00422 registers[instr->rt] = 1;
00423 else
00424 registers[instr->rt] = 0;
00425 break;
00426
00427 case OP_SLTU:
00428 rs = registers[instr->rs];
00429 rt = registers[instr->rt];
00430 if (rs < rt)
00431 registers[instr->rd] = 1;
00432 else
00433 registers[instr->rd] = 0;
00434 break;
00435
00436 case OP_SRA:
00437 registers[instr->rd] = registers[instr->rt] >> instr->extra;
00438 break;
00439
00440 case OP_SRAV:
00441 registers[instr->rd] = registers[instr->rt] >>
00442 (registers[instr->rs] & 0x1f);
00443 break;
00444
00445 case OP_SRL:
00446 tmp = registers[instr->rt];
00447 tmp >>= instr->extra;
00448 registers[instr->rd] = tmp;
00449 break;
00450
00451 case OP_SRLV:
00452 tmp = registers[instr->rt];
00453 tmp >>= (registers[instr->rs] & 0x1f);
00454 registers[instr->rd] = tmp;
00455 break;
00456
00457 case OP_SUB:
00458 diff = registers[instr->rs] - registers[instr->rt];
00459 if (((registers[instr->rs] ^ registers[instr->rt]) & SIGN_BIT) &&
00460 ((registers[instr->rs] ^ diff) & SIGN_BIT)) {
00461 RaiseException(OverflowException, 0);
00462 return;
00463 }
00464 registers[instr->rd] = diff;
00465 break;
00466
00467 case OP_SUBU:
00468 registers[instr->rd] = registers[instr->rs] - registers[instr->rt];
00469 break;
00470
00471 case OP_SW:
00472 if (!machine->WriteMem((unsigned)
00473 (registers[instr->rs] + instr->extra), 4, registers[instr->rt]))
00474 return;
00475 break;
00476
00477 case OP_SWL:
00478 tmp = registers[instr->rs] + instr->extra;
00479
00480 // The little endian/big endian swap code would
00481 // fail (I think) if the other cases are ever exercised.
00482 ASSERT((tmp & 0x3) == 0);
00483
00484 if (!machine->ReadMem((tmp & ~0x3), 4, &value))
00485 return;
00486 switch (tmp & 0x3) {
00487 case 0:
00488 value = registers[instr->rt];
00489 break;
00490 case 1:
00491 value = (value & 0xff000000) | ((registers[instr->rt] >> 8) &
00492 0xffffff);
00493 break;
00494 case 2:
00495 value = (value & 0xffff0000) | ((registers[instr->rt] >> 16) &
00496 0xffff);
00497 break;
00498 case 3:
00499 value = (value & 0xffffff00) | ((registers[instr->rt] >> 24) &
00500 0xff);
00501 break;
00502 }
00503 if (!machine->WriteMem((tmp & ~0x3), 4, value))
00504 return;
00505 break;
00506
00507 case OP_SWR:
00508 tmp = registers[instr->rs] + instr->extra;
00509
00510 // The little endian/big endian swap code would
00511 // fail (I think) if the other cases are ever exercised.
00512 ASSERT((tmp & 0x3) == 0);
00513
00514 if (!machine->ReadMem((tmp & ~0x3), 4, &value))
00515 return;
00516 switch (tmp & 0x3) {
00517 case 0:
00518 value = (value & 0xffffff) | (registers[instr->rt] << 24);
00519 break;
00520 case 1:
00521 value = (value & 0xffff) | (registers[instr->rt] << 16);
00522 break;
00523 case 2:
00524 value = (value & 0xff) | (registers[instr->rt] << 8);
00525 break;
00526 case 3:
00527 value = registers[instr->rt];
00528 break;
00529 }
00530 if (!machine->WriteMem((tmp & ~0x3), 4, value))
00531 return;
00532 break;
00533
00534 case OP_SYSCALL:
00535 RaiseException(SyscallException, 0);
00536 return;
00537
00538 case OP_XOR:
00539 registers[instr->rd] = registers[instr->rs] ^ registers[instr->rt];
00540 break;
00541
00542 case OP_XORI:
00543 registers[instr->rt] = registers[instr->rs] ^ (instr->extra & 0xffff);
00544 break;
00545
00546 case OP_RES:
00547 case OP_UNIMP:
00548 RaiseException(IllegalInstrException, 0);
00549 return;
00550
00551 default:
00552 ASSERT(FALSE);
00553 }
00554
00555 // Now we have successfully executed the instruction.
00556
00557 // Do any delayed load operation
00558 DelayedLoad(nextLoadReg, nextLoadValue);
00559
00560 // Advance program counters.
00561 registers[PrevPCReg] = registers[PCReg]; // for debugging, in case we
00562 // are jumping into lala-land
00563 registers[PCReg] = registers[NextPCReg];
00564 registers[NextPCReg] = pcAfter;
00565 }
|
|
||||||||||||
|
Definition at line 101 of file machine.cc. References BadVAddrReg, DEBUG, DelayedLoad, ExceptionHandler, exceptionNames, ExceptionType, registers, SystemMode, and UserMode. Referenced by OneInstruction.
00102 {
00103 DEBUG('m', "Exception: %s\n", exceptionNames[which]);
00104
00105 // ASSERT(interrupt->getStatus() == UserMode);
00106 registers[BadVAddrReg] = badVAddr;
00107 DelayedLoad(0, 0); // finish anything in progress
00108 interrupt->setStatus(SystemMode);
00109 ExceptionHandler(which); // interrupts are enabled at this point
00110 interrupt->setStatus(UserMode);
00111 }
|
|
||||||||||||||||
|
Definition at line 88 of file translate.cc. References ASSERT, DEBUG, ExceptionType, FALSE, NoException, ShortToHost, Translate, and WordToHost.
00089 {
00090 int data;
00091 ExceptionType exception;
00092 int physicalAddress;
00093
00094 DEBUG('a', "Reading VA 0x%x, size %d\n", addr, size);
00095
00096 exception = Translate(addr, &physicalAddress, size, FALSE);
00097 if (exception != NoException) {
00098 machine->RaiseException(exception, addr);
00099 return FALSE;
00100 }
00101 switch (size) {
00102 case 1:
00103 data = machine->mainMemory[physicalAddress];
00104 *value = data;
00105 break;
00106
00107 case 2:
00108 data = *(unsigned short *) &machine->mainMemory[physicalAddress];
00109 *value = ShortToHost(data);
00110 break;
00111
00112 case 4:
00113 data = *(unsigned int *) &machine->mainMemory[physicalAddress];
00114 *value = WordToHost(data);
00115 break;
00116
00117 default: ASSERT(FALSE);
00118 }
00119
00120 DEBUG('a', "\tvalue read = %8.8x\n", *value);
00121 return (TRUE);
00122 }
|
|
|
Definition at line 202 of file machine.cc. References ASSERT, NumTotalRegs, and registers.
00203 {
00204 ASSERT((num >= 0) && (num < NumTotalRegs));
00205 return registers[num];
00206 }
|
|
|
Definition at line 31 of file mipssim.cc. References Debugger, DebugIsEnabled, OneInstruction, runUntilTime, singleStep, and UserMode.
00032 {
00033 Instruction *instr = new Instruction; // storage for decoded instruction
00034
00035 if(DebugIsEnabled('m'))
00036 printf("Starting thread \"%s\" at time %d\n",
00037 currentThread->getName(), stats->totalTicks);
00038 interrupt->setStatus(UserMode);
00039 for (;;) {
00040 OneInstruction(instr);
00041 interrupt->OneTick();
00042 if (singleStep && (runUntilTime <= stats->totalTicks))
00043 Debugger();
00044 }
00045 }
|
|
||||||||||||||||||||
|
Definition at line 187 of file translate.cc. References AddressErrorException, ASSERT, BusErrorException, DEBUG, TranslationEntry::dirty, MemorySize, NoException, NULL, NumPhysPages, PageFaultException, PageSize, pageTable, pageTableSize, TranslationEntry::physicalPage, TranslationEntry::readOnly, ReadOnlyException, tlb, TLBSize, TRUE, TranslationEntry::use, TranslationEntry::valid, and TranslationEntry::virtualPage. Referenced by ReadMem, and WriteMem.
00188 {
00189 int i;
00190 unsigned int vpn, offset;
00191 TranslationEntry *entry;
00192 unsigned int pageFrame;
00193
00194 DEBUG('a', "\tTranslate 0x%x, %s: ", virtAddr, writing ? "write" : "read");
00195
00196 // check for alignment errors
00197 if (((size == 4) && (virtAddr & 0x3)) || ((size == 2) && (virtAddr & 0x1))){
00198 DEBUG('a', "alignment problem at %d, size %d!\n", virtAddr, size);
00199 return AddressErrorException;
00200 }
00201
00202 // we must have either a TLB or a page table, but not both!
00203 ASSERT(tlb == NULL || pageTable == NULL);
00204 ASSERT(tlb != NULL || pageTable != NULL);
00205
00206 // calculate the virtual page number, and offset within the page,
00207 // from the virtual address
00208 vpn = (unsigned) virtAddr / PageSize;
00209 offset = (unsigned) virtAddr % PageSize;
00210
00211 if (tlb == NULL) { // => page table => vpn is index into table
00212 if (vpn >= pageTableSize) {
00213 DEBUG('a', "virtual page # %d too large for page table size %d!\n",
00214 virtAddr, pageTableSize);
00215 return AddressErrorException;
00216 } else if (!pageTable[vpn].valid) {
00217 DEBUG('a', "virtual page # %d too large for page table size %d!\n",
00218 virtAddr, pageTableSize);
00219 return PageFaultException;
00220 }
00221 entry = &pageTable[vpn];
00222 } else {
00223 for (entry = NULL, i = 0; i < TLBSize; i++)
00224 if (tlb[i].valid && ((unsigned) tlb[i].virtualPage == vpn)) {
00225 entry = &tlb[i]; // FOUND!
00226 break;
00227 }
00228 if (entry == NULL) { // not found
00229 DEBUG('a', "*** no valid TLB entry found for this virtual page!\n");
00230 return PageFaultException; // really, this is a TLB fault,
00231 // the page may be in memory,
00232 // but not in the TLB
00233 }
00234 }
00235
00236 if (entry->readOnly && writing) { // trying to write to a read-only page
00237 DEBUG('a', "%d mapped read-only at %d in TLB!\n", virtAddr, i);
00238 return ReadOnlyException;
00239 }
00240 pageFrame = entry->physicalPage;
00241
00242 // if the pageFrame is too big, there is something really wrong!
00243 // An invalid translation was loaded into the page table or TLB.
00244 if (pageFrame >= NumPhysPages) {
00245 DEBUG('a', "*** frame %d > %d!\n", pageFrame, NumPhysPages);
00246 return BusErrorException;
00247 }
00248 entry->use = TRUE; // set the use, dirty bits
00249 if (writing)
00250 entry->dirty = TRUE;
00251 *physAddr = pageFrame * PageSize + offset;
00252 ASSERT((*physAddr >= 0) && ((*physAddr + size) <= MemorySize));
00253 DEBUG('a', "phys addr = 0x%x\n", *physAddr);
00254 return NoException;
00255 }
|
|
||||||||||||||||
|
Definition at line 138 of file translate.cc. References ASSERT, DEBUG, ExceptionType, FALSE, NoException, ShortToMachine, Translate, TRUE, and WordToMachine.
00139 {
00140 ExceptionType exception;
00141 int physicalAddress;
00142
00143 DEBUG('a', "Writing VA 0x%x, size %d, value 0x%x\n", addr, size, value);
00144
00145 exception = Translate(addr, &physicalAddress, size, TRUE);
00146 if (exception != NoException) {
00147 machine->RaiseException(exception, addr);
00148 return FALSE;
00149 }
00150 switch (size) {
00151 case 1:
00152 machine->mainMemory[physicalAddress] = (unsigned char) (value & 0xff);
00153 break;
00154
00155 case 2:
00156 *(unsigned short *) &machine->mainMemory[physicalAddress]
00157 = ShortToMachine((unsigned short) (value & 0xffff));
00158 break;
00159
00160 case 4:
00161 *(unsigned int *) &machine->mainMemory[physicalAddress]
00162 = WordToMachine((unsigned int) value);
00163 break;
00164
00165 default: ASSERT(FALSE);
00166 }
00167
00168 return TRUE;
00169 }
|
|
||||||||||||
|
Definition at line 208 of file machine.cc. References ASSERT, NumTotalRegs, and registers.
00209 {
00210 ASSERT((num >= 0) && (num < NumTotalRegs));
00211 // DEBUG('m', "WriteRegister %d, value %d\n", num, value);
00212 registers[num] = value;
00213 }
|
|
|
|
|
|
|
|
|
Definition at line 183 of file machine.h. Referenced by Translate. |
|
|
Definition at line 158 of file machine.h. Referenced by DelayedLoad, DumpState, Machine, OneInstruction, RaiseException, ReadRegister, and WriteRegister. |
|
|
|
|
|
|
|
|
|
1.2.14 written by Dimitri van Heesch,
© 1997-2002