#include "../h/sysSupport.h" #include "../h/syscall.h" #include "../h/libraries.h" extern swap_t swapPoolTable[POOLSIZE]; extern int supportDeviceSemaphore[3][UPROCMAX]; // 3 device semaphores for printer, terminal receiver and terminal transmitter extern int flashSemaphores[UPROCMAX]; extern int master_sem; void GeneralException_Handler() { support_t* supportPointer = (support_t*) SYSCALL(GETSUPPORTPTR, 0, 0, 0); // Get access to the support info of the current process int exceptionCode = GET_EXEC_CODE(supportPointer->sup_exceptState[GENERALEXCEPT].cause); if (exceptionCode >= 9) { Terminate_SYS9(supportPointer); return; } int sysnumber = (int) supportPointer->sup_exceptState[GENERALEXCEPT].reg_a0; supportPointer->sup_exceptState[GENERALEXCEPT].pc_epc = supportPointer->sup_exceptState[GENERALEXCEPT].pc_epc + 4; switch (sysnumber) { case TERMINATE: Terminate_SYS9(supportPointer); break; case GET_TOD: Get_Tod_SYS10(supportPointer); break; case WRITEPRINTER: Write_To_Printer_SYS11(supportPointer); break; case WRITETERMINAL: Write_to_Terminal_SYS12(supportPointer); break; case READTERMINAL: Read_From_Terminal_SYS13(supportPointer); break; default: Terminate_SYS9(supportPointer); break; } LDST((state_t*) &(supportPointer->sup_exceptState[GENERALEXCEPT])); } /* void Terminate_SYS9(support_t* sPtr) { SYSCALL(VERHOGEN, (int) &master_sem, 0, 0); deleteSwTbEntries(sPtr->sup_asid); // Clear entries in the swap pool table // Any device semaphore being held should be released for (int device = 0; device < 3; device++) { if (sPtr->sup_asid - 1 <= 0) { SYSCALL(VERHOGEN, (int) &(supportDeviceSemaphore[device][(sPtr->sup_asid) - 1]), 0, 0); } } if (flashSemaphores[(sPtr->sup_asid) - 1] <= 0) { SYSCALL(VERHOGEN, (int) &(flashSemaphores[(sPtr->sup_asid) - 1]), 0, 0); } } */ void Terminate_SYS9(support_t* sPtr) // sys2 wrapper { // cleaning the entries on the swap table deleteSwTbEntries(sPtr->sup_asid); // checking if the process to be terminated is holding any mutex semaphore // in that case use a SYS4 to free it and terminate it with sys2 for (int i = 0; i < SUPP_SEM_N; i++) { if (supportDeviceSemaphore[i][sPtr->sup_asid - 1] <= 0) // i is the device semaphore line, asid represents the device SYSCALL(VERHOGEN, (int) &supportDeviceSemaphore[i][sPtr->sup_asid - 1], 0, 0); } if (flashSemaphores[sPtr->sup_asid - 1] <= 0) SYSCALL(VERHOGEN, (int) &flashSemaphores[sPtr->sup_asid - 1], 0, 0); // waking up the test proc SYSCALL(VERHOGEN, (int) &master_sem, 0, 0); SYSCALL(TERMPROCESS, 0, 0, 0); } void Get_Tod_SYS10(support_t* sPtr) { unsigned int timeofDay; STCK(timeofDay); // population of timeofDay with current time of day sPtr->sup_exceptState[1].reg_v0 = (unsigned int) timeofDay; } void Write_To_Printer_SYS11(support_t* sPtr) { // Get the address of the device register associated with the printer devreg_t* deviceRegister = GET_DEV_ADDR(6, ((sPtr->sup_asid) - 1)); // Gain mutual exclusion on the printer device semaphore SYSCALL(PASSEREN, (int) &(supportDeviceSemaphore[0][(sPtr->sup_asid) - 1]), 0, 0); int stringLength = (int) sPtr->sup_exceptState[1].reg_a2; // length of the passed string char* s_addr = (char*) sPtr->sup_exceptState[1].reg_a1; // address of the first character of the string int charTransmitted = 0; unsigned int printerStatus; // Transmit all characters in length for (charTransmitted = 0; charTransmitted < stringLength; charTransmitted++) { deviceRegister->dtp.data0 = *s_addr; DISABLE_INTERRUPTS_COMMAND; // ATOMIC deviceRegister->dtp.command = 2; SYSCALL(IOWAIT, 6, (sPtr->sup_asid) - 1, 0); ENABLE_INTERRUPTS_COMMAND; // ATOMIC END printerStatus = deviceRegister->dtp.status; if (printerStatus != 1) { // Error printerStatus = printerStatus*(-1); break; } //No error s_addr = s_addr + 1; charTransmitted = charTransmitted + 1; } sPtr->sup_exceptState->reg_v0 = charTransmitted; SYSCALL(VERHOGEN, (int) &(supportDeviceSemaphore[0][(sPtr->sup_asid) - 1]), 0, 0); } // Communicate with the TERMINAL device void Write_to_Terminal_SYS12(support_t* sPtr) { devreg_t* deviceRegister = GET_DEV_ADDR(7, ((sPtr->sup_asid) - 1)); SYSCALL(PASSERN, (memaddr) &supportDeviceSemaphore[1][(sPtr->sup_asid) - 1], 0, 0); // Gain mutual exclusion int stringLength = (int) sPtr->sup_exceptState[1].reg_a2; char* s_addr = (char*) sPtr->sup_exceptState[1].reg_a1; int charTransmitted = 0; unsigned int terminalStatus; if( (memaddr) s_addr >= 0x80000000 && stringLength >=0 && stringLength <=128) { for (charTransmitted = 0; charTransmitted < stringLength; charTransmitted++) { DISABLE_INTERRUPTS_COMMAND; deviceRegister->term.transm_command = ((unsigned int) *s_addr << 8) | 2; // Constructs a transmitter command by embedding the address in the // higher-order bits and a specific command (2) in the lower-order bits, then assigns it to the device register terminalStatus = SYSCALL(IOWAIT, 7, (sPtr->sup_asid) - 1, 0); ENABLE_INTERRUPTS_COMMAND; if ((terminalStatus & 0xFF) != 5) { // error terminalStatus = terminalStatus * (-1); break; } // not error s_addr = s_addr + 1; //charTransmitted = charTransmitted + 1; //I changed this (incrementing is already being done in the for loop (while loop would have required this) } } else { Terminate_SYS9(sPtr); //I changed code here (added the missing else condition) } sPtr->sup_exceptState[1].reg_v0 = charTransmitted; SYSCALL(VERHOGEN, (int) &supportDeviceSemaphore[1][(sPtr->sup_asid) - 1], 0, 0); } void Read_From_Terminal_SYS13(support_t* sPtr) { devreg_t* deviceRegister = GET_DEV_ADDR(7, ((sPtr->sup_asid) - 1)); SYSCALL(PASSERN, (int) &supportDeviceSemaphore[2][(sPtr->sup_asid) - 1], 0, 0); // Gain mutual exclusion char* s_addr = (char*) sPtr->sup_exceptState[1].reg_a1; // address of the first character in the string int charTransmitted = 0; unsigned int terminalStatus; if( (memaddr) s_addr >= 0x80000000) { //I changed this (added this missing if) while(1) { // terminates when new line is read DISABLE_INTERRUPTS_COMMAND; deviceRegister->term.recv_command = 2; terminalStatus = SYSCALL(IOWAIT, 7, (sPtr->sup_asid) - 1, 1); ENABLE_INTERRUPTS_COMMAND; if ((terminalStatus & 0xFF) != 5) { // failed read operation charTransmitted = ((terminalStatus >> 8) & 0xFF) * (-1); break; } else { // successful read operation charTransmitted = charTransmitted + 1; *s_addr = (terminalStatus >> 8) & 0xFF; char currentChar = *s_addr; s_addr = s_addr + 1; if (currentChar == '\n') { break; } } } } else { Terminate_SYS9(sPtr); //I changed code here (added the missing else condition) } sPtr->sup_exceptState[1].reg_v0 = charTransmitted; SYSCALL(VERHOGEN, (int) &supportDeviceSemaphore[2][(sPtr->sup_asid) - 1], 0, 0); //I changed this .. & was missing } // Clear all those entries in the swap pool table that are related to a specific process whose ASID // matches the asid value passed in void deleteSwTbEntries(int asid) { for (int i = 0; i < POOLSIZE; i++) { if (swapPoolTable[i].sw_asid == asid) { swapPoolTable[i].sw_asid = NOPROC; } } }