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;
    }