gem5  v20.1.0.0
memhelpers.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 Google
3  * Copyright (c) 2015 Advanced Micro Devices, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met: redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer;
10  * redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution;
13  * neither the name of the copyright holders nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef __ARCH_X86_MEMHELPERS_HH__
31 #define __ARCH_X86_MEMHELPERS_HH__
32 
33 #include <array>
34 
35 #include "base/types.hh"
36 #include "cpu/exec_context.hh"
37 #include "sim/byteswap.hh"
38 #include "sim/insttracer.hh"
39 
40 namespace X86ISA
41 {
42 
44 static Fault
46  unsigned dataSize, Request::Flags flags)
47 {
48  return xc->initiateMemRead(addr, dataSize, flags);
49 }
50 
51 static void
52 getMem(PacketPtr pkt, uint64_t &mem, unsigned dataSize,
53  Trace::InstRecord *traceData)
54 {
55  switch (dataSize) {
56  case 1:
57  mem = pkt->getLE<uint8_t>();
58  break;
59  case 2:
60  mem = pkt->getLE<uint16_t>();
61  break;
62  case 4:
63  mem = pkt->getLE<uint32_t>();
64  break;
65  case 8:
66  mem = pkt->getLE<uint64_t>();
67  break;
68  default:
69  panic("Unhandled size in getMem.\n");
70  }
71  if (traceData)
72  traceData->setData(mem);
73 }
74 
75 template <typename T, size_t N>
76 static void
77 getPackedMem(PacketPtr pkt, std::array<uint64_t, N> &mem, unsigned dataSize)
78 {
79  std::array<T, N> real_mem = pkt->getLE<std::array<T, N> >();
80  for (int i = 0; i < N; i++)
81  mem[i] = real_mem[i];
82 }
83 
84 template <size_t N>
85 static void
86 getMem(PacketPtr pkt, std::array<uint64_t, N> &mem, unsigned dataSize,
87  Trace::InstRecord *traceData)
88 {
89  switch (dataSize) {
90  case 4:
91  getPackedMem<uint32_t, N>(pkt, mem, dataSize);
92  break;
93  case 8:
94  getPackedMem<uint64_t, N>(pkt, mem, dataSize);
95  break;
96  default:
97  panic("Unhandled element size in getMem.\n");
98  }
99  if (traceData)
100  traceData->setData(mem[0]);
101 }
102 
103 
104 static Fault
106  uint64_t &mem, unsigned dataSize, Request::Flags flags)
107 {
108  memset(&mem, 0, sizeof(mem));
109  Fault fault = xc->readMem(addr, (uint8_t *)&mem, dataSize, flags);
110  if (fault == NoFault) {
111  // If LE to LE, this is a nop, if LE to BE, the actual data ends up
112  // in the right place because the LSBs where at the low addresses on
113  // access. This doesn't work for BE guests.
114  mem = letoh(mem);
115  if (traceData)
116  traceData->setData(mem);
117  }
118  return fault;
119 }
120 
121 template <typename T, size_t N>
122 static Fault
123 readPackedMemAtomic(ExecContext *xc, Addr addr, std::array<uint64_t, N> &mem,
124  unsigned flags)
125 {
126  std::array<T, N> real_mem;
127  Fault fault = xc->readMem(addr, (uint8_t *)&real_mem,
128  sizeof(T) * N, flags);
129  if (fault == NoFault) {
130  real_mem = letoh(real_mem);
131  for (int i = 0; i < N; i++)
132  mem[i] = real_mem[i];
133  }
134  return fault;
135 }
136 
137 template <size_t N>
138 static Fault
140  std::array<uint64_t, N> &mem, unsigned dataSize,
141  unsigned flags)
142 {
143  Fault fault = NoFault;
144 
145  switch (dataSize) {
146  case 4:
147  fault = readPackedMemAtomic<uint32_t, N>(xc, addr, mem, flags);
148  break;
149  case 8:
150  fault = readPackedMemAtomic<uint64_t, N>(xc, addr, mem, flags);
151  break;
152  default:
153  panic("Unhandled element size in readMemAtomic\n");
154  }
155  if (fault == NoFault && traceData)
156  traceData->setData(mem[0]);
157  return fault;
158 }
159 
160 template <typename T, size_t N>
161 static Fault
162 writePackedMem(ExecContext *xc, std::array<uint64_t, N> &mem, Addr addr,
163  unsigned flags, uint64_t *res)
164 {
165  std::array<T, N> real_mem;
166  for (int i = 0; i < N; i++)
167  real_mem[i] = mem[i];
168  real_mem = htole(real_mem);
169  return xc->writeMem((uint8_t *)&real_mem, sizeof(T) * N,
170  addr, flags, res);
171 }
172 
173 static Fault
175  unsigned dataSize, Addr addr, Request::Flags flags,
176  uint64_t *res)
177 {
178  if (traceData)
179  traceData->setData(mem);
180  mem = htole(mem);
181  return xc->writeMem((uint8_t *)&mem, dataSize, addr, flags, res);
182 }
183 
184 template <size_t N>
185 static Fault
187  std::array<uint64_t, N> &mem, unsigned dataSize,
188  Addr addr, unsigned flags, uint64_t *res)
189 {
190  if (traceData)
191  traceData->setData(mem[0]);
192 
193  switch (dataSize) {
194  case 4:
195  return writePackedMem<uint32_t, N>(xc, mem, addr, flags, res);
196  case 8:
197  return writePackedMem<uint64_t, N>(xc, mem, addr, flags, res);
198  default:
199  panic("Unhandled element size in writeMemTiming.\n");
200  }
201 }
202 
203 static Fault
205  unsigned dataSize, Addr addr, Request::Flags flags,
206  uint64_t *res)
207 {
208  if (traceData)
209  traceData->setData(mem);
210  uint64_t host_mem = htole(mem);
211  Fault fault =
212  xc->writeMem((uint8_t *)&host_mem, dataSize, addr, flags, res);
213  if (fault == NoFault && res)
214  *res = letoh(*res);
215  return fault;
216 }
217 
218 template <size_t N>
219 static Fault
221  std::array<uint64_t, N> &mem, unsigned dataSize,
222  Addr addr, unsigned flags, uint64_t *res)
223 {
224  if (traceData)
225  traceData->setData(mem[0]);
226 
227  Fault fault;
228  switch (dataSize) {
229  case 4:
230  fault = writePackedMem<uint32_t, N>(xc, mem, addr, flags, res);
231  break;
232  case 8:
233  fault = writePackedMem<uint64_t, N>(xc, mem, addr, flags, res);
234  break;
235  default:
236  panic("Unhandled element size in writeMemAtomic.\n");
237  }
238 
239  if (fault == NoFault && res)
240  *res = letoh(*res);
241 
242  return fault;
243 }
244 
245 }
246 
247 #endif
ExecContext::initiateMemRead
virtual Fault initiateMemRead(Addr addr, unsigned int size, Request::Flags flags, const std::vector< bool > &byte_enable=std::vector< bool >())
Initiate a timing memory read operation.
Definition: exec_context.hh:248
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
insttracer.hh
Flags< FlagsType >
htole
T htole(T value)
Definition: byteswap.hh:140
Trace::InstRecord
Definition: insttracer.hh:55
X86ISA::writeMemAtomic
static Fault writeMemAtomic(ExecContext *xc, Trace::InstRecord *traceData, uint64_t mem, unsigned dataSize, Addr addr, Request::Flags flags, uint64_t *res)
Definition: memhelpers.hh:204
ExecContext::writeMem
virtual Fault writeMem(uint8_t *data, unsigned int size, Addr addr, Request::Flags flags, uint64_t *res, const std::vector< bool > &byte_enable=std::vector< bool >())=0
For atomic-mode contexts, perform an atomic memory write operation.
X86ISA::initiateMemRead
static Fault initiateMemRead(ExecContext *xc, Trace::InstRecord *traceData, Addr addr, unsigned dataSize, Request::Flags flags)
Initiate a read from memory in timing mode.
Definition: memhelpers.hh:45
X86ISA::getPackedMem
static void getPackedMem(PacketPtr pkt, std::array< uint64_t, N > &mem, unsigned dataSize)
Definition: memhelpers.hh:77
X86ISA::getMem
static void getMem(PacketPtr pkt, uint64_t &mem, unsigned dataSize, Trace::InstRecord *traceData)
Definition: memhelpers.hh:52
letoh
T letoh(T value)
Definition: byteswap.hh:141
X86ISA::writeMemTiming
static Fault writeMemTiming(ExecContext *xc, Trace::InstRecord *traceData, uint64_t mem, unsigned dataSize, Addr addr, Request::Flags flags, uint64_t *res)
Definition: memhelpers.hh:174
Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:240
X86ISA::readPackedMemAtomic
static Fault readPackedMemAtomic(ExecContext *xc, Addr addr, std::array< uint64_t, N > &mem, unsigned flags)
Definition: memhelpers.hh:123
ExecContext
The ExecContext is an abstract base class the provides the interface used by the ISA to manipulate th...
Definition: exec_context.hh:70
Trace::InstRecord::setData
void setData(std::array< T, N > d)
Definition: insttracer.hh:183
NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:245
X86ISA
This is exposed globally, independent of the ISA.
Definition: acpi.hh:55
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
X86ISA::writePackedMem
static Fault writePackedMem(ExecContext *xc, std::array< uint64_t, N > &mem, Addr addr, unsigned flags, uint64_t *res)
Definition: memhelpers.hh:162
X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:79
Packet::getLE
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
Definition: packet_access.hh:75
types.hh
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:257
exec_context.hh
X86ISA::readMemAtomic
static Fault readMemAtomic(ExecContext *xc, Trace::InstRecord *traceData, Addr addr, uint64_t &mem, unsigned dataSize, Request::Flags flags)
Definition: memhelpers.hh:105
mem
bool_vector8 mem[]
Definition: reset_stim.h:43
ExecContext::readMem
virtual Fault readMem(Addr addr, uint8_t *data, unsigned int size, Request::Flags flags, const std::vector< bool > &byte_enable=std::vector< bool >())
Perform an atomic memory read operation.
Definition: exec_context.hh:234
byteswap.hh
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171

Generated on Wed Sep 30 2020 14:02:07 for gem5 by doxygen 1.8.17