Add names to memory Port objects for tracing.
[gem5.git] / src / mem / translating_port.cc
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
35 using namespace TheISA;
36
37 TranslatingPort::TranslatingPort(const std::string &_name,
38 PageTable *p_table, bool alloc)
39 : FunctionalPort(_name), pTable(p_table), allocating(alloc)
40 { }
41
42 TranslatingPort::~TranslatingPort()
43 { }
44
45 bool
46 TranslatingPort::tryReadBlob(Addr addr, uint8_t *p, int size)
47 {
48 Addr paddr;
49 int prevSize = 0;
50
51 for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
52
53 if (!pTable->translate(gen.addr(),paddr))
54 return false;
55
56 Port::readBlob(paddr, p + prevSize, gen.size());
57 prevSize += gen.size();
58 }
59
60 return true;
61 }
62
63 void
64 TranslatingPort::readBlob(Addr addr, uint8_t *p, int size)
65 {
66 if (!tryReadBlob(addr, p, size))
67 fatal("readBlob(0x%x, ...) failed", addr);
68 }
69
70
71 bool
72 TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size)
73 {
74
75 Addr paddr;
76 int prevSize = 0;
77
78 for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
79
80 if (!pTable->translate(gen.addr(), paddr)) {
81 if (allocating) {
82 pTable->allocate(roundDown(gen.addr(), VMPageSize),
83 VMPageSize);
84 pTable->translate(gen.addr(), paddr);
85 } else {
86 return false;
87 }
88 }
89
90 Port::writeBlob(paddr, p + prevSize, gen.size());
91 prevSize += gen.size();
92 }
93
94 return true;
95 }
96
97
98 void
99 TranslatingPort::writeBlob(Addr addr, uint8_t *p, int size)
100 {
101 if (!tryWriteBlob(addr, p, size))
102 fatal("writeBlob(0x%x, ...) failed", addr);
103 }
104
105 bool
106 TranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size)
107 {
108 Addr paddr;
109
110 for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
111
112 if (!pTable->translate(gen.addr(), paddr)) {
113 if (allocating) {
114 pTable->allocate(roundDown(gen.addr(), VMPageSize),
115 VMPageSize);
116 pTable->translate(gen.addr(), paddr);
117 } else {
118 return false;
119 }
120 }
121
122 Port::memsetBlob(paddr, val, gen.size());
123 }
124
125 return true;
126 }
127
128 void
129 TranslatingPort::memsetBlob(Addr addr, uint8_t val, int size)
130 {
131 if (!tryMemsetBlob(addr, val, size))
132 fatal("memsetBlob(0x%x, ...) failed", addr);
133 }
134
135
136 bool
137 TranslatingPort::tryWriteString(Addr addr, const char *str)
138 {
139 Addr paddr,vaddr;
140 uint8_t c;
141
142 vaddr = addr;
143
144 do {
145 c = *str++;
146 if (!pTable->translate(vaddr++,paddr))
147 return false;
148
149 Port::writeBlob(paddr, &c, 1);
150 } while (c);
151
152 return true;
153 }
154
155 void
156 TranslatingPort::writeString(Addr addr, const char *str)
157 {
158 if (!tryWriteString(addr, str))
159 fatal("writeString(0x%x, ...) failed", addr);
160 }
161
162 bool
163 TranslatingPort::tryReadString(std::string &str, Addr addr)
164 {
165 Addr paddr,vaddr;
166 uint8_t c;
167
168 vaddr = addr;
169
170 do {
171 if (!pTable->translate(vaddr++,paddr))
172 return false;
173
174 Port::readBlob(paddr, &c, 1);
175 str += c;
176 } while (c);
177
178 return true;
179 }
180
181 void
182 TranslatingPort::readString(std::string &str, Addr addr)
183 {
184 if (!tryReadString(str, addr))
185 fatal("readString(0x%x, ...) failed", addr);
186 }
187