//----------------------------------------------------------------- // DfsReadBlock reads an allocated DFS block from the disk // (which could span multiple physical disk blocks). The block // must be allocated in order to read from it. Returns DFS_FAIL // on failure, and the number of bytes read on success. //----------------------------------------------------------------- int DfsReadBlock(uint32 blocknum, dfs_block *b) { disk_block diskb; int diskblocksize; int factor; int i; int count = 0; if(!sb.valid) { printf("DfsReadBlock: file system is not valid\n"); return DFS_FAIL; } // if(!(fbv[blocknum / 32] & (1 << (blocknum % 32)))) { // printf("DfsReadBlock: the block %d is not allocated\n", blocknum); // return DFS_FAIL; // } diskblocksize = DiskBytesPerBlock(); factor = sb.blocksize / diskblocksize; for(i = 0; i < factor; i++) { if(DiskReadBlock((blocknum * factor) + i, &diskb) == DISK_FAIL) { printf("DfsReadBlock: Disk read failed copied %d of %d\n", count, sb.blocksize); break; } bcopy(diskb.data, &(b->data[i * diskblocksize]), diskblocksize); count += diskblocksize; } return count; }
//----------------------------------------------------------------- // DfsWriteBlock writes to an allocated DFS block on the disk // (which could span multiple physical disk blocks). The block // must be allocated in order to write to it. Returns DFS_FAIL // on failure, and the number of bytes written on success. //----------------------------------------------------------------- int DfsWriteBlock(uint32 blocknum, dfs_block *b) { disk_block diskb; int diskblocksize; int factor; int i; int count = 0; if(fbv[blocknum / 32] & (1 << (blocknum % 32))) { printf("DfsWriteBlock: the block %d is not allocated\n", blocknum); return DFS_FAIL; } diskblocksize = DiskBytesPerBlock(); factor = sb.blocksize / diskblocksize; for(i = 0; i < factor; i++) { bcopy(&(b->data[i * diskblocksize]), diskb.data, diskblocksize); if(DiskWriteBlock((blocknum * factor) + i, &diskb) == DISK_FAIL) { printf("DfsWriteBlock: Disk write failed copied %d of %d\n", count, sb.blocksize); break; } count += diskblocksize; } return count; }
//---------------------------------------------------------------------- // // doInterrupt // // Handle an interrupt or trap. // //---------------------------------------------------------------------- void dointerrupt (unsigned int cause, unsigned int iar, unsigned int isr, uint32 *trapArgs) { int result; int i; uint32 args[4]; int intrs; uint32 handle; int ihandle; dbprintf ('t',"Interrupt cause=0x%x iar=0x%x isr=0x%x args=0x%08x.\n", cause, iar, isr, (int)trapArgs); // If the TRAP_INSTR bit is set, this was from a trap instruction. // If the bit isn't set, this was a system interrupt. if (cause & TRAP_TRAP_INSTR) { cause &= ~TRAP_TRAP_INSTR; switch (cause) { case TRAP_CONTEXT_SWITCH: dbprintf ('t', "Got a context switch trap!\n"); ProcessSchedule (); ClkResetProcess(); break; case TRAP_EXIT: case TRAP_USER_EXIT: dbprintf ('t', "Got an exit trap!\n"); ProcessDestroy (currentPCB); ProcessSchedule (); ClkResetProcess(); break; case TRAP_PROCESS_FORK: dbprintf ('t', "Got a fork trap!\n"); break; case TRAP_PROCESS_SLEEP: dbprintf ('t', "Got a process sleep trap!\n"); ProcessSuspend (currentPCB); ProcessSchedule (); ClkResetProcess(); break; case TRAP_PRINTF: // Call the trap printf handler and pass the arguments and a flag // indicating whether the trap was called from system mode. dbprintf ('t', "Got a printf trap!\n"); TrapPrintfHandler (trapArgs, isr & DLX_STATUS_SYSMODE); break; case TRAP_OPEN: // Get the arguments to the trap handler. If this is a user mode trap, // copy them from user space. if (isr & DLX_STATUS_SYSMODE) { args[0] = trapArgs[0]; args[1] = trapArgs[1]; } else { char filename[32]; // trapArgs points to the trap arguments in user space. There are // two of them, so copy them to to system space. The first argument // is a string, so it has to be copied to system space and the // argument replaced with a pointer to the string in system space. MemoryCopyUserToSystem (currentPCB, trapArgs, args, sizeof(args[0])*2); MemoryCopyUserToSystem (currentPCB, args[0], filename, 31); // Null-terminate the string in case it's longer than 31 characters. filename[31] = '\0'; // Set the argument to be the filename args[0] = (uint32)filename; } // Allow Open() calls to be interruptible! intrs = EnableIntrs (); ProcessSetResult (currentPCB, args[1] + 0x10000); printf ("Got an open with parameters ('%s',0x%x)\n", (char *)(args[0]), args[1]); RestoreIntrs (intrs); break; case TRAP_CLOSE: // Allow Close() calls to be interruptible! intrs = EnableIntrs (); ProcessSetResult (currentPCB, -1); RestoreIntrs (intrs); break; case TRAP_READ: // Allow Read() calls to be interruptible! intrs = EnableIntrs (); ProcessSetResult (currentPCB, -1); RestoreIntrs (intrs); break; case TRAP_WRITE: // Allow Write() calls to be interruptible! intrs = EnableIntrs (); ProcessSetResult (currentPCB, -1); RestoreIntrs (intrs); break; case TRAP_DELETE: intrs = EnableIntrs (); ProcessSetResult (currentPCB, -1); RestoreIntrs (intrs); break; case TRAP_SEEK: intrs = EnableIntrs (); ProcessSetResult (currentPCB, -1); RestoreIntrs (intrs); break; case TRAP_PROCESS_GETPID: ProcessSetResult(currentPCB, GetCurrentPid()); break; case TRAP_PROCESS_CREATE: TrapProcessCreateHandler(trapArgs, isr & DLX_STATUS_SYSMODE); break; case TRAP_SEM_CREATE: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = SemCreate(ihandle); ProcessSetResult(currentPCB, ihandle); //Return handle break; case TRAP_SEM_WAIT: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); handle = SemHandleWait(ihandle); ProcessSetResult(currentPCB, handle); //Return 1 or 0 break; case TRAP_SEM_SIGNAL: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); handle = SemHandleSignal(ihandle); ProcessSetResult(currentPCB, handle); //Return 1 or 0 break; case TRAP_LOCK_CREATE: ihandle = LockCreate(); ProcessSetResult(currentPCB, ihandle); //Return handle break; case TRAP_LOCK_ACQUIRE: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); handle = LockHandleAcquire(ihandle); ProcessSetResult(currentPCB, handle); //Return 1 or 0 break; case TRAP_LOCK_RELEASE: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); handle = LockHandleRelease(ihandle); ProcessSetResult(currentPCB, handle); //Return 1 or 0 break; case TRAP_COND_CREATE: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = CondCreate(ihandle); ProcessSetResult(currentPCB, ihandle); //Return handle break; case TRAP_COND_WAIT: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = CondHandleWait(ihandle); ProcessSetResult(currentPCB, ihandle); //Return 1 or 0 break; case TRAP_COND_SIGNAL: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = CondHandleSignal(ihandle); ProcessSetResult(currentPCB, ihandle); //Return 1 or 0 break; case TRAP_COND_BROADCAST: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = CondHandleBroadcast(ihandle); ProcessSetResult(currentPCB, ihandle); //Return 1 or 0 break; // Traps for Disk Access case TRAP_DISK_WRITE_BLOCK: ihandle = TrapDiskWriteBlockHandler(trapArgs, isr & DLX_STATUS_SYSMODE); ProcessSetResult(currentPCB, ihandle); break; case TRAP_DISK_SIZE: ProcessSetResult(currentPCB, DiskSize()); break; case TRAP_DISK_BLOCKSIZE: ProcessSetResult(currentPCB, DiskBytesPerBlock()); break; case TRAP_DISK_CREATE: ProcessSetResult(currentPCB, DiskCreate()); break; // Traps for DFS filesystem case TRAP_DFS_INVALIDATE: DfsInvalidate(); break; // Traps for file functions case TRAP_FILE_OPEN: ProcessSetResult(currentPCB, TrapFileOpenHandler(trapArgs, isr & DLX_STATUS_SYSMODE)); break; case TRAP_FILE_CLOSE: ProcessSetResult(currentPCB, TrapFileCloseHandler(trapArgs, isr & DLX_STATUS_SYSMODE)); break; case TRAP_FILE_DELETE: ProcessSetResult(currentPCB, TrapFileDeleteHandler(trapArgs, isr & DLX_STATUS_SYSMODE)); break; case TRAP_FILE_READ: ProcessSetResult(currentPCB, TrapFileReadHandler(trapArgs, isr & DLX_STATUS_SYSMODE)); break; case TRAP_FILE_WRITE: ProcessSetResult(currentPCB, TrapFileWriteHandler(trapArgs, isr & DLX_STATUS_SYSMODE)); break; case TRAP_FILE_SEEK: ProcessSetResult(currentPCB, TrapFileSeekHandler(trapArgs, isr & DLX_STATUS_SYSMODE)); break; // Traps for running OS testing code case TRAP_TESTOS: RunOSTests(); break; default: printf ("Got an unrecognized trap (0x%x) - exiting!\n", cause); GracefulExit (); break; } } else { switch (cause) { case TRAP_TIMER: dbprintf ('t', "Got a timer interrupt!\n"); // ClkInterrupt returns 1 when 1 "process quantum" has passed, meaning // that it's time to call ProcessSchedule again. if (ClkInterrupt()) { ProcessSchedule (); } break; case TRAP_KBD: do { i = *((uint32 *)DLX_KBD_NCHARSIN); result = *((uint32 *)DLX_KBD_GETCHAR); printf ("Got a keyboard interrupt (char=0x%x(%c), nleft=%d)!\n", result, result, i); } while (i > 1); break; case TRAP_ACCESS: printf ("Exiting after illegal access at iar=0x%x, isr=0x%x\n", iar, isr); GracefulExit (); break; case TRAP_ADDRESS: printf ("Exiting after illegal address at iar=0x%x, isr=0x%x\n", iar, isr); GracefulExit (); break; case TRAP_ILLEGALINST: printf ("Exiting after illegal instruction at iar=0x%x, isr=0x%x\n", iar, isr); GracefulExit (); break; case TRAP_PAGEFAULT: printf ("Exiting after page fault at iar=0x%x, isr=0x%x\n", iar, isr); GracefulExit (); break; default: printf ("Got an unrecognized system interrupt (0x%x) - exiting!\n", cause); GracefulExit (); break; } } dbprintf ('t',"About to return from dointerrupt.\n"); // Note that this return may schedule a new process! intrreturn (); }