se_translating_port_proxy.cc revision 14009:a4b36ce75361
13536SN/A/*
211274Sshingarov@labware.com * Copyright (c) 2011 ARM Limited
310595Sgabeblack@google.com * All rights reserved
410037SARM gem5 Developers *
57752SWilliam.Wang@arm.com * The license below extends only to copyright in the software and shall
67752SWilliam.Wang@arm.com * not be construed as granting a license to any other intellectual
77752SWilliam.Wang@arm.com * property including but not limited to intellectual property relating
87752SWilliam.Wang@arm.com * to a hardware implementation of the functionality of the software
97752SWilliam.Wang@arm.com * licensed hereunder.  You may use the software subject to the license
107752SWilliam.Wang@arm.com * terms below provided that you ensure that this notice is replicated
117752SWilliam.Wang@arm.com * unmodified and in its entirety in all distributions of the software,
127752SWilliam.Wang@arm.com * modified or unmodified, in source code or in binary form.
137752SWilliam.Wang@arm.com *
147752SWilliam.Wang@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan
157752SWilliam.Wang@arm.com * All rights reserved.
163536SN/A *
173536SN/A * Redistribution and use in source and binary forms, with or without
183536SN/A * modification, are permitted provided that the following conditions are
193536SN/A * met: redistributions of source code must retain the above copyright
203536SN/A * notice, this list of conditions and the following disclaimer;
213536SN/A * redistributions in binary form must reproduce the above copyright
223536SN/A * notice, this list of conditions and the following disclaimer in the
233536SN/A * documentation and/or other materials provided with the distribution;
243536SN/A * neither the name of the copyright holders nor the names of its
253536SN/A * contributors may be used to endorse or promote products derived from
263536SN/A * this software without specific prior written permission.
273536SN/A *
283536SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
293536SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
303536SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
313536SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
323536SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
333536SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
343536SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
353536SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
363536SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
373536SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
383536SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
393536SN/A *
403536SN/A * Authors: Ron Dreslinski
413536SN/A *          Steve Reinhardt
423536SN/A *          Andreas Hansson
437752SWilliam.Wang@arm.com */
4411274Sshingarov@labware.com
453536SN/A#include "mem/se_translating_port_proxy.hh"
463536SN/A
473536SN/A#include <string>
488332Snate@binkert.org
498332Snate@binkert.org#include "arch/isa_traits.hh"
503536SN/A#include "base/chunk_generator.hh"
513536SN/A#include "config/the_isa.hh"
523536SN/A#include "mem/page_table.hh"
533536SN/A#include "sim/process.hh"
543536SN/A#include "sim/system.hh"
553536SN/A
563536SN/Ausing namespace TheISA;
575543SN/A
585543SN/ASETranslatingPortProxy::SETranslatingPortProxy(MasterPort& port, Process *p,
593536SN/A                                           AllocType alloc)
603536SN/A    : PortProxy(port, p->system->cacheLineSize()), pTable(p->pTable),
613536SN/A      process(p), allocating(alloc)
623536SN/A{ }
633536SN/A
643536SN/Abool
653536SN/ASETranslatingPortProxy::tryReadBlob(Addr addr, void *p, int size) const
663536SN/A{
673536SN/A    int prevSize = 0;
683536SN/A    auto *bytes = static_cast<uint8_t *>(p);
693536SN/A
705543SN/A    for (ChunkGenerator gen(addr, size, PageBytes); !gen.done(); gen.next()) {
715543SN/A        Addr paddr;
723536SN/A
733536SN/A        if (!pTable->translate(gen.addr(),paddr))
743536SN/A            return false;
753536SN/A
763536SN/A        PortProxy::readBlobPhys(paddr, 0, bytes + prevSize, gen.size());
773536SN/A        prevSize += gen.size();
783536SN/A    }
793536SN/A
803536SN/A    return true;
813536SN/A}
823536SN/A
833536SN/A
843536SN/Abool
853536SN/ASETranslatingPortProxy::tryWriteBlob(Addr addr, const void *p, int size) const
863536SN/A{
873536SN/A    int prevSize = 0;
885543SN/A    auto *bytes = static_cast<const uint8_t *>(p);
893536SN/A
903536SN/A    for (ChunkGenerator gen(addr, size, PageBytes); !gen.done(); gen.next()) {
913536SN/A        Addr paddr;
923536SN/A
933536SN/A        if (!pTable->translate(gen.addr(), paddr)) {
943536SN/A            if (allocating == Always) {
953536SN/A                process->allocateMem(roundDown(gen.addr(), PageBytes),
963536SN/A                                     PageBytes);
973536SN/A            } else if (allocating == NextPage) {
983536SN/A                // check if we've accessed the next page on the stack
993536SN/A                if (!process->fixupStackFault(gen.addr()))
1003536SN/A                    panic("Page table fault when accessing virtual address %#x "
1013536SN/A                            "during functional write\n", gen.addr());
1023536SN/A            } else {
1033536SN/A                return false;
1043536SN/A            }
1053536SN/A            pTable->translate(gen.addr(), paddr);
1063536SN/A        }
1073536SN/A
1085543SN/A        PortProxy::writeBlobPhys(paddr, 0, bytes + prevSize, gen.size());
1095543SN/A        prevSize += gen.size();
1103536SN/A    }
1113536SN/A
1123536SN/A    return true;
1133536SN/A}
1143536SN/A
1153536SN/A
1163536SN/Abool
1173536SN/ASETranslatingPortProxy::tryMemsetBlob(Addr addr, uint8_t val, int size) const
1183536SN/A{
1193536SN/A    for (ChunkGenerator gen(addr, size, PageBytes); !gen.done(); gen.next()) {
1203536SN/A        Addr paddr;
1213536SN/A
1223536SN/A        if (!pTable->translate(gen.addr(), paddr)) {
1233536SN/A            if (allocating == Always) {
1243536SN/A                process->allocateMem(roundDown(gen.addr(), PageBytes),
1253536SN/A                                     PageBytes);
1263536SN/A                pTable->translate(gen.addr(), paddr);
1273536SN/A            } else {
1283536SN/A                return false;
1293536SN/A            }
1303536SN/A        }
1313536SN/A
1323536SN/A        PortProxy::memsetBlobPhys(paddr, 0, val, gen.size());
1333536SN/A    }
1343536SN/A
1353536SN/A    return true;
1365569SN/A}
1373536SN/A