se_translating_port_proxy.cc revision 2519
1/* 2 * Copyright (c) 2001-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <string> 30#include "base/chunk_generator.hh" 31#include "mem/port.hh" 32#include "mem/translating_port.hh" 33#include "mem/page_table.hh" 34 35using namespace TheISA; 36 37TranslatingPort::TranslatingPort(PageTable *p_table, bool alloc) 38 : pTable(p_table), allocating(alloc) 39{ } 40 41TranslatingPort::~TranslatingPort() 42{ } 43 44bool 45TranslatingPort::tryReadBlob(Addr addr, uint8_t *p, int size) 46{ 47 Addr paddr; 48 int prevSize = 0; 49 50 for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) { 51 52 if (!pTable->translate(gen.addr(),paddr)) 53 return false; 54 55 Port::readBlob(paddr, p + prevSize, gen.size()); 56 prevSize += gen.size(); 57 } 58 59 return true; 60} 61 62void 63TranslatingPort::readBlob(Addr addr, uint8_t *p, int size) 64{ 65 if (!tryReadBlob(addr, p, size)) 66 fatal("readBlob(0x%x, ...) failed", addr); 67} 68 69 70bool 71TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size) 72{ 73 74 Addr paddr; 75 int prevSize = 0; 76 77 for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) { 78 79 if (!pTable->translate(gen.addr(), paddr)) { 80 if (allocating) { 81 pTable->allocate(roundDown(gen.addr(), VMPageSize), 82 VMPageSize); 83 pTable->translate(gen.addr(), paddr); 84 } else { 85 return false; 86 } 87 } 88 89 Port::writeBlob(paddr, p + prevSize, gen.size()); 90 prevSize += gen.size(); 91 } 92 93 return true; 94} 95 96 97void 98TranslatingPort::writeBlob(Addr addr, uint8_t *p, int size) 99{ 100 if (!tryWriteBlob(addr, p, size)) 101 fatal("writeBlob(0x%x, ...) failed", addr); 102} 103 104bool 105TranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size) 106{ 107 Addr paddr; 108 109 for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) { 110 111 if (!pTable->translate(gen.addr(), paddr)) { 112 if (allocating) { 113 pTable->allocate(roundDown(gen.addr(), VMPageSize), 114 VMPageSize); 115 pTable->translate(gen.addr(), paddr); 116 } else { 117 return false; 118 } 119 } 120 121 Port::memsetBlob(paddr, val, gen.size()); 122 } 123 124 return true; 125} 126 127void 128TranslatingPort::memsetBlob(Addr addr, uint8_t val, int size) 129{ 130 if (!tryMemsetBlob(addr, val, size)) 131 fatal("memsetBlob(0x%x, ...) failed", addr); 132} 133 134 135bool 136TranslatingPort::tryWriteString(Addr addr, const char *str) 137{ 138 Addr paddr,vaddr; 139 uint8_t c; 140 141 vaddr = addr; 142 143 do { 144 c = *str++; 145 if (!pTable->translate(vaddr++,paddr)) 146 return false; 147 148 Port::writeBlob(paddr, &c, 1); 149 } while (c); 150 151 return true; 152} 153 154void 155TranslatingPort::writeString(Addr addr, const char *str) 156{ 157 if (!tryWriteString(addr, str)) 158 fatal("writeString(0x%x, ...) failed", addr); 159} 160 161bool 162TranslatingPort::tryReadString(std::string &str, Addr addr) 163{ 164 Addr paddr,vaddr; 165 uint8_t c; 166 167 vaddr = addr; 168 169 do { 170 if (!pTable->translate(vaddr++,paddr)) 171 return false; 172 173 Port::readBlob(paddr, &c, 1); 174 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