Example #1
1
    /* translate virtual address to pysical address. handles tlbmiss, page faults,
    loads page to physical memory in case of page fault */
    int translate(VirtualAddress address, PhysicalAddress &physicalAddress)
    {
        int rval = status_success;

        PageEntry pageEntry;    /* the page entry from page table. We use this for lookup in page table, and get frame no from it */
        Page page;              /* in case we need to get page from backing store and add it to physical memory */
        FrameNumber frameno;    /* in case we need to add page to physical memory */
        PageNumber pageno = -1; /* page number we will lookkup. get this from virtual address */
        int offset = -1;        /* offset we will lookkup. get this from virtual address */
        bool pagehit = false;   /* flags */
        bool tlbhit = false;


        /* break address to page no offset */
        zlog(ZLOG_LOC, "VirtualMemoryManager::translate- get page number and offset\n");
        pageno = getPageNumberFromLogicalAddress(address);
        offset = getOffsetFromLogicalAddress(address);

        /* we are storing he required frame number in the frameno value, weather we get a hit
        from tlb, page table or page fault */

        /* check in tlb */
        tlb.lookup(pageno, frameno, tlbhit);
        if(true == tlbhit)
        {
            /* we are done here */
            zlog(ZLOG_LOC, "VirtualMemoryManager::translate - tlbhit !!\n");
            tlbhits++;
        }
        else
        {
            /* check in page table tlb miss */
            zlog(ZLOG_LOC, "VirtualMemoryManager::translate- get page entry for page no : %d\n", pageno);
            if(status_success != pageTable.lookup(pageno, pageEntry))
            {
                rval = status_failure;
                zlog(ZLOG_LOC, "VirtualMemoryManager::translate- unable to get page table entry\n");
                goto exit1;
            }

            /* check if this is a page fault */
            zlog(ZLOG_LOC, "VirtualMemoryManager::translate- check for page fault\n");
            if(true == pageEntry.isValid)
            {
                /* we are done */
                zlog(ZLOG_LOC, "VirtualMemoryManager::translate- page hit! \n");
                frameno = pageEntry.frameNumber;
                pagehit = true;

                /* update counter */
                pagehits++;
            }

            /* page fault code */
            if(false == pagehit)
            {
                /* update counter */
                pagefaults++;

                /* get page from backing store */
                zlog(ZLOG_LOC, "VirtualMemoryManager::translate- page fault on page : %d, reading block : %d from backing store\n",
                            pageno, pageno);
                if(status_success != backingStore.getPage(page, pageno*PageSize, PageSize))
                {
                    zlog(ZLOG_LOC, "VirtualMemoryManager::translate- unable to get page form backing store\n");
                    rval = status_failure;
                    goto exit2;
                }

                /* add to physical memory */
                zlog(ZLOG_LOC, "VirtualMemoryManager::translate- putting the page in physical memory\n");
                if(status_success != physicalMemory.addPage(page, frameno))
                {
                    zlog(ZLOG_LOC, "VirtualMemoryManager::translate- unable to add page to physical memory\n");
                    rval = status_failure;
                    goto exit2;
                }

                /* update page entry */
                zlog(ZLOG_LOC, "VirtualMemoryManager::translate- update page Entry \n");
                pageEntry.frameNumber = frameno;
                pageEntry.isModified  = false;
                pageEntry.isValid = true;

                /* add page entry to page table */
                zlog(ZLOG_LOC, "VirtualMemoryManager::translate- update page table\n");
                if(status_success != pageTable.updatePageEntry(pageEntry, pageno))
                {
                    zlog(ZLOG_LOC, "VirtualMemoryManager::translate- unable to add entry to page table\n");
                    rval = status_failure;
                    goto exit2;
                }

                zlog(ZLOG_LOC, "VirtualMemoryManager::translate- lookup page table again\n");
                frameno = pageEntry.frameNumber;
                pagehit = true;
            }

            /* by this time we have a valid page frame mapping
                if there was a tlb miss, update tlb table */
            if(false == tlbhit)
            {
                TlbEntry tlbEntry;
                tlbEntry.pageNumber = pageno;
                tlbEntry.frameNumber = frameno;
                tlbEntry.valid = true;

                tlb.addEntry(tlbEntry);
            }
        }

        /* page entry contains the frame number required */
        physicalAddress = (frameno << numBitsForFrameOffset) + offset;

    exit2:
    exit1:
        return rval;
    }
Example #2
0
void *MMU::palloc(size_t numberOfPages)
{
    size_t contiguousFoundPages = 0;
    size_t retpde = 0, retpte = 0;
    void *retval = nullptr;
    for (size_t pde = 0; pde < 1024 && contiguousFoundPages != numberOfPages; ++pde) {
        PageTable table = getOrCreateTable(pde);

        // look through page table
        for (size_t pte = 0; pte < 1024; ++pte) {
            PageEntry entry = table.entryAtIndex(pte);
            if (!entry.getFlag(kPresentBit)) { // found a page that isn't present (is available)
                if (contiguousFoundPages == 0) { // this is the first available page, set our return pointer to it
                    retpde = pde;
                    retpte = pte;
                }

                ++contiguousFoundPages;
                if (contiguousFoundPages == numberOfPages) { // done
                    retval = (void *) ((retpde << 22) | (retpte << 12));
                    break;
                }
            } else if (contiguousFoundPages) { // current page is used, reset our contiguous page count
                retval = nullptr;
                contiguousFoundPages = 0;
            }
        }
    }

    if (retval) { // if we succeeded in finding space
        allocatePages(retval, numberOfPages);
    }

    return retval;
}
Example #3
0
int getPhysicalAddr(unsigned int x){

	unsigned int pageNum = getPageNum(x) + 1;
	unsigned int offset = getPageOff(x);

	return ((ptable.getFrameNumber(pageNum)-1) * 256) + offset;
}
Example #4
0
int main(int argc, char* argv[]){
	size_t pos = 0;
	int count = 0;

	string input;
	string fOutput;

	//get the input yo
	if(argc > 1){
		input = argv[1];
	} else {
		cerr << "Failed, usage is memTrans <InputFile> \n";
		exit(EXIT_FAILURE);
	}
	
	ifstream fRead(input);
	while(!fRead.eof()){

		getline(fRead,fOutput);
		istringstream r(fOutput);

		unsigned int fOut;
		r >> fOut;

		if(fOut != 0){
		    count++;
			signed int value = getValue(fOut);

			cout << "Virtual address: " << fOut << " ";
			cout << "Physical address: " << getPhysicalAddr(fOut) << " ";
			cout << "Value: " << value << std::endl;
		}
		fOut = 0;
	}

	//close the damn reader
	fRead.close();
	//output needed statistics
	cout << "Number of Translated Addresses = " << count << std::endl;
	cout << "Page faults = " << ptable.getCounter() << std::endl;
	cout << "Page Fault Rate = " << ((double)ptable.getCounter()/(double)count) << std::endl;
	cout << "TLB hits = " << working_tlb.getHits() << std::endl;
	cout << "TLB Hit Rate = = " << ((double)working_tlb.getHits()/(double)count) << std::endl;
	
	//cout << "All Done <(^_^)^" << std::endl;
	return 0;
  }
Example #5
0
int MMU::pfree(void *startOfMemoryRange, size_t numberOfPages)
{
    uint32_t virtualAddress = (uint32_t) startOfMemoryRange;

    if (!numberOfPages) return -1;

    while (numberOfPages--) {
        uint32_t pdeIndex = virtualAddress >> 22;
        uint32_t pteIndex = virtualAddress >> 12 & 0x03FF;
        PageTable table = PageTableForDirectoryIndex(pdeIndex);
        PageEntry pte = table.entryAtIndex(pteIndex);
        _pageFrameAllocator.free(pte.address());
        table.setEntry(pteIndex, PageEntry(0));

        virtualAddress += 0x1000;
    }

    _flush();

    return 0;
}
Example #6
0
void MMU::allocatePages(void *address, size_t numberOfPages)
{
    uintptr_t virtualAddress = reinterpret_cast<uintptr_t>(address);
    uint32_t currpde = virtualAddress >> 22;
    uint32_t currpte = virtualAddress >> 12 & 0x03FF;
    size_t pagesLeft = numberOfPages;
    while (pagesLeft > 0) { // map the pages
        PageTable table = PageTableForDirectoryIndex(currpde);
        PageEntry entry = PageEntry(_pageFrameAllocator.alloc());
        entry.setFlags(kPresentBit | kReadWriteBit);
        table.setEntry(currpte, entry);

        ++currpte;
        --pagesLeft;

        // move to next PDE if needed
        if (currpte > 1023) {
            ++currpde;
            currpte = 0;
        }
    }

    _flush();
}
Example #7
0
File: kernel.C Project: vandanab/OS
int main() {

    GDT::init();
    Console::init();
    IDT::init();
    ExceptionHandler::init_dispatcher();
    IRQ::init();
    InterruptHandler::init_dispatcher();


    /* -- EXAMPLE OF AN EXCEPTION HANDLER -- */

    class DBZ_Handler : public ExceptionHandler {
      public:
      virtual void handle_exception(REGS * _regs) {
        Console::puts("DIVISION BY ZERO!\n");
        for(;;);
      }
    } dbz_handler;

    ExceptionHandler::register_handler(0, &dbz_handler);

    /* -- INITIALIZE FRAME POOLS -- */

    FramePool kernel_mem_pool(KERNEL_POOL_START_FRAME,
                              KERNEL_POOL_SIZE,
                              0);
    unsigned long process_mem_pool_info_frame = kernel_mem_pool.get_frame();
    FramePool process_mem_pool(PROCESS_POOL_START_FRAME,
                               PROCESS_POOL_SIZE,
                               process_mem_pool_info_frame);
    process_mem_pool.mark_inaccessible(MEM_HOLE_START_FRAME, MEM_HOLE_SIZE);

    /* -- INITIALIZE MEMORY (PAGING) -- */

    /* ---- INSTALL PAGE FAULT HANDLER -- */

    class PageFault_Handler : public ExceptionHandler {
      public:
      virtual void handle_exception(REGS * _regs) {
        PageTable::handle_fault(_regs);
      }
    } pagefault_handler;

    ExceptionHandler::register_handler(14, &pagefault_handler);
    
    /* ---- INITIALIZE THE PAGE TABLE -- */
    
    PageTable::init_paging(&kernel_mem_pool,
                           &process_mem_pool,
                           4 MB);
		
    PageTable pt;

    pt.load();

    PageTable::enable_paging();

    /* -- INITIALIZE THE TIMER (we use a very simple timer).-- */
    
    SimpleTimer timer(100); /* timer ticks every 10ms. */
    InterruptHandler::register_handler(0, &timer);

    /* NOTE: The timer chip starts periodically firing as
             soon as we enable interrupts.
             It is important to install a timer handler, as we
             would get a lot of uncaptured interrupts otherwise. */

    /* -- ENABLE INTERRUPTS -- */

    Machine::enable_interrupts();

    /* -- MOST OF WHAT WE NEED IS SETUP. THE KERNEL CAN START. */

    Console::puts("Hello World!\n");

    /* -- GENERATE MEMORY REFERENCES */

    int *foo = (int *) FAULT_ADDR;
    int i;

    for (i=0; i<NACCESS; i++) {
       foo[i] = i;
    }

    for (i=0; i<NACCESS; i++) {
       if(foo[i] != i) {
          Console::puts("TEST FAILED for access number:");
          Console::putui(i);
          Console::puts("\n");
          break;
       }
    }
    if(i == NACCESS) {
       Console::puts("TEST PASSED\n");
    }

    /* -- NOW LOOP FOREVER */
    for(;;);

    /* -- WE DO THE FOLLOWING TO KEEP THE COMPILER HAPPY. */
    return 1;
}
Example #8
0
signed int getValue(unsigned int x){
  
	unsigned int pageNum = getPageNum(x) + 1;
	unsigned int offset = getPageOff(x);

 	//cout << pageNum;
	if(working_tlb.check(pageNum)){
		//need more things here, like returning the actual physical address
		return (ptable.getValue(working_tlb.getFrameNumber(pageNum), offset));
	}
	else if(ptable.checkPageTable(pageNum)){
		//if in the page table, return the physical address
		working_tlb.addEntry(pageNum, ptable.getFrameNumber(pageNum));
		return (ptable.getValue(ptable.getFrameNumber(pageNum), offset));
	}
	else if((!(ptable.checkPageTable(pageNum)) && !(working_tlb.check(pageNum)))){
		//up the page fault counter
		Frame f;
		f.setVal(getFrameDat(pageNum));
		f.setPageNumber(pageNum);
		ptable.addEntry(f);
		ptable.incCounter();
		working_tlb.addEntry(pageNum, ptable.getFrameNumber(pageNum));
		return (ptable.getValue(ptable.getFrameNumber(pageNum), offset));
	}
}
Example #9
0
int main(int argc, char **argv)
{
    //cout<<argc<<endl;
    //srand((int)time(NULL));
    /**
     * Configuration
     */
    for(int i = 1; i < argc; i++)
    {
        if(i == 1)
        {
            if(strcmp(argv[i], "1") == 0)
            {
                debugMode = true;
            } else {
                debugMode = false;
            }
        } else if(i == 2)
        {
            sscanf(argv[i],"%d",&numberOfTLBEntries);
            numberOfTLBEntries = getNearestBiggerPowerOfTwo(numberOfTLBEntries);
        } else if(i == 3)
        {
            sscanf(argv[i],"%d",&numberOfPageFrames);
            numberOfPageFrames = getNearestBiggerPowerOfTwo(numberOfPageFrames);
        } else if(i == 4)
        {
            sscanf(argv[i],"%d",&numberOfInstructions);
        } else if(i == 5)
        {
            sscanf(argv[i],"%d",&pageChangeAfterInstructionCount);
        }
    }
    /**
     * Initial State
     */

    cout<<"Debug Mode: "<<debugMode<<endl;
    cout<<"Total number of TLB Entries: "<<numberOfTLBEntries<<endl;
    cout<<"Total number of Page Frames: "<<numberOfPageFrames<<endl;
    cout<<"Total number of Instructions: "<<numberOfInstructions<<endl;
    cout<<"Total number of Virtual Pages: "<<numberOfVirtualPages<<endl;
    cout<<"On Average Virtual Address Page Changes after: "<<pageChangeAfterInstructionCount<<endl;

    /**
     * Operation starts...
     * Create a pageTable, a TLB
     */

    PageTable pageTable;
    TranslationLookaheadBuffer tlb(numberOfTLBEntries);
    pageTable.setTranslationLookaheadBuffer(&tlb);

    for(int i = 0; i < numberOfInstructions; i++)
    {
        Instruction nextInstruction = getNextInstruction();
        if(debugMode)
        {
            nextInstruction.print();
        }
        LookupResult l = tlb.lookup(nextInstruction.msbAddress);
        if(l.isFound == true)
        {
            //do nothing
        } else
        {
            if(debugMode)
            {
                printf("Cache Miss for page %02x\n",nextInstruction.msbAddress);
            }
            totalNumberOfCacheMisses += 1;
            l = pageTable.lookup(nextInstruction.msbAddress);
            if(l.isFound == true)
            {
                //do nothing
            } else
            {
                if(debugMode)
                {
                    printf("Page fault on page %02x\n",nextInstruction.msbAddress);
                }
                totalNumberOfPageFaults += 1;
                pageTable.insert(nextInstruction.msbAddress);
                l = pageTable.lookup(nextInstruction.msbAddress);
            }
            tlb.insert(nextInstruction.msbAddress, l.frameIndex);
            //pageTable.insert(nextInstruction.msbAddress);
            //l = pageTable.lookup(nextInstruction.msbAddress);
        }
        //
        if(debugMode)
        {
            printf("Virtual Address: %02x%02x, Physical Address: %02x%02x\n", nextInstruction.msbAddress, nextInstruction.lsbAddress, l.frameIndex, nextInstruction.lsbAddress);
        }
    }
    cout<<"Total number of Cache Misses: "<<totalNumberOfCacheMisses<<endl;
    cout<<"Total number of Page Faults: "<<totalNumberOfPageFaults<<endl;
    cout<<"Total number of Page Used: "<<pageTable.getUsedPageCount()<<endl;
    cout<<"Total number of Page Changed: "<<pageChangeCount<<endl;

    /*TranslationLookaheadBuffer tlb;
    unsigned char accessPattern[] = "ABACBDADEDAEBAC";
    for(int i = 0; i < 15; i++)
    {
        cout<<i<<","<<accessPattern[i]<<endl;
        LookupResult result = tlb.lookup(accessPattern[i]);
        if(result.isFound)
        {
            tlb.print();
        } else {
            cout<<"Cache Miss"<<endl;
            tlb.insert(accessPattern[i],accessPattern[i]);
            tlb.print();
        }
    }*/
    return 0;
}