void swapOutFrame(int entry1Index) { // clear the definition bit in entry 1 probably just set entry 1 to 0 int entry1, entry2; entry1 = memory[entry1Index]; entry2 = memory[entry1Index + 1]; // if dirty bit is not set and swap exists we are done if (DIRTY(entry1) && PAGED(entry2)) { DEBUG_STATEMENT(DEBUG_MMU,"\nDirty copy of swap write to old page"); // if swap exits swap access page with old write accessPage(SWAPPAGE(entry2), FRAME(entry1), PAGE_OLD_WRITE); } else if (!PAGED(entry2)) { DEBUG_STATEMENT(DEBUG_MMU,"\nNo copy in swap write to new swap"); // if swap doesn't exist then we need to write out to an new write memory[entry1Index + 1] = entry2 = SET_PAGED(nextPage); accessPage(nextPage, FRAME(entry1), PAGE_NEW_WRITE); } if (DEBUG_MMU) { outPTE("\nSwapped Entry - (Pre-clear) ", entry1Index); } memory[entry1Index] = 0; if (DEBUG_MMU) { outPTE("Swapped Entry - ", entry1Index); } return; }
// ************************************************************************** // ************************************************************************** // output page table entry void outPTE(char* s, int pte) { int pte1, pte2; char flags[10]; // read pt pte1 = memory[pte]; pte2 = memory[pte+1]; // look at appropriate flags strcpy(flags, "-----"); if (DEFINED(pte1)) flags[0] = 'F'; if (DIRTY(pte1)) flags[1] = 'D'; if (REFERENCED(pte1)) flags[2] = 'R'; if (PINNED(pte1)) flags[3] = 'P'; if (PAGED(pte2)) flags[4] = 'S'; // output pte line if(DEFINED(pte1) || DEFINED(pte2)) printf("\n%s x%04x = %04x %04x %s", s, pte, pte1, pte2, flags); if (DEFINED(pte1) || DEFINED(pte2)) printf(" Frame=%d", FRAME(pte1)); if (DEFINED(pte2)) printf(" Page=%d", SWAPPAGE(pte2)); return; } // end outPTE
unsigned short int *getMemAdr(int va, int rwFlg) { unsigned short int pa; int rpta, rpte1, rpte2; int upta, upte1, upte2; int rptFrame, uptFrame; memAccess += 2; // rpta = 0x2400 + RPTI(va); rpta = tcb[curTask].RPT + RPTI(va); rpte1 = memory[rpta]; rpte2 = memory[rpta+1]; // turn off virtual addressing for system RAM if (va < 0x3000) return &memory[va]; #if MMU_ENABLE if (DEFINED(rpte1)) { // printf("\nUPT frame already defined"); // defined memHits++; } else { // fault memPageFaults++; rptFrame = getFrame(-1); rpte1 = SET_DEFINED(rptFrame); if (PAGED(rpte2)) { //upt is in swap and we need to read it back in accessPage(SWAPPAGE(rpte2), rptFrame, PAGE_READ); } else { //initialize the upt memory memset(&memory[(rptFrame<<6)], 0, 128); } } memory[rpta] = rpte1 = SET_REF(rpte1); memory[rpta+1] = rpte2; upta = (FRAME(rpte1)<<6) + UPTI(va); upte1 = memory[upta]; upte2 = memory[upta+1]; if (DEFINED(upte1)) { // defined memHits++; } else { // fault memPageFaults++; uptFrame = getFrame(FRAME(memory[rpta])); memory[rpta] = rpte1 = SET_REF(SET_DIRTY(rpte1)); upte1 = SET_DEFINED(uptFrame); if (PAGED(upte2)) { //get the data frame from swap accessPage(SWAPPAGE(upte2), uptFrame, PAGE_READ); } else { //we don't need to do anything //but we could initialize the mem to 0xf025 which is lc-3 halt instruction memset(&memory[(uptFrame<<6)], 0xf025, 128); } } if (rwFlg) { upte1 = SET_DIRTY(upte1); } memory[upta] = SET_REF(upte1); memory[upta+1] = upte2; return &memory[(FRAME(upte1)<<6) + FRAMEOFFSET(va)]; #else return &memory[va]; #endif } // end getMemAdr
int getFrame(int notme) { int UPTClock; // clock for UPT int frame; frame = getAvailableFrame(); if (frame >=0) return frame; if(RPTClock == 0){ RPTClock = LC3_RPT; } int RPTBegin = RPTClock; int first = 1; int rptCount = 0; //iterate the first time through the tables while(first || RPTClock != RPTBegin){ rptCount++; first = 0; //Check and make sure the notme condition holds if(DEFINED(memory[RPTClock])){ UPTClock = (FRAME(memory[RPTClock])<<6); int UPTBegin = UPTClock; int uFirst = 1; int hadDefined = 0; int uptcount = 0; while(uFirst || UPTClock != UPTBegin){ uptcount++; uFirst = 0; if(DEFINED(memory[UPTClock])){ hadDefined = 1; } if(notme != UPTClock && DEFINED(memory[UPTClock])){ //swap out if not referenced if(!REFERENCED(memory[UPTClock])){ //if it's dirty, write it to memory int swapPage = 0; if (DIRTY(memory[UPTClock])){ if(PAGED(memory[UPTClock + 1])) swapPage = accessPage(SWAPPAGE(memory[UPTClock + 1]), FRAME(memory[UPTClock]), PAGE_OLD_WRITE); else swapPage = accessPage(0, FRAME(memory[UPTClock]), PAGE_NEW_WRITE); memory[UPTClock] = CLEAR_DIRTY(memory[UPTClock]); memory[UPTClock+1] = SET_PAGED(swapPage); pageWrites++; } //no longer in main memory--it's swapped! memory[UPTClock] = CLEAR_DEFINED(memory[UPTClock]); //increment the clock if(RPTClock + 2 < LC3_RPT_END) RPTClock += 2; else RPTClock = LC3_RPT; return FRAME(memory[UPTClock]); } memory[UPTClock] = CLEAR_REF(memory[UPTClock]); } //sanity check assert(UPTClock >= 0x3000); if(UPTClock + 2 < UPTBegin + LC3_FRAME_SIZE) UPTClock += 2; else UPTClock = UPTBegin; } if(!REFERENCED(memory[RPTClock]) && !hadDefined && notme != RPTClock){ int swapPage; if(PAGED(memory[RPTClock + 1])) swapPage = accessPage(SWAPPAGE(memory[RPTClock + 1]), FRAME(memory[RPTClock]), PAGE_OLD_WRITE); else swapPage = accessPage(0, FRAME(memory[RPTClock]), PAGE_NEW_WRITE); memory[RPTClock] = CLEAR_DIRTY(memory[RPTClock]); memory[RPTClock+1] = SET_PAGED(swapPage); pageWrites++; memory[RPTClock] = CLEAR_DEFINED(memory[RPTClock]); int rE1 = memory[RPTClock]; if(RPTClock + 2 < LC3_RPT_END) RPTClock += 2; else RPTClock = LC3_RPT; return FRAME(rE1); } //clear the reference bit memory[RPTClock] = CLEAR_REF(memory[RPTClock]); } if(RPTClock + 2 < LC3_RPT_END){ RPTClock += 2; } else{ RPTClock = LC3_RPT; } } RPTBegin = RPTClock; first = 1; while(first || RPTClock != RPTBegin){ rptCount++; first = 0; //Check and make sure the notme condition holds if(DEFINED(memory[RPTClock])){ UPTClock = (FRAME(memory[RPTClock])<<6); int UPTBegin = UPTClock; int uFirst = 1; int hadDefined = 0; int uptcount = 0; while(uFirst || UPTClock != UPTBegin){ uptcount++; uFirst = 0; if(DEFINED(memory[UPTClock])){ hadDefined = 1; } if(notme != UPTClock && DEFINED(memory[UPTClock])){ //swap out if not referenced if(!REFERENCED(memory[UPTClock])){ //if it's dirty, write it to memory int swapPage = 0; if (DIRTY(memory[UPTClock])){ if(PAGED(memory[UPTClock + 1])) swapPage = accessPage(SWAPPAGE(memory[UPTClock + 1]), FRAME(memory[UPTClock]), PAGE_OLD_WRITE); else swapPage = accessPage(0, FRAME(memory[UPTClock]), PAGE_NEW_WRITE); memory[UPTClock] = CLEAR_DIRTY(memory[UPTClock]); memory[UPTClock+1] = SET_PAGED(swapPage); pageWrites++; } //no longer in main memory--it's swapped! memory[UPTClock] = CLEAR_DEFINED(memory[UPTClock]); //increment the clock if(RPTClock + 2 < LC3_RPT_END) RPTClock += 2; else RPTClock = LC3_RPT; return FRAME(memory[UPTClock]); } memory[UPTClock] = CLEAR_REF(memory[UPTClock]); } //sanity check assert(UPTClock >= 0x3000); if(UPTClock + 2 < UPTBegin + LC3_FRAME_SIZE) UPTClock += 2; else UPTClock = UPTBegin; } if(!REFERENCED(memory[RPTClock]) && !hadDefined && notme != RPTClock){ int swapPage; if(PAGED(memory[RPTClock + 1])) swapPage = accessPage(SWAPPAGE(memory[RPTClock + 1]), FRAME(memory[RPTClock]), PAGE_OLD_WRITE); else swapPage = accessPage(0, FRAME(memory[RPTClock]), PAGE_NEW_WRITE); memory[RPTClock] = CLEAR_DIRTY(memory[RPTClock]); memory[RPTClock+1] = SET_PAGED(swapPage); pageWrites++; memory[RPTClock] = CLEAR_DEFINED(memory[RPTClock]); int rE1 = memory[RPTClock]; if(RPTClock + 2 < LC3_RPT_END) RPTClock += 2; else RPTClock = LC3_RPT; return FRAME(rE1); } //clear the reference bit memory[RPTClock] = CLEAR_REF(memory[RPTClock]); } if(RPTClock + 2 < LC3_RPT_END){ RPTClock += 2; } else{ RPTClock = LC3_RPT; } } //we should never ever be here assert(0); return -1; }
unsigned short int *getMemAdr(int va, int rwFlg) { unsigned short int pa; int rpta, rpte1, rpte2; int upta, upte1, upte2; int rptFrame, uptFrame; rpta = tcb[curTask].RPT + RPTI(va); rpte1 = memory[rpta]; rpte2 = memory[rpta+1]; // turn off virtual addressing for system RAM if (va < 0x3000) return &memory[va]; #if MMU_ENABLE if (DEFINED(rpte1)) { memHits++; } else { // fault memPageFaults++; rptFrame = getFrame(-1); assert(rptFrame >= 192); rpte1 = SET_DEFINED(rptFrame); if (PAGED(rpte2)) { accessPage(SWAPPAGE(rpte2), rptFrame, PAGE_READ); pageReads++; } else { rpte1 = SET_DIRTY(rpte1); rpte2 = 0; memset(&memory[(rptFrame<<6)], 0, 128); } } memory[rpta] = rpte1 = SET_REF(rpte1); memory[rpta+1] = rpte2; upta = (FRAME(rpte1)<<6) + UPTI(va); upte1 = memory[upta]; upte2 = memory[upta+1]; if (DEFINED(upte1)) { memHits++; } else { // fault memPageFaults++; uptFrame = getFrame(FRAME(memory[rpta])); assert(uptFrame >= 192); upte1 = SET_DEFINED(uptFrame); if (PAGED(upte2)) { accessPage(SWAPPAGE(upte2), uptFrame, PAGE_READ); pageReads++; } else { upte1 = SET_DIRTY(upte1); upte2 = 0; } } if(rwFlg != 0){ upte1 = SET_DIRTY(upte1); } memory[upta] = SET_REF(upte1); memory[upta+1] = upte2; memAccess = memHits + memPageFaults; return &memory[(FRAME(upte1)<<6) + FRAMEOFFSET(va)]; #else pa = va; #endif return &memory[pa]; } // end getMemAdr
int clockRunner(int notme) { //extern int curRPT; //extern TCB tcb[MAX_TASKS]; int i,j,k; int rpta, rpte1, rpte2; int upta, upte1, upte2; int victimFrame; int tupta, tupte1; //printf("\nClock running...%d\n",clockCount++); //victimEntry = 0; while (1) { //rpta = tcb[curRPT].RPT; for (i = curRPTE; i < 0x3000; i+=2) { //rpte1 = memory[rpta + i]; //rpte2 = memory[rpta + i + 1]; rpte1 = memory[i]; rpte2 = memory[i + 1]; if (DEFINED(rpte1)) { if (curUPTE == 0) { if(PINNED(rpte1)) { //memory[rpta + i] = rpte1 = CLEAR_PINNED(rpte1); memory[i] = rpte1 = CLEAR_PINNED(rpte1); } } upta = (FRAME(rpte1)<<6); for (j = curUPTE; j < 64; j+=2) { upte1 = memory[upta + j]; upte2 = memory[upta + j + 1]; if (DEFINED(upte1)) { //memory[rpta + i] = rpte1 = SET_PINNED(rpte1); memory[i] = rpte1 = SET_PINNED(rpte1); if (REFERENCED(upte1)) { memory[upta + j] = upte1 = CLEAR_REF(upte1); } else { //victimEntry = upte1; // if end of UPT, reset upte and move to next UPT //break; // because this is the victim // instead of break, do swapping and return victim frame number // immunity from notme //if (FRAME(upte1) != notme) //{ if (DIRTY(upte1)) { int page; //stat pageWrites++; if(PAGED(upte2)) { page = accessPage(SWAPPAGE(upte2),FRAME(upte1),PAGE_OLD_WRITE); } else { page = accessPage(0,FRAME(upte1),PAGE_NEW_WRITE); } upte2 = page; memory[upta + j + 1] = upte2 = SET_PAGED(upte2); } // save frame number before obliterating first word victimFrame = FRAME(upte1); //memory[upta + j] = upte1 = CLEAR_DEFINED(upte1); memory[upta + j] = upte1 = 0; curUPTE = (j + 2) % 64; //printf("\nChose a UPT victim: %d\n",victimFrame); return victimFrame; //} } } } // immunity from notme if ((FRAME(rpte1) != notme) && (!PINNED(rpte1))) { //victimEntry = rpte1; // if end of RPT, reset rpte and move to next RPT //break; // because this is the victim // instead of break, do swapping and return victim frame number //victimEntry = FRAME(rpte1); // sanity check tupta = (FRAME(rpte1)<<6); for (k = 0; k < 64; k+=2) { tupte1 = memory[tupta + k]; if (DEFINED(tupte1)) printf("\nEvicting a UPT that has defined entries!!!\n"); } //if (DIRTY(rpte1)) { int page; //stat pageWrites++; if(PAGED(rpte2)) { page = accessPage(SWAPPAGE(rpte2),FRAME(rpte1),PAGE_OLD_WRITE); } else { page = accessPage(0,FRAME(rpte1),PAGE_NEW_WRITE); } rpte2 = page; //memory[rpta + i + 1] = rpte2 = SET_PAGED(rpte2); memory[i + 1] = rpte2 = SET_PAGED(rpte2); } // save frame number before obliterating first word victimFrame = FRAME(rpte1); //memory[rpta + i] = rpte1 = CLEAR_DEFINED(rpte1); //memory[rpta + i] = rpte1 = 0; memory[i] = rpte1 = 0; //curRPTE = (i + 2) % 64; //printf("\nChose a RPT victim: %d\n",victimFrame); return victimFrame; } curUPTE = 0; } } //curRPT = (curRPT + 1) % MAX_TASKS; curRPTE = 0x2400; } }
unsigned short int *getMemAdr(int va, int rwFlg) { unsigned short int pa; int rpta, rpte1, rpte2; int upta, upte1, upte2; int rptFrame, uptFrame; extern TCB tcb[MAX_TASKS]; extern int curTask; //stat memAccess++; rpta = tcb[curTask].RPT + RPTI(va); // 0x2400 + RPTI(va); rpte1 = memory[rpta]; rpte2 = memory[rpta+1]; // turn off virtual addressing for system RAM if (va < 0x3000) return &memory[va]; #if MMU_ENABLE if (DEFINED(rpte1)) { // defined //stat memHits++; if (rwFlg) rpte1 = SET_DIRTY(rpte1); } else { // fault //stat memPageFaults++; rptFrame = getFrame(-1); rpte1 = SET_DEFINED(rptFrame); if (PAGED(rpte2)) { accessPage(SWAPPAGE(rpte2), rptFrame, PAGE_READ); //stat pageReads++; //clean if (rwFlg) rpte1 = SET_DIRTY(rpte1); else rpte1 = CLEAR_DIRTY(rpte1); } else { memset(&memory[(rptFrame<<6)], 0, 128); //dirty rpte1 = SET_DIRTY(rpte1); } } rpte1 = SET_PINNED(rpte1); memory[rpta] = rpte1 = SET_REF(rpte1); memory[rpta+1] = rpte2; upta = (FRAME(rpte1)<<6) + UPTI(va); upte1 = memory[upta]; upte2 = memory[upta+1]; //stat memAccess++; if (DEFINED(upte1)) { // defined //stat memHits++; if (rwFlg) upte1 = SET_DIRTY(upte1); } else { // fault //stat memPageFaults++; uptFrame = getFrame(FRAME(memory[rpta])); upte1 = SET_DEFINED(uptFrame); if (PAGED(upte2)) { accessPage(SWAPPAGE(upte2), uptFrame, PAGE_READ); //stat pageReads++; //clean unless being written to if (rwFlg) upte1 = SET_DIRTY(upte1); else upte1 = CLEAR_DIRTY(upte1); } else { //dirty upte1 = SET_DIRTY(upte1); } } rpte1 = SET_PINNED(rpte1); memory[rpta] = rpte1; memory[upta] = upte1 = SET_REF(upte1); memory[upta+1] = upte2; return &memory[(FRAME(upte1)<<6) + FRAMEOFFSET(va)]; #else return &memory[va]; #endif } // end getMemAdr
int getFrame(int notme) { int frame; frame = getAvailableFrame(); if (frame >=0) return frame; // run clock int i, j, upta, frameToRemove; i = lastRpte; // i = 0x2400; // j = lastUpte; while(1){ // for(i=0x2400;i<0x3000;i+=2){ // printf("%x", i); if(DEFINED(memory[i])){ upta = FRAME(memory[i]); upta = (upta<<6); //double confirm int k; bool nothingInFrame = 1; for(k=upta;k<upta+64;k+=2){ if(DEFINED(memory[k])){ nothingInFrame = 0; break; } } if(nothingInFrame && FRAME(memory[i])!=notme){ frameToRemove = FRAME(memory[i]); lastRpte=i+2; memory[i] = CLEAR_DEFINED(memory[i]); memory[i] = CLEAR_REF(memory[i]); if(PAGED(memory[i+1]) && DIRTY(memory[i])){ memory[i+1] = accessPage(SWAPPAGE(memory[i+1]), frameToRemove, PAGE_OLD_WRITE); }else{ memory[i+1] = accessPage(0, frameToRemove, PAGE_NEW_WRITE); } memory[i+1] = SET_PAGED(memory[i+1]); memory[i] = SET_DIRTY(memory[i]); //possibly clear frame number return frameToRemove; // i can swap out this upt } // for(j=upta;j<upta+64;j+=2){ while(uptOffset < 64){ j = upta + uptOffset; if(DEFINED(memory[j])){ if(REFERENCED(memory[j])){ memory[j] = CLEAR_REF(memory[j]); }else{ //use this data frame frameToRemove = FRAME(memory[j]); lastRpte = i; memory[j] = CLEAR_DEFINED(memory[j]); memory[j] = CLEAR_REF(memory[j]); // memory[j] = SWAPPAGE(memory[j]); if(PAGED(memory[j+1]) && DIRTY(memory[j])){ memory[j+1] = accessPage(SWAPPAGE(memory[j+1]), frameToRemove, PAGE_OLD_WRITE); }else{ memory[j+1] = accessPage(0, frameToRemove, PAGE_NEW_WRITE); } memory[j+1] = SET_PAGED(memory[j+1]); uptOffset+=2; // may not need this line //need to loop through rest next time but if nothing dont remove this one return frameToRemove; } } uptOffset+=2; } uptOffset = 0; // } } i+=2; if(i==0x3000){ i=0x2400; } // } } // memory[(frameToRemove<<6)] return frame; }
unsigned short int *getMemAdr(int va, int rwFlg) { unsigned short int pa; int rpta, rpte1, rpte2; int upta, upte1, upte2; int rptFrame, uptFrame; rpta = 0x2400 + RPTI(va) + 0x40*curTask; // address of the root page table rpte1 = memory[rpta]; // get a word rpte2 = memory[rpta+1]; // get another word // turn off virtual addressing for system RAM if (va < 0x3000) return &memory[va]; #if MMU_ENABLE // printf("using memory Management\n"); if (DEFINED(rpte1)) { memHits++; // defined } else { memPageFaults++; // fault rptFrame = getFrame(-1); rpte1 = SET_DEFINED(rptFrame); // setting the frame bit in the user page table rpte1 = SET_DIRTY(rpte1); if (PAGED(rpte2)) // it exists in swap space { accessPage(SWAPPAGE(rpte2), rptFrame, PAGE_READ); } else { memset(&memory[(rptFrame<<6)], 0, 128); //sets 128 bytes to 0 why is it 128? why bitshift by 6? } } memory[rpta] = rpte1 = SET_REF(rpte1); // sets the referenced bit in the root page table memory[rpta+1] = rpte2; upta = (FRAME(rpte1)<<6) + UPTI(va); upte1 = memory[upta]; upte2 = memory[upta+1]; if (DEFINED(upte1)) { memHits++; // defined } else { memPageFaults++; // fault uptFrame = getFrame(FRAME(memory[rpta])); upte1 = SET_DEFINED(uptFrame); upte1 = SET_DIRTY(upte1); if (PAGED(upte2)) { accessPage(SWAPPAGE(upte2), uptFrame, PAGE_READ); } else { memset(&memory[(uptFrame<<6)], 0, 128); //sets 128 bytes to 0 why is it 128? why bitshift by 6? } } if(rwFlg){ memory[rpta] = SET_DIRTY(memory[rpta]); }else{ } memory[upta] = SET_REF(upte1); memory[upta+1] = upte2; return &memory[(FRAME(upte1)<<6) + FRAMEOFFSET(va)]; #else return &memory[va]; #endif } // end getMemAdr