page_table.cc revision 6658:f4de76601762
112027Sjungma@eit.uni-kl.de/* 212027Sjungma@eit.uni-kl.de * Copyright (c) 2003 The Regents of The University of Michigan 312027Sjungma@eit.uni-kl.de * All rights reserved. 412027Sjungma@eit.uni-kl.de * 512027Sjungma@eit.uni-kl.de * Redistribution and use in source and binary forms, with or without 612027Sjungma@eit.uni-kl.de * modification, are permitted provided that the following conditions are 712027Sjungma@eit.uni-kl.de * met: redistributions of source code must retain the above copyright 812027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer; 912027Sjungma@eit.uni-kl.de * redistributions in binary form must reproduce the above copyright 1012027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer in the 1112027Sjungma@eit.uni-kl.de * documentation and/or other materials provided with the distribution; 1212027Sjungma@eit.uni-kl.de * neither the name of the copyright holders nor the names of its 1312027Sjungma@eit.uni-kl.de * contributors may be used to endorse or promote products derived from 1412027Sjungma@eit.uni-kl.de * this software without specific prior written permission. 1512027Sjungma@eit.uni-kl.de * 1612027Sjungma@eit.uni-kl.de * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712027Sjungma@eit.uni-kl.de * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812027Sjungma@eit.uni-kl.de * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912027Sjungma@eit.uni-kl.de * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012027Sjungma@eit.uni-kl.de * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112027Sjungma@eit.uni-kl.de * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212027Sjungma@eit.uni-kl.de * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312027Sjungma@eit.uni-kl.de * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412027Sjungma@eit.uni-kl.de * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512027Sjungma@eit.uni-kl.de * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612027Sjungma@eit.uni-kl.de * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712027Sjungma@eit.uni-kl.de * 2812027Sjungma@eit.uni-kl.de * Authors: Steve Reinhardt 2912027Sjungma@eit.uni-kl.de * Ron Dreslinski 3012027Sjungma@eit.uni-kl.de * Ali Saidi 3112027Sjungma@eit.uni-kl.de */ 3212027Sjungma@eit.uni-kl.de 3312027Sjungma@eit.uni-kl.de/** 3412027Sjungma@eit.uni-kl.de * @file 3512027Sjungma@eit.uni-kl.de * Definitions of page table. 3612027Sjungma@eit.uni-kl.de */ 3712027Sjungma@eit.uni-kl.de#include <string> 3812027Sjungma@eit.uni-kl.de#include <map> 3912027Sjungma@eit.uni-kl.de#include <fstream> 4012027Sjungma@eit.uni-kl.de 4112027Sjungma@eit.uni-kl.de#include "arch/faults.hh" 4212027Sjungma@eit.uni-kl.de#include "base/bitfield.hh" 4312027Sjungma@eit.uni-kl.de#include "base/intmath.hh" 4412027Sjungma@eit.uni-kl.de#include "base/trace.hh" 4512027Sjungma@eit.uni-kl.de#include "config/the_isa.hh" 4612027Sjungma@eit.uni-kl.de#include "mem/page_table.hh" 4712027Sjungma@eit.uni-kl.de#include "sim/process.hh" 4812027Sjungma@eit.uni-kl.de#include "sim/sim_object.hh" 4912027Sjungma@eit.uni-kl.de#include "sim/system.hh" 5012027Sjungma@eit.uni-kl.de 5112027Sjungma@eit.uni-kl.deusing namespace std; 5212027Sjungma@eit.uni-kl.deusing namespace TheISA; 5312027Sjungma@eit.uni-kl.de 5412027Sjungma@eit.uni-kl.dePageTable::PageTable(Process *_process, Addr _pageSize) 5512027Sjungma@eit.uni-kl.de : pageSize(_pageSize), offsetMask(mask(floorLog2(_pageSize))), 5612027Sjungma@eit.uni-kl.de process(_process) 5712027Sjungma@eit.uni-kl.de{ 5812027Sjungma@eit.uni-kl.de assert(isPowerOf2(pageSize)); 5912027Sjungma@eit.uni-kl.de pTableCache[0].vaddr = 0; 6012027Sjungma@eit.uni-kl.de pTableCache[1].vaddr = 0; 6112027Sjungma@eit.uni-kl.de pTableCache[2].vaddr = 0; 6212027Sjungma@eit.uni-kl.de} 6312027Sjungma@eit.uni-kl.de 6412027Sjungma@eit.uni-kl.dePageTable::~PageTable() 6512027Sjungma@eit.uni-kl.de{ 6612027Sjungma@eit.uni-kl.de} 6712027Sjungma@eit.uni-kl.de 6812027Sjungma@eit.uni-kl.devoid 6912027Sjungma@eit.uni-kl.dePageTable::allocate(Addr vaddr, int64_t size) 7012027Sjungma@eit.uni-kl.de{ 7112027Sjungma@eit.uni-kl.de // starting address must be page aligned 7212027Sjungma@eit.uni-kl.de assert(pageOffset(vaddr) == 0); 7312027Sjungma@eit.uni-kl.de 7412027Sjungma@eit.uni-kl.de DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr+ size); 7512027Sjungma@eit.uni-kl.de 7612027Sjungma@eit.uni-kl.de for (; size > 0; size -= pageSize, vaddr += pageSize) { 7712027Sjungma@eit.uni-kl.de PTableItr iter = pTable.find(vaddr); 7812027Sjungma@eit.uni-kl.de 7912027Sjungma@eit.uni-kl.de if (iter != pTable.end()) { 8012027Sjungma@eit.uni-kl.de // already mapped 8112027Sjungma@eit.uni-kl.de fatal("PageTable::allocate: address 0x%x already mapped", 8212027Sjungma@eit.uni-kl.de vaddr); 8312027Sjungma@eit.uni-kl.de } 8412027Sjungma@eit.uni-kl.de 8512027Sjungma@eit.uni-kl.de pTable[vaddr] = TheISA::TlbEntry(process->M5_pid, vaddr, 8612027Sjungma@eit.uni-kl.de process->system->new_page()); 8712027Sjungma@eit.uni-kl.de updateCache(vaddr, pTable[vaddr]); 8812027Sjungma@eit.uni-kl.de } 8912027Sjungma@eit.uni-kl.de} 9012027Sjungma@eit.uni-kl.de 9112027Sjungma@eit.uni-kl.devoid 9212027Sjungma@eit.uni-kl.dePageTable::remap(Addr vaddr, int64_t size, Addr new_vaddr) 9312027Sjungma@eit.uni-kl.de{ 9412027Sjungma@eit.uni-kl.de assert(pageOffset(vaddr) == 0); 9512027Sjungma@eit.uni-kl.de assert(pageOffset(new_vaddr) == 0); 9612027Sjungma@eit.uni-kl.de 9712027Sjungma@eit.uni-kl.de DPRINTF(MMU, "moving pages from vaddr %08p to %08p, size = %d\n", vaddr, 9812027Sjungma@eit.uni-kl.de new_vaddr, size); 9912027Sjungma@eit.uni-kl.de 10012027Sjungma@eit.uni-kl.de for (; size > 0; size -= pageSize, vaddr += pageSize, new_vaddr += pageSize) { 10112027Sjungma@eit.uni-kl.de PTableItr iter = pTable.find(vaddr); 10212027Sjungma@eit.uni-kl.de 10312027Sjungma@eit.uni-kl.de assert(iter != pTable.end()); 10412027Sjungma@eit.uni-kl.de 10512027Sjungma@eit.uni-kl.de pTable[new_vaddr] = pTable[vaddr]; 10612027Sjungma@eit.uni-kl.de pTable.erase(vaddr); 10712027Sjungma@eit.uni-kl.de pTable[new_vaddr].updateVaddr(new_vaddr); 10812027Sjungma@eit.uni-kl.de updateCache(new_vaddr, pTable[new_vaddr]); 10912027Sjungma@eit.uni-kl.de } 11012027Sjungma@eit.uni-kl.de} 11112027Sjungma@eit.uni-kl.de 11212027Sjungma@eit.uni-kl.devoid 11312027Sjungma@eit.uni-kl.dePageTable::deallocate(Addr vaddr, int64_t size) 11412027Sjungma@eit.uni-kl.de{ 11512027Sjungma@eit.uni-kl.de assert(pageOffset(vaddr) == 0); 11612027Sjungma@eit.uni-kl.de 11712027Sjungma@eit.uni-kl.de DPRINTF(MMU, "Deallocating page: %#x-%#x\n", vaddr, vaddr+ size); 11812027Sjungma@eit.uni-kl.de 11912027Sjungma@eit.uni-kl.de for (; size > 0; size -= pageSize, vaddr += pageSize) { 12012027Sjungma@eit.uni-kl.de PTableItr iter = pTable.find(vaddr); 12112027Sjungma@eit.uni-kl.de 12212027Sjungma@eit.uni-kl.de assert(iter != pTable.end()); 12312027Sjungma@eit.uni-kl.de 12412027Sjungma@eit.uni-kl.de pTable.erase(vaddr); 12512027Sjungma@eit.uni-kl.de } 12612027Sjungma@eit.uni-kl.de 12712027Sjungma@eit.uni-kl.de} 12812027Sjungma@eit.uni-kl.de 12912027Sjungma@eit.uni-kl.debool 13012027Sjungma@eit.uni-kl.dePageTable::lookup(Addr vaddr, TheISA::TlbEntry &entry) 13112027Sjungma@eit.uni-kl.de{ 13212027Sjungma@eit.uni-kl.de Addr page_addr = pageAlign(vaddr); 13312027Sjungma@eit.uni-kl.de 13412027Sjungma@eit.uni-kl.de if (pTableCache[0].vaddr == page_addr) { 13512027Sjungma@eit.uni-kl.de entry = pTableCache[0].entry; 13612027Sjungma@eit.uni-kl.de return true; 13712027Sjungma@eit.uni-kl.de } 13812027Sjungma@eit.uni-kl.de if (pTableCache[1].vaddr == page_addr) { 13912027Sjungma@eit.uni-kl.de entry = pTableCache[1].entry; 14012027Sjungma@eit.uni-kl.de return true; 14112027Sjungma@eit.uni-kl.de } 14212027Sjungma@eit.uni-kl.de if (pTableCache[2].vaddr == page_addr) { 14312027Sjungma@eit.uni-kl.de entry = pTableCache[2].entry; 14412027Sjungma@eit.uni-kl.de return true; 14512027Sjungma@eit.uni-kl.de } 14612027Sjungma@eit.uni-kl.de 14712027Sjungma@eit.uni-kl.de PTableItr iter = pTable.find(page_addr); 14812027Sjungma@eit.uni-kl.de 14912027Sjungma@eit.uni-kl.de if (iter == pTable.end()) { 15012027Sjungma@eit.uni-kl.de return false; 15112027Sjungma@eit.uni-kl.de } 15212027Sjungma@eit.uni-kl.de 15312027Sjungma@eit.uni-kl.de updateCache(page_addr, iter->second); 15412027Sjungma@eit.uni-kl.de entry = iter->second; 15512027Sjungma@eit.uni-kl.de return true; 15612027Sjungma@eit.uni-kl.de} 15712027Sjungma@eit.uni-kl.de 15812027Sjungma@eit.uni-kl.debool 15912027Sjungma@eit.uni-kl.dePageTable::translate(Addr vaddr, Addr &paddr) 16012027Sjungma@eit.uni-kl.de{ 16112027Sjungma@eit.uni-kl.de TheISA::TlbEntry entry; 16212027Sjungma@eit.uni-kl.de if (!lookup(vaddr, entry)) { 16312027Sjungma@eit.uni-kl.de DPRINTF(MMU, "Couldn't Translate: %#x\n", vaddr); 16412027Sjungma@eit.uni-kl.de return false; 16512027Sjungma@eit.uni-kl.de } 16612027Sjungma@eit.uni-kl.de paddr = pageOffset(vaddr) + entry.pageStart(); 16712027Sjungma@eit.uni-kl.de DPRINTF(MMU, "Translating: %#x->%#x\n", vaddr, paddr); 16812027Sjungma@eit.uni-kl.de return true; 16912027Sjungma@eit.uni-kl.de} 17012027Sjungma@eit.uni-kl.de 17112027Sjungma@eit.uni-kl.deFault 17212027Sjungma@eit.uni-kl.dePageTable::translate(RequestPtr req) 17312027Sjungma@eit.uni-kl.de{ 17412027Sjungma@eit.uni-kl.de Addr paddr; 17512027Sjungma@eit.uni-kl.de assert(pageAlign(req->getVaddr() + req->getSize() - 1) 17612027Sjungma@eit.uni-kl.de == pageAlign(req->getVaddr())); 17712027Sjungma@eit.uni-kl.de if (!translate(req->getVaddr(), paddr)) { 17812027Sjungma@eit.uni-kl.de return Fault(new GenericPageTableFault(req->getVaddr())); 17912027Sjungma@eit.uni-kl.de } 18012027Sjungma@eit.uni-kl.de req->setPaddr(paddr); 18112027Sjungma@eit.uni-kl.de if ((paddr & (pageSize - 1)) + req->getSize() > pageSize) { 18212027Sjungma@eit.uni-kl.de panic("Request spans page boundaries!\n"); 18312027Sjungma@eit.uni-kl.de return NoFault; 18412027Sjungma@eit.uni-kl.de } 18512027Sjungma@eit.uni-kl.de return NoFault; 18612027Sjungma@eit.uni-kl.de} 18712027Sjungma@eit.uni-kl.de 18812027Sjungma@eit.uni-kl.devoid 18912027Sjungma@eit.uni-kl.dePageTable::serialize(std::ostream &os) 19012027Sjungma@eit.uni-kl.de{ 19112027Sjungma@eit.uni-kl.de paramOut(os, "ptable.size", pTable.size()); 19212027Sjungma@eit.uni-kl.de 19312027Sjungma@eit.uni-kl.de PTable::size_type count = 0; 19412027Sjungma@eit.uni-kl.de 19512027Sjungma@eit.uni-kl.de PTableItr iter = pTable.begin(); 19612027Sjungma@eit.uni-kl.de PTableItr end = pTable.end(); 19712027Sjungma@eit.uni-kl.de while (iter != end) { 19812027Sjungma@eit.uni-kl.de os << "\n[" << csprintf("%s.Entry%d", process->name(), count) << "]\n"; 19912027Sjungma@eit.uni-kl.de 20012027Sjungma@eit.uni-kl.de paramOut(os, "vaddr", iter->first); 20112027Sjungma@eit.uni-kl.de iter->second.serialize(os); 20212027Sjungma@eit.uni-kl.de 20312027Sjungma@eit.uni-kl.de ++iter; 20412027Sjungma@eit.uni-kl.de ++count; 20512027Sjungma@eit.uni-kl.de } 20612027Sjungma@eit.uni-kl.de assert(count == pTable.size()); 20712027Sjungma@eit.uni-kl.de} 20812027Sjungma@eit.uni-kl.de 20912027Sjungma@eit.uni-kl.devoid 21012027Sjungma@eit.uni-kl.dePageTable::unserialize(Checkpoint *cp, const std::string §ion) 21112027Sjungma@eit.uni-kl.de{ 21212027Sjungma@eit.uni-kl.de int i = 0, count; 21312027Sjungma@eit.uni-kl.de paramIn(cp, section, "ptable.size", count); 21412027Sjungma@eit.uni-kl.de Addr vaddr; 21512027Sjungma@eit.uni-kl.de TheISA::TlbEntry *entry; 21612027Sjungma@eit.uni-kl.de 21712027Sjungma@eit.uni-kl.de pTable.clear(); 21812027Sjungma@eit.uni-kl.de 21912027Sjungma@eit.uni-kl.de while(i < count) { 22012027Sjungma@eit.uni-kl.de paramIn(cp, csprintf("%s.Entry%d", process->name(), i), "vaddr", vaddr); 22112027Sjungma@eit.uni-kl.de entry = new TheISA::TlbEntry(); 22212027Sjungma@eit.uni-kl.de entry->unserialize(cp, csprintf("%s.Entry%d", process->name(), i)); 22312027Sjungma@eit.uni-kl.de pTable[vaddr] = *entry; 22412027Sjungma@eit.uni-kl.de ++i; 22512027Sjungma@eit.uni-kl.de } 22612027Sjungma@eit.uni-kl.de} 22712027Sjungma@eit.uni-kl.de 22812027Sjungma@eit.uni-kl.de