page_table.cc revision 12461
12379SN/A/*
210298Salexandru.dutu@amd.com * Copyright (c) 2014 Advanced Micro Devices, Inc.
32379SN/A * Copyright (c) 2003 The Regents of The University of Michigan
42379SN/A * All rights reserved.
52379SN/A *
62379SN/A * Redistribution and use in source and binary forms, with or without
72379SN/A * modification, are permitted provided that the following conditions are
82379SN/A * met: redistributions of source code must retain the above copyright
92379SN/A * notice, this list of conditions and the following disclaimer;
102379SN/A * redistributions in binary form must reproduce the above copyright
112379SN/A * notice, this list of conditions and the following disclaimer in the
122379SN/A * documentation and/or other materials provided with the distribution;
132379SN/A * neither the name of the copyright holders nor the names of its
142379SN/A * contributors may be used to endorse or promote products derived from
152379SN/A * this software without specific prior written permission.
162379SN/A *
172379SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182379SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192379SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202379SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212379SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222379SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232379SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242379SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252379SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262379SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272379SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282665Ssaidi@eecs.umich.edu *
292665Ssaidi@eecs.umich.edu * Authors: Steve Reinhardt
302665Ssaidi@eecs.umich.edu *          Ron Dreslinski
313311Ssaidi@eecs.umich.edu *          Ali Saidi
322379SN/A */
332379SN/A
342379SN/A/**
352379SN/A * @file
3610298Salexandru.dutu@amd.com * Definitions of functional page table.
372379SN/A */
3811793Sbrandon.potter@amd.com#include "mem/page_table.hh"
3911793Sbrandon.potter@amd.com
402379SN/A#include <string>
412379SN/A
422379SN/A#include "base/trace.hh"
438232Snate@binkert.org#include "debug/MMU.hh"
447678Sgblack@eecs.umich.edu#include "sim/faults.hh"
4511800Sbrandon.potter@amd.com#include "sim/serialize.hh"
462379SN/A
472399SN/Ausing namespace std;
482379SN/A
492399SN/Avoid
5012448Sgabeblack@google.comEmulationPageTable::map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags)
512399SN/A{
5210558Salexandru.dutu@amd.com    bool clobber = flags & Clobber;
532399SN/A    // starting address must be page aligned
542399SN/A    assert(pageOffset(vaddr) == 0);
552399SN/A
5612448Sgabeblack@google.com    DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr + size);
573311Ssaidi@eecs.umich.edu
5812448Sgabeblack@google.com    while (size > 0) {
5912442Sgabeblack@google.com        auto it = pTable.find(vaddr);
6012442Sgabeblack@google.com        if (it != pTable.end()) {
6112461Sgabeblack@google.com            // already mapped
6212461Sgabeblack@google.com            panic_if(!clobber,
6312461Sgabeblack@google.com                     "EmulationPageTable::allocate: addr %#x already mapped",
6412461Sgabeblack@google.com                     vaddr);
6512461Sgabeblack@google.com            it->second = Entry(paddr, flags);
6612442Sgabeblack@google.com        } else {
6712461Sgabeblack@google.com            pTable.emplace(vaddr, Entry(paddr, flags));
682399SN/A        }
692399SN/A
7012448Sgabeblack@google.com        size -= pageSize;
7112448Sgabeblack@google.com        vaddr += pageSize;
7212448Sgabeblack@google.com        paddr += pageSize;
732399SN/A    }
742399SN/A}
752399SN/A
765877Shsul@eecs.umich.eduvoid
7712448Sgabeblack@google.comEmulationPageTable::remap(Addr vaddr, int64_t size, Addr new_vaddr)
785877Shsul@eecs.umich.edu{
795877Shsul@eecs.umich.edu    assert(pageOffset(vaddr) == 0);
805877Shsul@eecs.umich.edu    assert(pageOffset(new_vaddr) == 0);
815877Shsul@eecs.umich.edu
825877Shsul@eecs.umich.edu    DPRINTF(MMU, "moving pages from vaddr %08p to %08p, size = %d\n", vaddr,
835877Shsul@eecs.umich.edu            new_vaddr, size);
845877Shsul@eecs.umich.edu
8512448Sgabeblack@google.com    while (size > 0) {
8612442Sgabeblack@google.com        auto new_it = pTable.find(new_vaddr);
8712442Sgabeblack@google.com        auto old_it = pTable.find(vaddr);
8812442Sgabeblack@google.com        assert(old_it != pTable.end() && new_it == pTable.end());
895877Shsul@eecs.umich.edu
9012442Sgabeblack@google.com        new_it->second = old_it->second;
9112442Sgabeblack@google.com        pTable.erase(old_it);
9212448Sgabeblack@google.com        size -= pageSize;
9312448Sgabeblack@google.com        vaddr += pageSize;
9412448Sgabeblack@google.com        new_vaddr += pageSize;
955877Shsul@eecs.umich.edu    }
965877Shsul@eecs.umich.edu}
975877Shsul@eecs.umich.edu
985877Shsul@eecs.umich.eduvoid
9912448Sgabeblack@google.comEmulationPageTable::getMappings(std::vector<std::pair<Addr, Addr>> *addr_maps)
10011886Sbrandon.potter@amd.com{
10111886Sbrandon.potter@amd.com    for (auto &iter : pTable)
10212461Sgabeblack@google.com        addr_maps->push_back(make_pair(iter.first, iter.second.paddr));
10311886Sbrandon.potter@amd.com}
10411886Sbrandon.potter@amd.com
10511886Sbrandon.potter@amd.comvoid
10612448Sgabeblack@google.comEmulationPageTable::unmap(Addr vaddr, int64_t size)
1075877Shsul@eecs.umich.edu{
1085877Shsul@eecs.umich.edu    assert(pageOffset(vaddr) == 0);
1095877Shsul@eecs.umich.edu
11012461Sgabeblack@google.com    DPRINTF(MMU, "Unmapping page: %#x-%#x\n", vaddr, vaddr + size);
1115877Shsul@eecs.umich.edu
11212448Sgabeblack@google.com    while (size > 0) {
11312442Sgabeblack@google.com        auto it = pTable.find(vaddr);
11412442Sgabeblack@google.com        assert(it != pTable.end());
11512442Sgabeblack@google.com        pTable.erase(it);
11612448Sgabeblack@google.com        size -= pageSize;
11712448Sgabeblack@google.com        vaddr += pageSize;
1185877Shsul@eecs.umich.edu    }
1195877Shsul@eecs.umich.edu}
1205877Shsul@eecs.umich.edu
1212399SN/Abool
12212448Sgabeblack@google.comEmulationPageTable::isUnmapped(Addr vaddr, int64_t size)
1238600Ssteve.reinhardt@amd.com{
1248600Ssteve.reinhardt@amd.com    // starting address must be page aligned
1258600Ssteve.reinhardt@amd.com    assert(pageOffset(vaddr) == 0);
1268600Ssteve.reinhardt@amd.com
12712448Sgabeblack@google.com    for (int64_t offset = 0; offset < size; offset += pageSize)
12812448Sgabeblack@google.com        if (pTable.find(vaddr + offset) != pTable.end())
1298600Ssteve.reinhardt@amd.com            return false;
1308600Ssteve.reinhardt@amd.com
1318600Ssteve.reinhardt@amd.com    return true;
1328600Ssteve.reinhardt@amd.com}
1338600Ssteve.reinhardt@amd.com
13412461Sgabeblack@google.comconst EmulationPageTable::Entry *
13512455Sgabeblack@google.comEmulationPageTable::lookup(Addr vaddr)
1362399SN/A{
1372399SN/A    Addr page_addr = pageAlign(vaddr);
1385004Sgblack@eecs.umich.edu    PTableItr iter = pTable.find(page_addr);
13912448Sgabeblack@google.com    if (iter == pTable.end())
14012455Sgabeblack@google.com        return nullptr;
14112461Sgabeblack@google.com    return &(iter->second);
1422399SN/A}
1432399SN/A
1445004Sgblack@eecs.umich.edubool
14512448Sgabeblack@google.comEmulationPageTable::translate(Addr vaddr, Addr &paddr)
1465004Sgblack@eecs.umich.edu{
14712461Sgabeblack@google.com    const Entry *entry = lookup(vaddr);
14812455Sgabeblack@google.com    if (!entry) {
1495183Ssaidi@eecs.umich.edu        DPRINTF(MMU, "Couldn't Translate: %#x\n", vaddr);
1505004Sgblack@eecs.umich.edu        return false;
1515183Ssaidi@eecs.umich.edu    }
15212461Sgabeblack@google.com    paddr = pageOffset(vaddr) + entry->paddr;
1535183Ssaidi@eecs.umich.edu    DPRINTF(MMU, "Translating: %#x->%#x\n", vaddr, paddr);
1545004Sgblack@eecs.umich.edu    return true;
1555004Sgblack@eecs.umich.edu}
1562399SN/A
1572394SN/AFault
15812448Sgabeblack@google.comEmulationPageTable::translate(RequestPtr req)
1592394SN/A{
1602532SN/A    Addr paddr;
16112448Sgabeblack@google.com    assert(pageAlign(req->getVaddr() + req->getSize() - 1) ==
16212448Sgabeblack@google.com           pageAlign(req->getVaddr()));
16312448Sgabeblack@google.com    if (!translate(req->getVaddr(), paddr))
1645004Sgblack@eecs.umich.edu        return Fault(new GenericPageTableFault(req->getVaddr()));
1652532SN/A    req->setPaddr(paddr);
1665004Sgblack@eecs.umich.edu    if ((paddr & (pageSize - 1)) + req->getSize() > pageSize) {
1675004Sgblack@eecs.umich.edu        panic("Request spans page boundaries!\n");
1685004Sgblack@eecs.umich.edu        return NoFault;
1695004Sgblack@eecs.umich.edu    }
1705004Sgblack@eecs.umich.edu    return NoFault;
1712394SN/A}
1723311Ssaidi@eecs.umich.edu
1733311Ssaidi@eecs.umich.eduvoid
17412448Sgabeblack@google.comEmulationPageTable::serialize(CheckpointOut &cp) const
1753311Ssaidi@eecs.umich.edu{
17610905Sandreas.sandberg@arm.com    paramOut(cp, "ptable.size", pTable.size());
1773320Shsul@eecs.umich.edu
1786227Snate@binkert.org    PTable::size_type count = 0;
17910905Sandreas.sandberg@arm.com    for (auto &pte : pTable) {
18010905Sandreas.sandberg@arm.com        ScopedCheckpointSection sec(cp, csprintf("Entry%d", count++));
1813311Ssaidi@eecs.umich.edu
18210905Sandreas.sandberg@arm.com        paramOut(cp, "vaddr", pte.first);
18312461Sgabeblack@google.com        paramOut(cp, "paddr", pte.second.paddr);
18412461Sgabeblack@google.com        paramOut(cp, "flags", pte.second.flags);
1853311Ssaidi@eecs.umich.edu    }
1863311Ssaidi@eecs.umich.edu    assert(count == pTable.size());
1873311Ssaidi@eecs.umich.edu}
1883311Ssaidi@eecs.umich.edu
1893311Ssaidi@eecs.umich.eduvoid
19012448Sgabeblack@google.comEmulationPageTable::unserialize(CheckpointIn &cp)
1913311Ssaidi@eecs.umich.edu{
19210905Sandreas.sandberg@arm.com    int count;
19310905Sandreas.sandberg@arm.com    paramIn(cp, "ptable.size", count);
1943311Ssaidi@eecs.umich.edu
19510905Sandreas.sandberg@arm.com    for (int i = 0; i < count; ++i) {
19610905Sandreas.sandberg@arm.com        ScopedCheckpointSection sec(cp, csprintf("Entry%d", i));
1973311Ssaidi@eecs.umich.edu
19812461Sgabeblack@google.com        Addr vaddr;
19912461Sgabeblack@google.com        UNSERIALIZE_SCALAR(vaddr);
20012461Sgabeblack@google.com        Addr paddr;
20112461Sgabeblack@google.com        uint64_t flags;
20212461Sgabeblack@google.com        UNSERIALIZE_SCALAR(paddr);
20312461Sgabeblack@google.com        UNSERIALIZE_SCALAR(flags);
20410905Sandreas.sandberg@arm.com
20512461Sgabeblack@google.com        pTable.emplace(vaddr, Entry(paddr, flags));
2066818SLisa.Hsu@amd.com    }
2073311Ssaidi@eecs.umich.edu}
2083311Ssaidi@eecs.umich.edu
209