se_translating_port_proxy.cc revision 2461
113168Smatt.horsnell@arm.com/*
213168Smatt.horsnell@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan
313168Smatt.horsnell@arm.com * All rights reserved.
413168Smatt.horsnell@arm.com *
513168Smatt.horsnell@arm.com * Redistribution and use in source and binary forms, with or without
613168Smatt.horsnell@arm.com * modification, are permitted provided that the following conditions are
713168Smatt.horsnell@arm.com * met: redistributions of source code must retain the above copyright
813168Smatt.horsnell@arm.com * notice, this list of conditions and the following disclaimer;
913168Smatt.horsnell@arm.com * redistributions in binary form must reproduce the above copyright
1013168Smatt.horsnell@arm.com * notice, this list of conditions and the following disclaimer in the
1113168Smatt.horsnell@arm.com * documentation and/or other materials provided with the distribution;
1213168Smatt.horsnell@arm.com * neither the name of the copyright holders nor the names of its
1313168Smatt.horsnell@arm.com * contributors may be used to endorse or promote products derived from
1413168Smatt.horsnell@arm.com * this software without specific prior written permission.
1513168Smatt.horsnell@arm.com *
1613168Smatt.horsnell@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1713168Smatt.horsnell@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1813168Smatt.horsnell@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1913168Smatt.horsnell@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2013168Smatt.horsnell@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2113168Smatt.horsnell@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2213168Smatt.horsnell@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2313168Smatt.horsnell@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2413168Smatt.horsnell@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2513168Smatt.horsnell@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2613168Smatt.horsnell@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2713168Smatt.horsnell@arm.com */
2813168Smatt.horsnell@arm.com
2913168Smatt.horsnell@arm.com#include <string>
3013168Smatt.horsnell@arm.com#include "base/chunk_generator.hh"
3113168Smatt.horsnell@arm.com#include "mem/port.hh"
3213168Smatt.horsnell@arm.com#include "mem/translating_port.hh"
3313168Smatt.horsnell@arm.com#include "mem/page_table.hh"
3413168Smatt.horsnell@arm.com
3513168Smatt.horsnell@arm.comusing namespace TheISA;
3613168Smatt.horsnell@arm.com
3713168Smatt.horsnell@arm.comTranslatingPort::TranslatingPort(Port *_port, PageTable *p_table)
3813168Smatt.horsnell@arm.com    : port(_port), pTable(p_table)
3913168Smatt.horsnell@arm.com{ }
4013168Smatt.horsnell@arm.com
4113168Smatt.horsnell@arm.comTranslatingPort::~TranslatingPort()
4213168Smatt.horsnell@arm.com{ }
4313168Smatt.horsnell@arm.com
4413168Smatt.horsnell@arm.combool
4513168Smatt.horsnell@arm.comTranslatingPort::tryReadBlob(Addr addr, uint8_t *p, int size)
4613168Smatt.horsnell@arm.com{
4713168Smatt.horsnell@arm.com    Addr paddr;
4813168Smatt.horsnell@arm.com    int prevSize = 0;
4913168Smatt.horsnell@arm.com
5013168Smatt.horsnell@arm.com    for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
5113168Smatt.horsnell@arm.com
5213168Smatt.horsnell@arm.com        if (!pTable->translate(gen.addr(),paddr))
5313168Smatt.horsnell@arm.com            return false;
5413168Smatt.horsnell@arm.com
5513168Smatt.horsnell@arm.com        port->readBlob(paddr, p + prevSize, gen.size());
5613168Smatt.horsnell@arm.com        prevSize += gen.size();
5713168Smatt.horsnell@arm.com    }
5813168Smatt.horsnell@arm.com
5913168Smatt.horsnell@arm.com    return true;
6013168Smatt.horsnell@arm.com}
6113168Smatt.horsnell@arm.com
6213168Smatt.horsnell@arm.comvoid
6313168Smatt.horsnell@arm.comTranslatingPort::readBlob(Addr addr, uint8_t *p, int size)
6413168Smatt.horsnell@arm.com{
6513168Smatt.horsnell@arm.com    if (!tryReadBlob(addr, p, size))
6613168Smatt.horsnell@arm.com        fatal("readBlob(0x%x, ...) failed", addr);
6713168Smatt.horsnell@arm.com}
6813168Smatt.horsnell@arm.com
6913168Smatt.horsnell@arm.com
7013168Smatt.horsnell@arm.combool
7113168Smatt.horsnell@arm.comTranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size, bool alloc)
7213168Smatt.horsnell@arm.com{
7313168Smatt.horsnell@arm.com
7413168Smatt.horsnell@arm.com    Addr paddr;
7513168Smatt.horsnell@arm.com    int prevSize = 0;
7613168Smatt.horsnell@arm.com
7713168Smatt.horsnell@arm.com    for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
7813168Smatt.horsnell@arm.com
7913168Smatt.horsnell@arm.com        if (!pTable->translate(gen.addr(), paddr)) {
8013168Smatt.horsnell@arm.com            if (alloc) {
8113168Smatt.horsnell@arm.com                pTable->allocate(roundDown(gen.addr(), VMPageSize),
8213168Smatt.horsnell@arm.com                                 VMPageSize);
8313168Smatt.horsnell@arm.com                pTable->translate(gen.addr(), paddr);
8413168Smatt.horsnell@arm.com            } else {
8513168Smatt.horsnell@arm.com                return false;
8613168Smatt.horsnell@arm.com            }
8713168Smatt.horsnell@arm.com        }
8813168Smatt.horsnell@arm.com
8913168Smatt.horsnell@arm.com        port->writeBlob(paddr, p + prevSize, gen.size());
9013168Smatt.horsnell@arm.com        prevSize += gen.size();
9113168Smatt.horsnell@arm.com    }
9213168Smatt.horsnell@arm.com
9313168Smatt.horsnell@arm.com    return true;
9413168Smatt.horsnell@arm.com}
9513168Smatt.horsnell@arm.com
9613168Smatt.horsnell@arm.com
9713168Smatt.horsnell@arm.comvoid
9813168Smatt.horsnell@arm.comTranslatingPort::writeBlob(Addr addr, uint8_t *p, int size, bool alloc)
9913168Smatt.horsnell@arm.com{
10013168Smatt.horsnell@arm.com    if (!tryWriteBlob(addr, p, size, alloc))
10113168Smatt.horsnell@arm.com        fatal("writeBlob(0x%x, ...) failed", addr);
10213168Smatt.horsnell@arm.com}
10313168Smatt.horsnell@arm.com
10413168Smatt.horsnell@arm.combool
10513168Smatt.horsnell@arm.comTranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size, bool alloc)
10613168Smatt.horsnell@arm.com{
10713168Smatt.horsnell@arm.com    Addr paddr;
10813168Smatt.horsnell@arm.com
10913168Smatt.horsnell@arm.com    for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
11013168Smatt.horsnell@arm.com
11113168Smatt.horsnell@arm.com        if (!pTable->translate(gen.addr(), paddr)) {
11213168Smatt.horsnell@arm.com            if (alloc) {
11313168Smatt.horsnell@arm.com                pTable->allocate(roundDown(gen.addr(), VMPageSize),
11413168Smatt.horsnell@arm.com                                 VMPageSize);
11513168Smatt.horsnell@arm.com                pTable->translate(gen.addr(), paddr);
11613168Smatt.horsnell@arm.com            } else {
11713168Smatt.horsnell@arm.com                return false;
11813168Smatt.horsnell@arm.com            }
11913168Smatt.horsnell@arm.com        }
12013168Smatt.horsnell@arm.com
12113168Smatt.horsnell@arm.com        port->memsetBlob(paddr, val, gen.size());
12213168Smatt.horsnell@arm.com    }
12313168Smatt.horsnell@arm.com
12413168Smatt.horsnell@arm.com    return true;
12513168Smatt.horsnell@arm.com}
12613168Smatt.horsnell@arm.com
12713168Smatt.horsnell@arm.comvoid
12813168Smatt.horsnell@arm.comTranslatingPort::memsetBlob(Addr addr, uint8_t val, int size, bool alloc)
12913168Smatt.horsnell@arm.com{
13013168Smatt.horsnell@arm.com    if (!tryMemsetBlob(addr, val, size, alloc))
13113168Smatt.horsnell@arm.com        fatal("memsetBlob(0x%x, ...) failed", addr);
13213168Smatt.horsnell@arm.com}
13313168Smatt.horsnell@arm.com
13413168Smatt.horsnell@arm.com
13513168Smatt.horsnell@arm.combool
13613168Smatt.horsnell@arm.comTranslatingPort::tryWriteString(Addr addr, const char *str)
13713168Smatt.horsnell@arm.com{
13813168Smatt.horsnell@arm.com    Addr paddr,vaddr;
13913168Smatt.horsnell@arm.com    uint8_t c;
14013168Smatt.horsnell@arm.com
14113168Smatt.horsnell@arm.com    vaddr = addr;
14213168Smatt.horsnell@arm.com
14313168Smatt.horsnell@arm.com    do {
14413168Smatt.horsnell@arm.com        c = *str++;
14513168Smatt.horsnell@arm.com        if (!pTable->translate(vaddr++,paddr))
14613168Smatt.horsnell@arm.com            return false;
14713168Smatt.horsnell@arm.com
14813168Smatt.horsnell@arm.com        port->writeBlob(paddr, &c, 1);
14913168Smatt.horsnell@arm.com    } while (c);
15013168Smatt.horsnell@arm.com
15113168Smatt.horsnell@arm.com    return true;
15213168Smatt.horsnell@arm.com}
15313168Smatt.horsnell@arm.com
15413168Smatt.horsnell@arm.comvoid
15513168Smatt.horsnell@arm.comTranslatingPort::writeString(Addr addr, const char *str)
15613168Smatt.horsnell@arm.com{
15713168Smatt.horsnell@arm.com    if (!tryWriteString(addr, str))
15813168Smatt.horsnell@arm.com        fatal("writeString(0x%x, ...) failed", addr);
15913168Smatt.horsnell@arm.com}
16013168Smatt.horsnell@arm.com
16113168Smatt.horsnell@arm.combool
16213168Smatt.horsnell@arm.comTranslatingPort::tryReadString(std::string &str, Addr addr)
16313168Smatt.horsnell@arm.com{
16413168Smatt.horsnell@arm.com    Addr paddr,vaddr;
16513168Smatt.horsnell@arm.com    uint8_t c;
16613168Smatt.horsnell@arm.com
16713168Smatt.horsnell@arm.com    vaddr = addr;
16813168Smatt.horsnell@arm.com
16913168Smatt.horsnell@arm.com    do {
17013168Smatt.horsnell@arm.com        if (!pTable->translate(vaddr++,paddr))
17113168Smatt.horsnell@arm.com            return false;
17213168Smatt.horsnell@arm.com
17313168Smatt.horsnell@arm.com        port->readBlob(paddr, &c, 1);
17413168Smatt.horsnell@arm.com        str += c;
175    } while (c);
176
177    return true;
178}
179
180void
181TranslatingPort::readString(std::string &str, Addr addr)
182{
183    if (!tryReadString(str, addr))
184        fatal("readString(0x%x, ...) failed", addr);
185}
186
187