Initial version
This commit is contained in:
commit
6f405265a5
102 changed files with 14486 additions and 0 deletions
239
code/machine/machine.h
Normal file
239
code/machine/machine.h
Normal file
|
@ -0,0 +1,239 @@
|
|||
// machine.h
|
||||
// Data structures for simulating the execution of user programs
|
||||
// running on top of Nachos.
|
||||
//
|
||||
// User programs are loaded into "mainMemory"; to Nachos,
|
||||
// this looks just like an array of bytes. Of course, the Nachos
|
||||
// kernel is in memory too -- but as in most machines these days,
|
||||
// the kernel is loaded into a separate memory region from user
|
||||
// programs, and accesses to kernel memory are not translated or paged.
|
||||
//
|
||||
// In Nachos, user programs are executed one instruction at a time,
|
||||
// by the simulator. Each memory reference is translated, checked
|
||||
// for errors, etc.
|
||||
//
|
||||
// DO NOT CHANGE -- part of the machine emulation
|
||||
//
|
||||
// Copyright (c) 1992-1993 The Regents of the University of California.
|
||||
// All rights reserved. See copyright.h for copyright notice and limitation
|
||||
// of liability and disclaimer of warranty provisions.
|
||||
|
||||
#ifndef MACHINE_H
|
||||
#define MACHINE_H
|
||||
|
||||
#include "copyright.h"
|
||||
#include "utility.h"
|
||||
#include "translate.h"
|
||||
#include "disk.h"
|
||||
|
||||
// Definitions related to the size, and format of user memory
|
||||
|
||||
#define PageSize SectorSize // set the page size equal to
|
||||
// the disk sector size, for
|
||||
// simplicity
|
||||
|
||||
#define NumPhysPages 64 // Increase this as necessary!
|
||||
#define MemorySize (NumPhysPages * PageSize)
|
||||
#define TLBSize 4 // if there is a TLB, make it small
|
||||
|
||||
enum ExceptionType { NoException, // Everything ok!
|
||||
SyscallException, // A program executed a system call.
|
||||
PageFaultException, // No valid translation found
|
||||
ReadOnlyException, // Write attempted to page marked
|
||||
// "read-only"
|
||||
BusErrorException, // Translation resulted in an
|
||||
// invalid physical address
|
||||
AddressErrorException, // Unaligned reference or one that
|
||||
// was beyond the end of the
|
||||
// address space
|
||||
OverflowException, // Integer overflow in add or sub.
|
||||
IllegalInstrException, // Unimplemented or reserved instr.
|
||||
|
||||
NumExceptionTypes
|
||||
};
|
||||
|
||||
// User program CPU state. The full set of MIPS registers, plus a few
|
||||
// more because we need to be able to start/stop a user program between
|
||||
// any two instructions (thus we need to keep track of things like load
|
||||
// delay slots, etc.)
|
||||
|
||||
#define StackReg 29 // User's stack pointer
|
||||
#define RetAddrReg 31 // Holds return address for procedure calls
|
||||
#define NumGPRegs 32 // 32 general purpose registers on MIPS
|
||||
#define HiReg 32 // Double register to hold multiply result
|
||||
#define LoReg 33
|
||||
#define PCReg 34 // Current program counter
|
||||
#define NextPCReg 35 // Next program counter (for branch delay)
|
||||
#define PrevPCReg 36 // Previous program counter (for debugging)
|
||||
#define LoadReg 37 // The register target of a delayed load.
|
||||
#define LoadValueReg 38 // The value to be loaded by a delayed load.
|
||||
#define BadVAddrReg 39 // The failing virtual address on an exception
|
||||
|
||||
#define NumTotalRegs 40
|
||||
|
||||
// The following class defines an instruction, represented in both
|
||||
// undecoded binary form
|
||||
// decoded to identify
|
||||
// operation to do
|
||||
// registers to act on
|
||||
// any immediate operand value
|
||||
|
||||
class Instruction {
|
||||
public:
|
||||
void Decode(); // decode the binary representation of the instruction
|
||||
|
||||
unsigned int value; // binary representation of the instruction
|
||||
|
||||
// Type of instruction. This is NOT the same as the
|
||||
// opcode field from the instruction: see defs in mips.h
|
||||
unsigned char opCode;
|
||||
// Three registers from instruction.
|
||||
unsigned char rs, rt, rd;
|
||||
// Immediate or target or shamt field or offset.
|
||||
// Immediates are sign-extended.
|
||||
unsigned int extra;
|
||||
};
|
||||
|
||||
// The following class defines the simulated host workstation hardware, as
|
||||
// seen by user programs -- the CPU registers, main memory, etc.
|
||||
// User programs shouldn't be able to tell that they are running on our
|
||||
// simulator or on the real hardware, except
|
||||
// we don't support floating point instructions
|
||||
// the system call interface to Nachos is not the same as UNIX
|
||||
// (10 system calls in Nachos vs. 200 in UNIX!)
|
||||
// If we were to implement more of the UNIX system calls, we ought to be
|
||||
// able to run Nachos on top of Nachos!
|
||||
//
|
||||
// The procedures in this class are defined in machine.cc, mipssim.cc, and
|
||||
// translate.cc.
|
||||
|
||||
class Machine:public dontcopythis {
|
||||
public:
|
||||
Machine(bool debug); // Initialize the simulation of the hardware
|
||||
// for running user programs
|
||||
~Machine(); // De-allocate the data structures
|
||||
|
||||
// Routines callable by the Nachos kernel
|
||||
void Run(); // Run a user program
|
||||
|
||||
int ReadRegister(int num); // read the contents of a CPU register
|
||||
|
||||
void WriteRegister(int num, int value);
|
||||
// store a value into a CPU register
|
||||
|
||||
|
||||
// Routines internal to the machine simulation -- DO NOT call these
|
||||
|
||||
void OneInstruction(Instruction *instr);
|
||||
// Run one instruction of a user program.
|
||||
void DelayedLoad(int nextReg, int nextVal);
|
||||
// Do a pending delayed load (modifying a reg)
|
||||
|
||||
bool ReadMem(int addr, int size, int* value);
|
||||
bool ReadMem(int addr, int size, int* value, bool debug);
|
||||
bool WriteMem(int addr, int size, int value);
|
||||
// Read or write 1, 2, or 4 bytes of virtual
|
||||
// memory (at addr). Return FALSE if a
|
||||
// correct translation couldn't be found.
|
||||
|
||||
ExceptionType Translate(int virtAddr, int* physAddr, int size, bool writing, bool debug);
|
||||
// Translate an address, and check for
|
||||
// alignment. Set the use and dirty bits in
|
||||
// the translation entry appropriately,
|
||||
// and return an exception code if the
|
||||
// translation couldn't be completed.
|
||||
|
||||
void RaiseException(ExceptionType which, int badVAddr);
|
||||
// Trap to the Nachos kernel, because of a
|
||||
// system call or other exception.
|
||||
|
||||
void Debugger(); // invoke the user program debugger
|
||||
void DumpState(); // print the user CPU and memory state
|
||||
void DumpMem(const char *name); // Draw the memory state
|
||||
void DumpReg(FILE *output, int val, const char *name, const char *color,
|
||||
int ptr_x, int ptr_y, unsigned virtual_x,
|
||||
unsigned y, unsigned blocksize);
|
||||
// Dump a register
|
||||
void DumpRegs(FILE *output, int ptr_x, int ptr_y, unsigned virtual_x,
|
||||
unsigned y, unsigned blocksize);
|
||||
// Dump the machine registers
|
||||
unsigned PageTableRoom(unsigned numPages, unsigned blocksize);
|
||||
// Return how much room is needed for a page table
|
||||
unsigned DumpPageTable(FILE *output,
|
||||
TranslationEntry *pageTable, unsigned pageTableSize,
|
||||
unsigned addr_x, unsigned virtual_x, unsigned virtual_width,
|
||||
unsigned physical_x, unsigned virtual_y, unsigned y,
|
||||
unsigned blocksize);
|
||||
// Dump a pagetable
|
||||
|
||||
|
||||
// Data structures -- all of these are accessible to Nachos kernel code.
|
||||
// "public" for convenience.
|
||||
//
|
||||
// Note that *all* communication between the user program and the kernel
|
||||
// are in terms of these data structures.
|
||||
|
||||
char *mainMemory; // physical memory to store user program,
|
||||
// code and data, while executing
|
||||
int registers[NumTotalRegs]; // CPU registers, for executing user programs
|
||||
|
||||
|
||||
// NOTE: the hardware translation of virtual addresses in the user program
|
||||
// to physical addresses (relative to the beginning of "mainMemory")
|
||||
// can be controlled by one of:
|
||||
// a traditional linear page table
|
||||
// a software-loaded translation lookaside buffer (tlb) -- a cache of
|
||||
// mappings of virtual page #'s to physical page #'s
|
||||
//
|
||||
// If "tlb" is NULL, the linear page table is used
|
||||
// If "tlb" is non-NULL, the Nachos kernel is responsible for managing
|
||||
// the contents of the TLB. But the kernel can use any data structure
|
||||
// it wants (eg, segmented paging) for handling TLB cache misses.
|
||||
//
|
||||
// For simplicity, both the page table pointer and the TLB pointer are
|
||||
// public. However, while there can be multiple page tables (one per address
|
||||
// space, stored in memory), there is only one TLB (implemented in hardware).
|
||||
// Thus the TLB pointer should be considered as *read-only*, although
|
||||
// the contents of the TLB are free to be modified by the kernel software.
|
||||
|
||||
TranslationEntry *tlb; // this pointer should be considered
|
||||
// "read-only" to Nachos kernel code
|
||||
|
||||
TranslationEntry *currentPageTable;
|
||||
unsigned int currentPageTableSize;
|
||||
|
||||
private:
|
||||
bool singleStep; // drop back into the debugger after each
|
||||
// simulated instruction
|
||||
int runUntilTime; // drop back into the debugger when simulated
|
||||
// time reaches this value
|
||||
};
|
||||
|
||||
extern void ExceptionHandler(ExceptionType which);
|
||||
// Entry point into Nachos for handling
|
||||
// user system calls and exceptions
|
||||
// Defined in exception.cc
|
||||
|
||||
|
||||
// Routines for converting Words and Short Words to and from the
|
||||
// simulated machine's format of little endian. If the host machine
|
||||
// is little endian (DEC and Intel), these end up being NOPs.
|
||||
//
|
||||
// What is stored in each format:
|
||||
// host byte ordering:
|
||||
// kernel data structures
|
||||
// user registers
|
||||
// simulated machine byte ordering:
|
||||
// contents of main memory
|
||||
|
||||
unsigned int WordToHost(unsigned int word);
|
||||
unsigned short ShortToHost(unsigned short shortword);
|
||||
unsigned int WordToMachine(unsigned int word);
|
||||
unsigned short ShortToMachine(unsigned short shortword);
|
||||
|
||||
extern unsigned AddrSpacesRoom(unsigned blocksize);
|
||||
extern void DumpAddrSpaces(FILE *output,
|
||||
unsigned addr_x, unsigned sections_x, unsigned virtual_x, unsigned virtual_width,
|
||||
unsigned physical_x, unsigned y, unsigned blocksize);
|
||||
|
||||
#endif // MACHINE_H
|
Loading…
Add table
Add a link
Reference in a new issue