// Shahir Ahmed and Boosung Kim #include "../h/vmSupport.h" extern state_t* savedException; extern int flashSemaphores[UPROCMAX]; // Semaphores to represent the flash devices extern pcb_t* currentProcess; swap_t swapPoolTable[POOLSIZE]; int swapPoolSemaphore; // for controlling access to the swap pool table void initSwapStructs() { swapPoolSemaphore = 1; for (int i = 0; i < POOLSIZE; i++) { swapPoolTable[i].sw_asid = NOPROC; } } /* * Handles page fault exceptions */ void Support_Pager() { // obtain a pointer to the current proccess's support structure support_t* supportPtr = (support_t*) SYSCALL(GETSUPPORTPTR, 0, 0, 0); // determine the cause of the TLB exception int execCode = GET_EXEC_CODE(supportPtr->sup_exceptState[PGFAULTEXCEPT].cause); if (execCode == 1) { // TLB modification exception SYSCALL(TERMINATE, 0, 0, 0); //I changed code here. Call the Level 4 SYSCALL } // Gain mutual exclusion over the swap pool table SYSCALL(PASSERN, (memaddr) &swapPoolSemaphore, 0, 0); //I changed code here. Added missing & // Determine the page number that caused the page fault int pgNo = (supportPtr->sup_exceptState[PGFAULTEXCEPT].entry_hi - 0x80000000) >> 12; if (pgNo < 0 || pgNo > 30) { pgNo = 31; // 31 represents the stack page } int frame = -1; // Find the first free frame in the swap pool and assign its number to frame for (int i = 0; i < POOLSIZE; i++) { if (swapPoolTable[i].sw_asid == NOPROC) { frame = i; break; } } if (frame == -1) { frame = replacementAlgorithm(); } int frameAsid = swapPoolTable[frame].sw_asid; // asid associated with the returned frame number int asid = supportPtr->sup_asid; // asid of the current process // 0x20020000 is the starting address of the swap pool. Each frame is 4096 bits. To get // to the base address of the frame, we need to add number of frames * 4096 bits + starting address of the swap pool memaddr frameAddress = (0x20020000) + (frame * 4096); if (frameAsid != NOPROC) { // the frame was occupied by a process page DISABLE_INTERRUPTS_COMMAND; // ATOMIC UNSET_BIT(swapPoolTable[frame].sw_pte->pte_entryLO, 9); // clear the valid bit // update the TLB to reflect the entry corresponding to the page removed from the swap pool updateTLB(swapPoolTable[frame].sw_pte); ENABLE_INTERRUPTS_COMMAND; // ATOMIC END // Update the process's backing store. Write the contents of removed frame to the correct location on // the process's backing store int blockNo = (swapPoolTable[frame].sw_pte->pte_entryHI - 0x80000000) >> 12; backStoreManager(3, frameAsid, frameAddress, blockNo); } // Read the contents of the current process's backing store/flash device logical page pgNo into frame because // the process is not in the RAM and needs to load the frame from the backing store/flash device backStoreManager(2, asid, frameAddress, pgNo); DISABLE_INTERRUPTS_COMMAND; // ATOMIC // Update the swap pool table's entry at index frame to reflect the new frame contents swapPoolTable[frame].sw_asid = asid; swapPoolTable[frame].sw_pageNo = pgNo; swapPoolTable[frame].sw_pte = &(supportPtr->sup_privatePgTbl[pgNo]); supportPtr->sup_privatePgTbl[pgNo].pte_entryLO = (frameAddress & 0xFFFFF000) | VALIDON | DIRTYON; updateTLB(&(supportPtr->sup_privatePgTbl[pgNo])); ENABLE_INTERRUPTS_COMMAND; SYSCALL(VERHOGEN, (int) &swapPoolSemaphore, 0, 0); // release mutual exclusion over the swap pool table ////I changed code here. Added missing & LDST((state_t*) &(supportPtr->sup_exceptState[PGFAULTEXCEPT])); // return control to the current process } void backStoreManager(unsigned int command, int flash_asid, unsigned int data_addr, unsigned int deviceBlockNumber) { SYSCALL(PASSERN, (memaddr) &flashSemaphores[flash_asid - 1], 0, 0); // Gain mutual exclusion on the flash device //I changed code here (added missing &) devreg_t* deviceRegister = GET_DEV_ADDR(4, flash_asid - 1); // Get the address of the device register deviceRegister->dtp.data0 = data_addr; DISABLE_INTERRUPTS_COMMAND; // ATOMIC deviceRegister->dtp.command = (deviceBlockNumber << 8) | command; SYSCALL(IOWAIT, 4, flash_asid - 1, 0); ENABLE_INTERRUPTS_COMMAND; // ATOMIC END SYSCALL(VERHOGEN, (int) &flashSemaphores[flash_asid - 1], 0, 0); if (deviceRegister->dtp.status != DEV0ON){ SYSCALL(TERMPROCESS, 0, 0, 0); } } // Update a specific mapping in the TLB // updated_entry is the address of the support page table field at index pgNo. void updateTLB(pteEntry_t *updated_entry) { setENTRYHI(updated_entry->pte_entryHI); TLBP(); // Search for the TLB and update the probe bit. if ((getINDEX() & 0x80000000) == 0){ // The entry is present in the TLB. setENTRYLO(updated_entry->pte_entryLO); TLBWI(); } } int replacementAlgorithm() { static int frameNum = 0; int frameReturn = frameNum; frameNum = (frameNum + 1) % POOLSIZE; return frameReturn; } void uTLB_RefillHandler() { GET_BDP_STATUS(savedException); // Create a passed variable and make it a pointer to the BIOSDATAPAGE int pgNum = (savedException->entry_hi - 0x80000000) >> 12; // Get the missing page number if (pgNum < 0 || pgNum > 30) { pgNum = 31; // stack page num } setENTRYHI(currentProcess->p_supportStruct->sup_privatePgTbl[pgNum].pte_entryHI); setENTRYLO(currentProcess->p_supportStruct->sup_privatePgTbl[pgNum].pte_entryLO); TLBWR(); LDST(savedException); }