Initial version
This commit is contained in:
commit
6f405265a5
102 changed files with 14486 additions and 0 deletions
137
code/userprog/exception.cc
Normal file
137
code/userprog/exception.cc
Normal file
|
@ -0,0 +1,137 @@
|
|||
// exception.cc
|
||||
// Entry point into the Nachos kernel from user programs.
|
||||
// There are two kinds of things that can cause control to
|
||||
// transfer back to here from user code:
|
||||
//
|
||||
// syscall -- The user code explicitly requests to call a procedure
|
||||
// in the Nachos kernel. Right now, the only function we support is
|
||||
// "Halt".
|
||||
//
|
||||
// exceptions -- The user code does something that the CPU can't handle.
|
||||
// For instance, accessing memory that doesn't exist, arithmetic errors,
|
||||
// etc.
|
||||
//
|
||||
// Interrupts (which can also cause control to transfer from user
|
||||
// code into the Nachos kernel) are handled elsewhere.
|
||||
//
|
||||
// For now, this only handles the Halt() system call.
|
||||
// Everything else core dumps.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include "copyright.h"
|
||||
#include "system.h"
|
||||
#include "syscall.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// UpdatePC : Increments the Program Counter register in order to resume
|
||||
// the user program immediately after the "syscall" instruction.
|
||||
//----------------------------------------------------------------------
|
||||
static void
|
||||
UpdatePC ()
|
||||
{
|
||||
int pc = machine->ReadRegister (PCReg);
|
||||
machine->WriteRegister (PrevPCReg, pc);
|
||||
pc = machine->ReadRegister (NextPCReg);
|
||||
machine->WriteRegister (PCReg, pc);
|
||||
pc += 4;
|
||||
machine->WriteRegister (NextPCReg, pc);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// ExceptionHandler
|
||||
// Entry point into the Nachos kernel. Called when a user program
|
||||
// is executing, and either does a syscall, or generates an addressing
|
||||
// or arithmetic exception.
|
||||
//
|
||||
// For system calls, the following is the calling convention:
|
||||
//
|
||||
// system call code -- r2
|
||||
// arg1 -- r4
|
||||
// arg2 -- r5
|
||||
// arg3 -- r6
|
||||
// arg4 -- r7
|
||||
//
|
||||
// The result of the system call, if any, must be put back into r2.
|
||||
//
|
||||
// And don't forget to increment the pc before returning. (Or else you'll
|
||||
// loop making the same system call forever!
|
||||
//
|
||||
// "which" is the kind of exception. The list of possible exceptions
|
||||
// are in machine.h.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void
|
||||
ExceptionHandler (ExceptionType which)
|
||||
{
|
||||
int type = machine->ReadRegister (2);
|
||||
int address = machine->registers[BadVAddrReg];
|
||||
|
||||
switch (which)
|
||||
{
|
||||
case SyscallException:
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case SC_Halt:
|
||||
{
|
||||
DEBUG ('s', "Shutdown, initiated by user program.\n");
|
||||
interrupt->Powerdown ();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
printf("Unimplemented system call %d\n", type);
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
// Do not forget to increment the pc before returning!
|
||||
UpdatePC ();
|
||||
break;
|
||||
}
|
||||
|
||||
case PageFaultException:
|
||||
if (!address) {
|
||||
printf("NULL dereference at PC %x!\n", machine->registers[PCReg]);
|
||||
ASSERT (FALSE);
|
||||
} else {
|
||||
printf ("Page Fault at address %x at PC %x\n", address, machine->registers[PCReg]);
|
||||
ASSERT (FALSE); // For now
|
||||
}
|
||||
break;
|
||||
|
||||
case ReadOnlyException:
|
||||
printf ("Read-Only at address %x at PC %x\n", address, machine->registers[PCReg]);
|
||||
ASSERT (FALSE); // For now
|
||||
break;
|
||||
|
||||
case BusErrorException:
|
||||
printf ("Invalid physical address at address %x at PC %x\n", address, machine->registers[PCReg]);
|
||||
ASSERT (FALSE); // For now
|
||||
break;
|
||||
|
||||
case AddressErrorException:
|
||||
printf ("Invalid address %x at PC %x\n", address, machine->registers[PCReg]);
|
||||
ASSERT (FALSE); // For now
|
||||
break;
|
||||
|
||||
case OverflowException:
|
||||
printf ("Overflow at PC %x\n", machine->registers[PCReg]);
|
||||
ASSERT (FALSE); // For now
|
||||
break;
|
||||
|
||||
case IllegalInstrException:
|
||||
printf ("Illegal instruction at PC %x\n", machine->registers[PCReg]);
|
||||
ASSERT (FALSE); // For now
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("Unexpected user mode exception %d %d %x at PC %x\n", which, type, address, machine->registers[PCReg]);
|
||||
ASSERT (FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue