se_translating_port_proxy.cc revision 9145:42dd80dee4dd
11689SN/A/*
27598Sminkyu.jeong@arm.com * Copyright (c) 2011 ARM Limited
37598Sminkyu.jeong@arm.com * All rights reserved
47598Sminkyu.jeong@arm.com *
57598Sminkyu.jeong@arm.com * The license below extends only to copyright in the software and shall
67598Sminkyu.jeong@arm.com * not be construed as granting a license to any other intellectual
77598Sminkyu.jeong@arm.com * property including but not limited to intellectual property relating
87598Sminkyu.jeong@arm.com * to a hardware implementation of the functionality of the software
97598Sminkyu.jeong@arm.com * licensed hereunder.  You may use the software subject to the license
107598Sminkyu.jeong@arm.com * terms below provided that you ensure that this notice is replicated
117598Sminkyu.jeong@arm.com * unmodified and in its entirety in all distributions of the software,
127598Sminkyu.jeong@arm.com * modified or unmodified, in source code or in binary form.
137598Sminkyu.jeong@arm.com *
142326SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan
151689SN/A * All rights reserved.
161689SN/A *
171689SN/A * Redistribution and use in source and binary forms, with or without
181689SN/A * modification, are permitted provided that the following conditions are
191689SN/A * met: redistributions of source code must retain the above copyright
201689SN/A * notice, this list of conditions and the following disclaimer;
211689SN/A * redistributions in binary form must reproduce the above copyright
221689SN/A * notice, this list of conditions and the following disclaimer in the
231689SN/A * documentation and/or other materials provided with the distribution;
241689SN/A * neither the name of the copyright holders nor the names of its
251689SN/A * contributors may be used to endorse or promote products derived from
261689SN/A * this software without specific prior written permission.
271689SN/A *
281689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
291689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
301689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
311689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
321689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
331689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
341689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
351689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
361689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
371689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
381689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392665Ssaidi@eecs.umich.edu *
402665Ssaidi@eecs.umich.edu * Authors: Ron Dreslinski
411689SN/A *          Steve Reinhardt
421689SN/A *          Andreas Hansson
431060SN/A */
441060SN/A
451689SN/A#include <string>
461060SN/A
471060SN/A#include "arch/isa_traits.hh"
481060SN/A#include "base/chunk_generator.hh"
491060SN/A#include "config/the_isa.hh"
506658Snate@binkert.org#include "mem/page_table.hh"
512292SN/A#include "mem/se_translating_port_proxy.hh"
521717SN/A#include "sim/process.hh"
535529Snate@binkert.org
541060SN/Ausing namespace TheISA;
556221Snate@binkert.org
566221Snate@binkert.orgSETranslatingPortProxy::SETranslatingPortProxy(MasterPort& port, Process *p,
571681SN/A                                           AllocType alloc)
585529Snate@binkert.org    : PortProxy(port), pTable(p->pTable), process(p),
592873Sktlim@umich.edu      allocating(alloc)
604329Sktlim@umich.edu{ }
614329Sktlim@umich.edu
624329Sktlim@umich.eduSETranslatingPortProxy::~SETranslatingPortProxy()
632292SN/A{ }
642292SN/A
652292SN/Abool
662292SN/ASETranslatingPortProxy::tryReadBlob(Addr addr, uint8_t *p, int size) const
672820Sktlim@umich.edu{
682292SN/A    int prevSize = 0;
692820Sktlim@umich.edu
702820Sktlim@umich.edu    for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
715529Snate@binkert.org        Addr paddr;
722307SN/A
731060SN/A        if (!pTable->translate(gen.addr(),paddr))
742292SN/A            return false;
752292SN/A
762292SN/A        PortProxy::readBlob(paddr, p + prevSize, gen.size());
771060SN/A        prevSize += gen.size();
781060SN/A    }
791060SN/A
801060SN/A    return true;
811060SN/A}
821060SN/A
831681SN/Avoid
846221Snate@binkert.orgSETranslatingPortProxy::readBlob(Addr addr, uint8_t *p, int size) const
856221Snate@binkert.org{
866221Snate@binkert.org    if (!tryReadBlob(addr, p, size))
876221Snate@binkert.org        fatal("readBlob(0x%x, ...) failed", addr);
882292SN/A}
892292SN/A
902820Sktlim@umich.edu
912820Sktlim@umich.edubool
922292SN/ASETranslatingPortProxy::tryWriteBlob(Addr addr, uint8_t *p, int size) const
932292SN/A{
942820Sktlim@umich.edu    int prevSize = 0;
952820Sktlim@umich.edu
962292SN/A    for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
972292SN/A        Addr paddr;
982292SN/A
992292SN/A        if (!pTable->translate(gen.addr(), paddr)) {
1002292SN/A            if (allocating == Always) {
1012292SN/A                process->allocateMem(roundDown(gen.addr(), VMPageSize),
1022292SN/A                                     VMPageSize);
1032292SN/A            } else if (allocating == NextPage) {
1041060SN/A                // check if we've accessed the next page on the stack
1051060SN/A                if (!process->fixupStackFault(gen.addr()))
1061681SN/A                    panic("Page table fault when accessing virtual address %#x "
1071062SN/A                            "during functional write\n", gen.addr());
1082292SN/A            } else {
1091062SN/A                return false;
1102301SN/A            }
1112301SN/A            pTable->translate(gen.addr(), paddr);
1121062SN/A        }
1132727Sktlim@umich.edu
1141062SN/A        PortProxy::writeBlob(paddr, p + prevSize, gen.size());
1151062SN/A        prevSize += gen.size();
1161062SN/A    }
1171062SN/A
1181062SN/A    return true;
1191062SN/A}
1201062SN/A
1211062SN/A
1221062SN/Avoid
1231062SN/ASETranslatingPortProxy::writeBlob(Addr addr, uint8_t *p, int size) const
1241062SN/A{
1251062SN/A    if (!tryWriteBlob(addr, p, size))
1261062SN/A        fatal("writeBlob(0x%x, ...) failed", addr);
1271062SN/A}
1281062SN/A
1291062SN/Abool
1301062SN/ASETranslatingPortProxy::tryMemsetBlob(Addr addr, uint8_t val, int size) const
1311062SN/A{
1321062SN/A    for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
1331062SN/A        Addr paddr;
1341062SN/A
1351062SN/A        if (!pTable->translate(gen.addr(), paddr)) {
1361062SN/A            if (allocating == Always) {
1371062SN/A                process->allocateMem(roundDown(gen.addr(), VMPageSize),
1381062SN/A                                     VMPageSize);
1391062SN/A                pTable->translate(gen.addr(), paddr);
1401062SN/A            } else {
1411062SN/A                return false;
1421062SN/A            }
1431062SN/A        }
1441062SN/A
1451062SN/A        PortProxy::memsetBlob(paddr, val, gen.size());
1461062SN/A    }
1471062SN/A
1481062SN/A    return true;
1491062SN/A}
1501062SN/A
1511062SN/Avoid
1521062SN/ASETranslatingPortProxy::memsetBlob(Addr addr, uint8_t val, int size) const
1531062SN/A{
1541062SN/A    if (!tryMemsetBlob(addr, val, size))
1552292SN/A        fatal("memsetBlob(0x%x, ...) failed", addr);
1562292SN/A}
1572292SN/A
1582292SN/A
1591062SN/Abool
1601062SN/ASETranslatingPortProxy::tryWriteString(Addr addr, const char *str) const
1611062SN/A{
1621062SN/A    uint8_t c;
1631062SN/A
1641062SN/A    Addr vaddr = addr;
1651062SN/A
1662292SN/A    do {
1672292SN/A        c = *str++;
1682292SN/A        Addr paddr;
1692292SN/A
1702292SN/A        if (!pTable->translate(vaddr++, paddr))
1712292SN/A            return false;
1722292SN/A
1732292SN/A        PortProxy::writeBlob(paddr, &c, 1);
1742292SN/A    } while (c);
1752292SN/A
1762301SN/A    return true;
1772727Sktlim@umich.edu}
1782353SN/A
1792727Sktlim@umich.eduvoid
1802727Sktlim@umich.eduSETranslatingPortProxy::writeString(Addr addr, const char *str) const
1812727Sktlim@umich.edu{
1826221Snate@binkert.org    if (!tryWriteString(addr, str))
1832353SN/A        fatal("writeString(0x%x, ...) failed", addr);
1842727Sktlim@umich.edu}
1852727Sktlim@umich.edu
1862727Sktlim@umich.edubool
1872727Sktlim@umich.eduSETranslatingPortProxy::tryReadString(std::string &str, Addr addr) const
1882353SN/A{
1892727Sktlim@umich.edu    uint8_t c;
1902727Sktlim@umich.edu
1912727Sktlim@umich.edu    Addr vaddr = addr;
1926221Snate@binkert.org
1932301SN/A    while (true) {
1942301SN/A        Addr paddr;
1952727Sktlim@umich.edu
1962301SN/A        if (!pTable->translate(vaddr++, paddr))
1972727Sktlim@umich.edu            return false;
1986221Snate@binkert.org
1992301SN/A        PortProxy::readBlob(paddr, &c, 1);
2002301SN/A        if (c == '\0')
2012727Sktlim@umich.edu            break;
2022301SN/A
2032727Sktlim@umich.edu        str += c;
2046221Snate@binkert.org    }
2052301SN/A
2062301SN/A    return true;
2072727Sktlim@umich.edu}
2082301SN/A
2092727Sktlim@umich.eduvoid
2106221Snate@binkert.orgSETranslatingPortProxy::readString(std::string &str, Addr addr) const
2112301SN/A{
2122301SN/A    if (!tryReadString(str, addr))
2132727Sktlim@umich.edu        fatal("readString(0x%x, ...) failed", addr);
2142301SN/A}
2152301SN/A
2162301SN/A