se_translating_port_proxy.cc revision 8861:56d011130987
14876Sstever@eecs.umich.edu/*
23646Srdreslin@umich.edu * Copyright (c) 2011 ARM Limited
33646Srdreslin@umich.edu * All rights reserved
43646Srdreslin@umich.edu *
53646Srdreslin@umich.edu * The license below extends only to copyright in the software and shall
63646Srdreslin@umich.edu * not be construed as granting a license to any other intellectual
73646Srdreslin@umich.edu * property including but not limited to intellectual property relating
83646Srdreslin@umich.edu * to a hardware implementation of the functionality of the software
93646Srdreslin@umich.edu * licensed hereunder.  You may use the software subject to the license
103646Srdreslin@umich.edu * terms below provided that you ensure that this notice is replicated
113646Srdreslin@umich.edu * unmodified and in its entirety in all distributions of the software,
123646Srdreslin@umich.edu * modified or unmodified, in source code or in binary form.
133646Srdreslin@umich.edu *
143646Srdreslin@umich.edu * Copyright (c) 2001-2005 The Regents of The University of Michigan
153646Srdreslin@umich.edu * All rights reserved.
163646Srdreslin@umich.edu *
173646Srdreslin@umich.edu * Redistribution and use in source and binary forms, with or without
183646Srdreslin@umich.edu * modification, are permitted provided that the following conditions are
193646Srdreslin@umich.edu * met: redistributions of source code must retain the above copyright
203646Srdreslin@umich.edu * notice, this list of conditions and the following disclaimer;
213646Srdreslin@umich.edu * redistributions in binary form must reproduce the above copyright
223646Srdreslin@umich.edu * notice, this list of conditions and the following disclaimer in the
233646Srdreslin@umich.edu * documentation and/or other materials provided with the distribution;
243646Srdreslin@umich.edu * neither the name of the copyright holders nor the names of its
253646Srdreslin@umich.edu * contributors may be used to endorse or promote products derived from
263646Srdreslin@umich.edu * this software without specific prior written permission.
273646Srdreslin@umich.edu *
283646Srdreslin@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
293646Srdreslin@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
303646Srdreslin@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
313646Srdreslin@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
323646Srdreslin@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3312564Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3412564Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
356654Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
366654Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
376654Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
386654Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
393646Srdreslin@umich.edu *
403646Srdreslin@umich.edu * Authors: Ron Dreslinski
416654Snate@binkert.org *          Steve Reinhardt
423646Srdreslin@umich.edu *          Andreas Hansson
433646Srdreslin@umich.edu */
443646Srdreslin@umich.edu
453646Srdreslin@umich.edu#include <string>
463646Srdreslin@umich.edu
473646Srdreslin@umich.edu#include "arch/isa_traits.hh"
483646Srdreslin@umich.edu#include "base/chunk_generator.hh"
493646Srdreslin@umich.edu#include "config/the_isa.hh"
503646Srdreslin@umich.edu#include "mem/page_table.hh"
513646Srdreslin@umich.edu#include "mem/se_translating_port_proxy.hh"
523646Srdreslin@umich.edu#include "sim/process.hh"
533646Srdreslin@umich.edu
543646Srdreslin@umich.eduusing namespace TheISA;
553646Srdreslin@umich.edu
563646Srdreslin@umich.eduSETranslatingPortProxy::SETranslatingPortProxy(Port& port, Process *p,
573646Srdreslin@umich.edu                                           AllocType alloc)
583646Srdreslin@umich.edu    : PortProxy(port), pTable(p->pTable), process(p),
593646Srdreslin@umich.edu      allocating(alloc)
603646Srdreslin@umich.edu{ }
613646Srdreslin@umich.edu
623646Srdreslin@umich.eduSETranslatingPortProxy::~SETranslatingPortProxy()
633646Srdreslin@umich.edu{ }
643646Srdreslin@umich.edu
653646Srdreslin@umich.edubool
663646Srdreslin@umich.eduSETranslatingPortProxy::tryReadBlob(Addr addr, uint8_t *p, int size) const
673646Srdreslin@umich.edu{
683646Srdreslin@umich.edu    int prevSize = 0;
693646Srdreslin@umich.edu
703646Srdreslin@umich.edu    for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
713646Srdreslin@umich.edu        Addr paddr;
723646Srdreslin@umich.edu
733646Srdreslin@umich.edu        if (!pTable->translate(gen.addr(),paddr))
743646Srdreslin@umich.edu            return false;
7512564Sgabeblack@google.com
763646Srdreslin@umich.edu        PortProxy::readBlob(paddr, p + prevSize, gen.size());
773646Srdreslin@umich.edu        prevSize += gen.size();
783646Srdreslin@umich.edu    }
793646Srdreslin@umich.edu
803646Srdreslin@umich.edu    return true;
8111851Sbrandon.potter@amd.com}
823646Srdreslin@umich.edu
833646Srdreslin@umich.eduvoid
843646Srdreslin@umich.eduSETranslatingPortProxy::readBlob(Addr addr, uint8_t *p, int size) const
853646Srdreslin@umich.edu{
8611851Sbrandon.potter@amd.com    if (!tryReadBlob(addr, p, size))
873646Srdreslin@umich.edu        fatal("readBlob(0x%x, ...) failed", addr);
883646Srdreslin@umich.edu}
893646Srdreslin@umich.edu
9011851Sbrandon.potter@amd.com
913646Srdreslin@umich.edubool
923646Srdreslin@umich.eduSETranslatingPortProxy::tryWriteBlob(Addr addr, uint8_t *p, int size) const
933646Srdreslin@umich.edu{
9411851Sbrandon.potter@amd.com    int prevSize = 0;
953646Srdreslin@umich.edu
963646Srdreslin@umich.edu    for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
973646Srdreslin@umich.edu        Addr paddr;
9811851Sbrandon.potter@amd.com
993646Srdreslin@umich.edu        if (!pTable->translate(gen.addr(), paddr)) {
1003646Srdreslin@umich.edu            if (allocating == Always) {
1013646Srdreslin@umich.edu                process->allocateMem(roundDown(gen.addr(), VMPageSize),
10211851Sbrandon.potter@amd.com                                     VMPageSize);
1033646Srdreslin@umich.edu            } else if (allocating == NextPage) {
1043646Srdreslin@umich.edu                // check if we've accessed the next page on the stack
1053646Srdreslin@umich.edu                if (!process->fixupStackFault(gen.addr()))
1063646Srdreslin@umich.edu                    panic("Page table fault when accessing virtual address %#x "
10711851Sbrandon.potter@amd.com                            "during functional write\n", gen.addr());
1083646Srdreslin@umich.edu            } else {
1093646Srdreslin@umich.edu                return false;
1103646Srdreslin@umich.edu            }
1113646Srdreslin@umich.edu            pTable->translate(gen.addr(), paddr);
11211851Sbrandon.potter@amd.com        }
1133646Srdreslin@umich.edu
1143646Srdreslin@umich.edu        PortProxy::writeBlob(paddr, p + prevSize, gen.size());
1153646Srdreslin@umich.edu        prevSize += gen.size();
11611851Sbrandon.potter@amd.com    }
1173646Srdreslin@umich.edu
1183646Srdreslin@umich.edu    return true;
1193646Srdreslin@umich.edu}
12011851Sbrandon.potter@amd.com
1213646Srdreslin@umich.edu
1223646Srdreslin@umich.eduvoid
1233646Srdreslin@umich.eduSETranslatingPortProxy::writeBlob(Addr addr, uint8_t *p, int size) const
1243646Srdreslin@umich.edu{
12511851Sbrandon.potter@amd.com    if (!tryWriteBlob(addr, p, size))
1263646Srdreslin@umich.edu        fatal("writeBlob(0x%x, ...) failed", addr);
1273646Srdreslin@umich.edu}
1283646Srdreslin@umich.edu
1293646Srdreslin@umich.edubool
13011851Sbrandon.potter@amd.comSETranslatingPortProxy::tryMemsetBlob(Addr addr, uint8_t val, int size) const
1313646Srdreslin@umich.edu{
1323646Srdreslin@umich.edu    for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
1333646Srdreslin@umich.edu        Addr paddr;
1343646Srdreslin@umich.edu
1353646Srdreslin@umich.edu        if (!pTable->translate(gen.addr(), paddr)) {
1363646Srdreslin@umich.edu            if (allocating == Always) {
1373646Srdreslin@umich.edu                process->allocateMem(roundDown(gen.addr(), VMPageSize),
1383646Srdreslin@umich.edu                                     VMPageSize);
1393646Srdreslin@umich.edu                pTable->translate(gen.addr(), paddr);
14011053Sandreas.hansson@arm.com            } else {
1413646Srdreslin@umich.edu                return false;
1423646Srdreslin@umich.edu            }
1433646Srdreslin@umich.edu        }
1443646Srdreslin@umich.edu
1453646Srdreslin@umich.edu        PortProxy::memsetBlob(paddr, val, gen.size());
1463646Srdreslin@umich.edu    }
1473646Srdreslin@umich.edu
1483646Srdreslin@umich.edu    return true;
14911053Sandreas.hansson@arm.com}
1503646Srdreslin@umich.edu
1513646Srdreslin@umich.eduvoid
1523646Srdreslin@umich.eduSETranslatingPortProxy::memsetBlob(Addr addr, uint8_t val, int size) const
1533646Srdreslin@umich.edu{
1543646Srdreslin@umich.edu    if (!tryMemsetBlob(addr, val, size))
1553646Srdreslin@umich.edu        fatal("memsetBlob(0x%x, ...) failed", addr);
1563646Srdreslin@umich.edu}
1573646Srdreslin@umich.edu
1583646Srdreslin@umich.edu
1593646Srdreslin@umich.edubool
1603646Srdreslin@umich.eduSETranslatingPortProxy::tryWriteString(Addr addr, const char *str) const
1613646Srdreslin@umich.edu{
1623646Srdreslin@umich.edu    uint8_t c;
1633646Srdreslin@umich.edu
1643646Srdreslin@umich.edu    Addr vaddr = addr;
1653646Srdreslin@umich.edu
1663646Srdreslin@umich.edu    do {
1673646Srdreslin@umich.edu        c = *str++;
1683646Srdreslin@umich.edu        Addr paddr;
1693646Srdreslin@umich.edu
1703646Srdreslin@umich.edu        if (!pTable->translate(vaddr++, paddr))
1713646Srdreslin@umich.edu            return false;
1723646Srdreslin@umich.edu
1733646Srdreslin@umich.edu        PortProxy::writeBlob(paddr, &c, 1);
17410720Sandreas.hansson@arm.com    } while (c);
1753646Srdreslin@umich.edu
1763646Srdreslin@umich.edu    return true;
1773646Srdreslin@umich.edu}
1783646Srdreslin@umich.edu
1793646Srdreslin@umich.eduvoid
1803646Srdreslin@umich.eduSETranslatingPortProxy::writeString(Addr addr, const char *str) const
1813646Srdreslin@umich.edu{
1823646Srdreslin@umich.edu    if (!tryWriteString(addr, str))
1833646Srdreslin@umich.edu        fatal("writeString(0x%x, ...) failed", addr);
1843646Srdreslin@umich.edu}
1853646Srdreslin@umich.edu
1863646Srdreslin@umich.edubool
18710720Sandreas.hansson@arm.comSETranslatingPortProxy::tryReadString(std::string &str, Addr addr) const
1883646Srdreslin@umich.edu{
1893646Srdreslin@umich.edu    uint8_t c;
1903646Srdreslin@umich.edu
1913646Srdreslin@umich.edu    Addr vaddr = addr;
1923646Srdreslin@umich.edu
1933646Srdreslin@umich.edu    do {
1943646Srdreslin@umich.edu        Addr paddr;
1953646Srdreslin@umich.edu
1963646Srdreslin@umich.edu        if (!pTable->translate(vaddr++, paddr))
1973646Srdreslin@umich.edu            return false;
1983646Srdreslin@umich.edu
1993646Srdreslin@umich.edu        PortProxy::readBlob(paddr, &c, 1);
20010720Sandreas.hansson@arm.com        str += c;
2013646Srdreslin@umich.edu    } while (c);
2023646Srdreslin@umich.edu
2033646Srdreslin@umich.edu    return true;
2043646Srdreslin@umich.edu}
2053646Srdreslin@umich.edu
2063646Srdreslin@umich.eduvoid
2073646Srdreslin@umich.eduSETranslatingPortProxy::readString(std::string &str, Addr addr) const
2083646Srdreslin@umich.edu{
2093646Srdreslin@umich.edu    if (!tryReadString(str, addr))
2103646Srdreslin@umich.edu        fatal("readString(0x%x, ...) failed", addr);
2113646Srdreslin@umich.edu}
2128931Sandreas.hansson@arm.com
2139036Sandreas.hansson@arm.com