isa.hh (13395:0f064dae9f6b) isa.hh (13531:e6f1bf55d038)
1/*
2 * Copyright (c) 2010, 2012-2018 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2009 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Gabe Black
41 */
42
43#ifndef __ARCH_ARM_ISA_HH__
44#define __ARCH_ARM_ISA_HH__
45
46#include "arch/arm/isa_device.hh"
47#include "arch/arm/miscregs.hh"
48#include "arch/arm/registers.hh"
49#include "arch/arm/system.hh"
50#include "arch/arm/tlb.hh"
51#include "arch/arm/types.hh"
52#include "arch/generic/traits.hh"
53#include "debug/Checkpoint.hh"
54#include "enums/VecRegRenameMode.hh"
55#include "sim/sim_object.hh"
56#include "enums/DecoderFlavour.hh"
57
58struct ArmISAParams;
59struct DummyArmISADeviceParams;
60class ThreadContext;
61class Checkpoint;
62class EventManager;
63
64namespace ArmISA
65{
66 class ISA : public SimObject
67 {
68 protected:
69 // Parent system
70 ArmSystem *system;
71
72 // Micro Architecture
73 const Enums::DecoderFlavour _decoderFlavour;
74 const Enums::VecRegRenameMode _vecRegRenameMode;
75
76 /** Dummy device for to handle non-existing ISA devices */
77 DummyISADevice dummyDevice;
78
79 // PMU belonging to this ISA
80 BaseISADevice *pmu;
81
82 // Generic timer interface belonging to this ISA
83 std::unique_ptr<BaseISADevice> timer;
84
1/*
2 * Copyright (c) 2010, 2012-2018 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2009 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Gabe Black
41 */
42
43#ifndef __ARCH_ARM_ISA_HH__
44#define __ARCH_ARM_ISA_HH__
45
46#include "arch/arm/isa_device.hh"
47#include "arch/arm/miscregs.hh"
48#include "arch/arm/registers.hh"
49#include "arch/arm/system.hh"
50#include "arch/arm/tlb.hh"
51#include "arch/arm/types.hh"
52#include "arch/generic/traits.hh"
53#include "debug/Checkpoint.hh"
54#include "enums/VecRegRenameMode.hh"
55#include "sim/sim_object.hh"
56#include "enums/DecoderFlavour.hh"
57
58struct ArmISAParams;
59struct DummyArmISADeviceParams;
60class ThreadContext;
61class Checkpoint;
62class EventManager;
63
64namespace ArmISA
65{
66 class ISA : public SimObject
67 {
68 protected:
69 // Parent system
70 ArmSystem *system;
71
72 // Micro Architecture
73 const Enums::DecoderFlavour _decoderFlavour;
74 const Enums::VecRegRenameMode _vecRegRenameMode;
75
76 /** Dummy device for to handle non-existing ISA devices */
77 DummyISADevice dummyDevice;
78
79 // PMU belonging to this ISA
80 BaseISADevice *pmu;
81
82 // Generic timer interface belonging to this ISA
83 std::unique_ptr<BaseISADevice> timer;
84
85 // GICv3 CPU interface belonging to this ISA
86 std::unique_ptr<BaseISADevice> gicv3CpuInterface;
87
85 // Cached copies of system-level properties
86 bool highestELIs64;
87 bool haveSecurity;
88 bool haveLPAE;
89 bool haveVirtualization;
90 bool haveCrypto;
91 bool haveLargeAsid64;
88 // Cached copies of system-level properties
89 bool highestELIs64;
90 bool haveSecurity;
91 bool haveLPAE;
92 bool haveVirtualization;
93 bool haveCrypto;
94 bool haveLargeAsid64;
95 bool haveGICv3CPUInterface;
92 uint8_t physAddrRange;
93
94 /**
95 * If true, accesses to IMPLEMENTATION DEFINED registers are treated
96 * as NOP hence not causing UNDEFINED INSTRUCTION.
97 */
98 bool impdefAsNop;
99
100 /** MiscReg metadata **/
101 struct MiscRegLUTEntry {
102 uint32_t lower; // Lower half mapped to this register
103 uint32_t upper; // Upper half mapped to this register
104 uint64_t _reset; // value taken on reset (i.e. initialization)
105 uint64_t _res0; // reserved
106 uint64_t _res1; // reserved
107 uint64_t _raz; // read as zero (fixed at 0)
108 uint64_t _rao; // read as one (fixed at 1)
109 public:
110 MiscRegLUTEntry() :
111 lower(0), upper(0),
112 _reset(0), _res0(0), _res1(0), _raz(0), _rao(0) {}
113 uint64_t reset() const { return _reset; }
114 uint64_t res0() const { return _res0; }
115 uint64_t res1() const { return _res1; }
116 uint64_t raz() const { return _raz; }
117 uint64_t rao() const { return _rao; }
118 // raz/rao implies writes ignored
119 uint64_t wi() const { return _raz | _rao; }
120 };
121
122 /** Metadata table accessible via the value of the register */
123 static std::vector<struct MiscRegLUTEntry> lookUpMiscReg;
124
125 class MiscRegLUTEntryInitializer {
126 struct MiscRegLUTEntry &entry;
127 std::bitset<NUM_MISCREG_INFOS> &info;
128 typedef const MiscRegLUTEntryInitializer& chain;
129 public:
130 chain mapsTo(uint32_t l, uint32_t u = 0) const {
131 entry.lower = l;
132 entry.upper = u;
133 return *this;
134 }
135 chain res0(uint64_t mask) const {
136 entry._res0 = mask;
137 return *this;
138 }
139 chain res1(uint64_t mask) const {
140 entry._res1 = mask;
141 return *this;
142 }
143 chain raz(uint64_t mask) const {
144 entry._raz = mask;
145 return *this;
146 }
147 chain rao(uint64_t mask) const {
148 entry._rao = mask;
149 return *this;
150 }
151 chain implemented(bool v = true) const {
152 info[MISCREG_IMPLEMENTED] = v;
153 return *this;
154 }
155 chain unimplemented() const {
156 return implemented(false);
157 }
158 chain unverifiable(bool v = true) const {
159 info[MISCREG_UNVERIFIABLE] = v;
160 return *this;
161 }
162 chain warnNotFail(bool v = true) const {
163 info[MISCREG_WARN_NOT_FAIL] = v;
164 return *this;
165 }
166 chain mutex(bool v = true) const {
167 info[MISCREG_MUTEX] = v;
168 return *this;
169 }
170 chain banked(bool v = true) const {
171 info[MISCREG_BANKED] = v;
172 return *this;
173 }
174 chain bankedChild(bool v = true) const {
175 info[MISCREG_BANKED_CHILD] = v;
176 return *this;
177 }
178 chain userNonSecureRead(bool v = true) const {
179 info[MISCREG_USR_NS_RD] = v;
180 return *this;
181 }
182 chain userNonSecureWrite(bool v = true) const {
183 info[MISCREG_USR_NS_WR] = v;
184 return *this;
185 }
186 chain userSecureRead(bool v = true) const {
187 info[MISCREG_USR_S_RD] = v;
188 return *this;
189 }
190 chain userSecureWrite(bool v = true) const {
191 info[MISCREG_USR_S_WR] = v;
192 return *this;
193 }
194 chain user(bool v = true) const {
195 userNonSecureRead(v);
196 userNonSecureWrite(v);
197 userSecureRead(v);
198 userSecureWrite(v);
199 return *this;
200 }
201 chain privNonSecureRead(bool v = true) const {
202 info[MISCREG_PRI_NS_RD] = v;
203 return *this;
204 }
205 chain privNonSecureWrite(bool v = true) const {
206 info[MISCREG_PRI_NS_WR] = v;
207 return *this;
208 }
209 chain privNonSecure(bool v = true) const {
210 privNonSecureRead(v);
211 privNonSecureWrite(v);
212 return *this;
213 }
214 chain privSecureRead(bool v = true) const {
215 info[MISCREG_PRI_S_RD] = v;
216 return *this;
217 }
218 chain privSecureWrite(bool v = true) const {
219 info[MISCREG_PRI_S_WR] = v;
220 return *this;
221 }
222 chain privSecure(bool v = true) const {
223 privSecureRead(v);
224 privSecureWrite(v);
225 return *this;
226 }
227 chain priv(bool v = true) const {
228 privSecure(v);
229 privNonSecure(v);
230 return *this;
231 }
232 chain privRead(bool v = true) const {
233 privSecureRead(v);
234 privNonSecureRead(v);
235 return *this;
236 }
237 chain hypRead(bool v = true) const {
238 info[MISCREG_HYP_RD] = v;
239 return *this;
240 }
241 chain hypWrite(bool v = true) const {
242 info[MISCREG_HYP_WR] = v;
243 return *this;
244 }
245 chain hyp(bool v = true) const {
246 hypRead(v);
247 hypWrite(v);
248 return *this;
249 }
250 chain monSecureRead(bool v = true) const {
251 info[MISCREG_MON_NS0_RD] = v;
252 return *this;
253 }
254 chain monSecureWrite(bool v = true) const {
255 info[MISCREG_MON_NS0_WR] = v;
256 return *this;
257 }
258 chain monNonSecureRead(bool v = true) const {
259 info[MISCREG_MON_NS1_RD] = v;
260 return *this;
261 }
262 chain monNonSecureWrite(bool v = true) const {
263 info[MISCREG_MON_NS1_WR] = v;
264 return *this;
265 }
266 chain mon(bool v = true) const {
267 monSecureRead(v);
268 monSecureWrite(v);
269 monNonSecureRead(v);
270 monNonSecureWrite(v);
271 return *this;
272 }
273 chain monSecure(bool v = true) const {
274 monSecureRead(v);
275 monSecureWrite(v);
276 return *this;
277 }
278 chain monNonSecure(bool v = true) const {
279 monNonSecureRead(v);
280 monNonSecureWrite(v);
281 return *this;
282 }
283 chain allPrivileges(bool v = true) const {
284 userNonSecureRead(v);
285 userNonSecureWrite(v);
286 userSecureRead(v);
287 userSecureWrite(v);
288 privNonSecureRead(v);
289 privNonSecureWrite(v);
290 privSecureRead(v);
291 privSecureWrite(v);
292 hypRead(v);
293 hypWrite(v);
294 monSecureRead(v);
295 monSecureWrite(v);
296 monNonSecureRead(v);
297 monNonSecureWrite(v);
298 return *this;
299 }
300 chain nonSecure(bool v = true) const {
301 userNonSecureRead(v);
302 userNonSecureWrite(v);
303 privNonSecureRead(v);
304 privNonSecureWrite(v);
305 hypRead(v);
306 hypWrite(v);
307 monNonSecureRead(v);
308 monNonSecureWrite(v);
309 return *this;
310 }
311 chain secure(bool v = true) const {
312 userSecureRead(v);
313 userSecureWrite(v);
314 privSecureRead(v);
315 privSecureWrite(v);
316 monSecureRead(v);
317 monSecureWrite(v);
318 return *this;
319 }
320 chain reads(bool v) const {
321 userNonSecureRead(v);
322 userSecureRead(v);
323 privNonSecureRead(v);
324 privSecureRead(v);
325 hypRead(v);
326 monSecureRead(v);
327 monNonSecureRead(v);
328 return *this;
329 }
330 chain writes(bool v) const {
331 userNonSecureWrite(v);
332 userSecureWrite(v);
333 privNonSecureWrite(v);
334 privSecureWrite(v);
335 hypWrite(v);
336 monSecureWrite(v);
337 monNonSecureWrite(v);
338 return *this;
339 }
340 chain exceptUserMode() const {
341 user(0);
342 return *this;
343 }
344 MiscRegLUTEntryInitializer(struct MiscRegLUTEntry &e,
345 std::bitset<NUM_MISCREG_INFOS> &i)
346 : entry(e),
347 info(i)
348 {
349 // force unimplemented registers to be thusly declared
350 implemented(1);
351 }
352 };
353
354 const MiscRegLUTEntryInitializer InitReg(uint32_t reg) {
355 return MiscRegLUTEntryInitializer(lookUpMiscReg[reg],
356 miscRegInfo[reg]);
357 }
358
359 void initializeMiscRegMetadata();
360
361 MiscReg miscRegs[NumMiscRegs];
362 const IntRegIndex *intRegMap;
363
364 void
365 updateRegMap(CPSR cpsr)
366 {
367 if (cpsr.width == 0) {
368 intRegMap = IntReg64Map;
369 } else {
370 switch (cpsr.mode) {
371 case MODE_USER:
372 case MODE_SYSTEM:
373 intRegMap = IntRegUsrMap;
374 break;
375 case MODE_FIQ:
376 intRegMap = IntRegFiqMap;
377 break;
378 case MODE_IRQ:
379 intRegMap = IntRegIrqMap;
380 break;
381 case MODE_SVC:
382 intRegMap = IntRegSvcMap;
383 break;
384 case MODE_MON:
385 intRegMap = IntRegMonMap;
386 break;
387 case MODE_ABORT:
388 intRegMap = IntRegAbtMap;
389 break;
390 case MODE_HYP:
391 intRegMap = IntRegHypMap;
392 break;
393 case MODE_UNDEFINED:
394 intRegMap = IntRegUndMap;
395 break;
396 default:
397 panic("Unrecognized mode setting in CPSR.\n");
398 }
399 }
400 }
401
402 BaseISADevice &getGenericTimer(ThreadContext *tc);
96 uint8_t physAddrRange;
97
98 /**
99 * If true, accesses to IMPLEMENTATION DEFINED registers are treated
100 * as NOP hence not causing UNDEFINED INSTRUCTION.
101 */
102 bool impdefAsNop;
103
104 /** MiscReg metadata **/
105 struct MiscRegLUTEntry {
106 uint32_t lower; // Lower half mapped to this register
107 uint32_t upper; // Upper half mapped to this register
108 uint64_t _reset; // value taken on reset (i.e. initialization)
109 uint64_t _res0; // reserved
110 uint64_t _res1; // reserved
111 uint64_t _raz; // read as zero (fixed at 0)
112 uint64_t _rao; // read as one (fixed at 1)
113 public:
114 MiscRegLUTEntry() :
115 lower(0), upper(0),
116 _reset(0), _res0(0), _res1(0), _raz(0), _rao(0) {}
117 uint64_t reset() const { return _reset; }
118 uint64_t res0() const { return _res0; }
119 uint64_t res1() const { return _res1; }
120 uint64_t raz() const { return _raz; }
121 uint64_t rao() const { return _rao; }
122 // raz/rao implies writes ignored
123 uint64_t wi() const { return _raz | _rao; }
124 };
125
126 /** Metadata table accessible via the value of the register */
127 static std::vector<struct MiscRegLUTEntry> lookUpMiscReg;
128
129 class MiscRegLUTEntryInitializer {
130 struct MiscRegLUTEntry &entry;
131 std::bitset<NUM_MISCREG_INFOS> &info;
132 typedef const MiscRegLUTEntryInitializer& chain;
133 public:
134 chain mapsTo(uint32_t l, uint32_t u = 0) const {
135 entry.lower = l;
136 entry.upper = u;
137 return *this;
138 }
139 chain res0(uint64_t mask) const {
140 entry._res0 = mask;
141 return *this;
142 }
143 chain res1(uint64_t mask) const {
144 entry._res1 = mask;
145 return *this;
146 }
147 chain raz(uint64_t mask) const {
148 entry._raz = mask;
149 return *this;
150 }
151 chain rao(uint64_t mask) const {
152 entry._rao = mask;
153 return *this;
154 }
155 chain implemented(bool v = true) const {
156 info[MISCREG_IMPLEMENTED] = v;
157 return *this;
158 }
159 chain unimplemented() const {
160 return implemented(false);
161 }
162 chain unverifiable(bool v = true) const {
163 info[MISCREG_UNVERIFIABLE] = v;
164 return *this;
165 }
166 chain warnNotFail(bool v = true) const {
167 info[MISCREG_WARN_NOT_FAIL] = v;
168 return *this;
169 }
170 chain mutex(bool v = true) const {
171 info[MISCREG_MUTEX] = v;
172 return *this;
173 }
174 chain banked(bool v = true) const {
175 info[MISCREG_BANKED] = v;
176 return *this;
177 }
178 chain bankedChild(bool v = true) const {
179 info[MISCREG_BANKED_CHILD] = v;
180 return *this;
181 }
182 chain userNonSecureRead(bool v = true) const {
183 info[MISCREG_USR_NS_RD] = v;
184 return *this;
185 }
186 chain userNonSecureWrite(bool v = true) const {
187 info[MISCREG_USR_NS_WR] = v;
188 return *this;
189 }
190 chain userSecureRead(bool v = true) const {
191 info[MISCREG_USR_S_RD] = v;
192 return *this;
193 }
194 chain userSecureWrite(bool v = true) const {
195 info[MISCREG_USR_S_WR] = v;
196 return *this;
197 }
198 chain user(bool v = true) const {
199 userNonSecureRead(v);
200 userNonSecureWrite(v);
201 userSecureRead(v);
202 userSecureWrite(v);
203 return *this;
204 }
205 chain privNonSecureRead(bool v = true) const {
206 info[MISCREG_PRI_NS_RD] = v;
207 return *this;
208 }
209 chain privNonSecureWrite(bool v = true) const {
210 info[MISCREG_PRI_NS_WR] = v;
211 return *this;
212 }
213 chain privNonSecure(bool v = true) const {
214 privNonSecureRead(v);
215 privNonSecureWrite(v);
216 return *this;
217 }
218 chain privSecureRead(bool v = true) const {
219 info[MISCREG_PRI_S_RD] = v;
220 return *this;
221 }
222 chain privSecureWrite(bool v = true) const {
223 info[MISCREG_PRI_S_WR] = v;
224 return *this;
225 }
226 chain privSecure(bool v = true) const {
227 privSecureRead(v);
228 privSecureWrite(v);
229 return *this;
230 }
231 chain priv(bool v = true) const {
232 privSecure(v);
233 privNonSecure(v);
234 return *this;
235 }
236 chain privRead(bool v = true) const {
237 privSecureRead(v);
238 privNonSecureRead(v);
239 return *this;
240 }
241 chain hypRead(bool v = true) const {
242 info[MISCREG_HYP_RD] = v;
243 return *this;
244 }
245 chain hypWrite(bool v = true) const {
246 info[MISCREG_HYP_WR] = v;
247 return *this;
248 }
249 chain hyp(bool v = true) const {
250 hypRead(v);
251 hypWrite(v);
252 return *this;
253 }
254 chain monSecureRead(bool v = true) const {
255 info[MISCREG_MON_NS0_RD] = v;
256 return *this;
257 }
258 chain monSecureWrite(bool v = true) const {
259 info[MISCREG_MON_NS0_WR] = v;
260 return *this;
261 }
262 chain monNonSecureRead(bool v = true) const {
263 info[MISCREG_MON_NS1_RD] = v;
264 return *this;
265 }
266 chain monNonSecureWrite(bool v = true) const {
267 info[MISCREG_MON_NS1_WR] = v;
268 return *this;
269 }
270 chain mon(bool v = true) const {
271 monSecureRead(v);
272 monSecureWrite(v);
273 monNonSecureRead(v);
274 monNonSecureWrite(v);
275 return *this;
276 }
277 chain monSecure(bool v = true) const {
278 monSecureRead(v);
279 monSecureWrite(v);
280 return *this;
281 }
282 chain monNonSecure(bool v = true) const {
283 monNonSecureRead(v);
284 monNonSecureWrite(v);
285 return *this;
286 }
287 chain allPrivileges(bool v = true) const {
288 userNonSecureRead(v);
289 userNonSecureWrite(v);
290 userSecureRead(v);
291 userSecureWrite(v);
292 privNonSecureRead(v);
293 privNonSecureWrite(v);
294 privSecureRead(v);
295 privSecureWrite(v);
296 hypRead(v);
297 hypWrite(v);
298 monSecureRead(v);
299 monSecureWrite(v);
300 monNonSecureRead(v);
301 monNonSecureWrite(v);
302 return *this;
303 }
304 chain nonSecure(bool v = true) const {
305 userNonSecureRead(v);
306 userNonSecureWrite(v);
307 privNonSecureRead(v);
308 privNonSecureWrite(v);
309 hypRead(v);
310 hypWrite(v);
311 monNonSecureRead(v);
312 monNonSecureWrite(v);
313 return *this;
314 }
315 chain secure(bool v = true) const {
316 userSecureRead(v);
317 userSecureWrite(v);
318 privSecureRead(v);
319 privSecureWrite(v);
320 monSecureRead(v);
321 monSecureWrite(v);
322 return *this;
323 }
324 chain reads(bool v) const {
325 userNonSecureRead(v);
326 userSecureRead(v);
327 privNonSecureRead(v);
328 privSecureRead(v);
329 hypRead(v);
330 monSecureRead(v);
331 monNonSecureRead(v);
332 return *this;
333 }
334 chain writes(bool v) const {
335 userNonSecureWrite(v);
336 userSecureWrite(v);
337 privNonSecureWrite(v);
338 privSecureWrite(v);
339 hypWrite(v);
340 monSecureWrite(v);
341 monNonSecureWrite(v);
342 return *this;
343 }
344 chain exceptUserMode() const {
345 user(0);
346 return *this;
347 }
348 MiscRegLUTEntryInitializer(struct MiscRegLUTEntry &e,
349 std::bitset<NUM_MISCREG_INFOS> &i)
350 : entry(e),
351 info(i)
352 {
353 // force unimplemented registers to be thusly declared
354 implemented(1);
355 }
356 };
357
358 const MiscRegLUTEntryInitializer InitReg(uint32_t reg) {
359 return MiscRegLUTEntryInitializer(lookUpMiscReg[reg],
360 miscRegInfo[reg]);
361 }
362
363 void initializeMiscRegMetadata();
364
365 MiscReg miscRegs[NumMiscRegs];
366 const IntRegIndex *intRegMap;
367
368 void
369 updateRegMap(CPSR cpsr)
370 {
371 if (cpsr.width == 0) {
372 intRegMap = IntReg64Map;
373 } else {
374 switch (cpsr.mode) {
375 case MODE_USER:
376 case MODE_SYSTEM:
377 intRegMap = IntRegUsrMap;
378 break;
379 case MODE_FIQ:
380 intRegMap = IntRegFiqMap;
381 break;
382 case MODE_IRQ:
383 intRegMap = IntRegIrqMap;
384 break;
385 case MODE_SVC:
386 intRegMap = IntRegSvcMap;
387 break;
388 case MODE_MON:
389 intRegMap = IntRegMonMap;
390 break;
391 case MODE_ABORT:
392 intRegMap = IntRegAbtMap;
393 break;
394 case MODE_HYP:
395 intRegMap = IntRegHypMap;
396 break;
397 case MODE_UNDEFINED:
398 intRegMap = IntRegUndMap;
399 break;
400 default:
401 panic("Unrecognized mode setting in CPSR.\n");
402 }
403 }
404 }
405
406 BaseISADevice &getGenericTimer(ThreadContext *tc);
407 BaseISADevice &getGICv3CPUInterface(ThreadContext *tc);
403
404
405 private:
406 inline void assert32(ThreadContext *tc) {
407 CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
408 assert(cpsr.width);
409 }
410
411 inline void assert64(ThreadContext *tc) {
412 CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
413 assert(!cpsr.width);
414 }
415
416 public:
417 void clear();
418
419 protected:
420 void clear32(const ArmISAParams *p, const SCTLR &sctlr_rst);
421 void clear64(const ArmISAParams *p);
422 void initID32(const ArmISAParams *p);
423 void initID64(const ArmISAParams *p);
424
425 public:
426 MiscReg readMiscRegNoEffect(int misc_reg) const;
427 MiscReg readMiscReg(int misc_reg, ThreadContext *tc);
428 void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
429 void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
430
431 RegId
432 flattenRegId(const RegId& regId) const
433 {
434 switch (regId.classValue()) {
435 case IntRegClass:
436 return RegId(IntRegClass, flattenIntIndex(regId.index()));
437 case FloatRegClass:
438 return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
439 case VecRegClass:
440 return RegId(VecRegClass, flattenVecIndex(regId.index()));
441 case VecElemClass:
442 return RegId(VecElemClass, flattenVecElemIndex(regId.index()));
443 case CCRegClass:
444 return RegId(CCRegClass, flattenCCIndex(regId.index()));
445 case MiscRegClass:
446 return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
447 }
448 return RegId();
449 }
450
451 int
452 flattenIntIndex(int reg) const
453 {
454 assert(reg >= 0);
455 if (reg < NUM_ARCH_INTREGS) {
456 return intRegMap[reg];
457 } else if (reg < NUM_INTREGS) {
458 return reg;
459 } else if (reg == INTREG_SPX) {
460 CPSR cpsr = miscRegs[MISCREG_CPSR];
461 ExceptionLevel el = opModeToEL(
462 (OperatingMode) (uint8_t) cpsr.mode);
463 if (!cpsr.sp && el != EL0)
464 return INTREG_SP0;
465 switch (el) {
466 case EL3:
467 return INTREG_SP3;
468 case EL2:
469 return INTREG_SP2;
470 case EL1:
471 return INTREG_SP1;
472 case EL0:
473 return INTREG_SP0;
474 default:
475 panic("Invalid exception level");
476 return 0; // Never happens.
477 }
478 } else {
479 return flattenIntRegModeIndex(reg);
480 }
481 }
482
483 int
484 flattenFloatIndex(int reg) const
485 {
486 assert(reg >= 0);
487 return reg;
488 }
489
490 int
491 flattenVecIndex(int reg) const
492 {
493 assert(reg >= 0);
494 return reg;
495 }
496
497 int
498 flattenVecElemIndex(int reg) const
499 {
500 assert(reg >= 0);
501 return reg;
502 }
503
504 int
505 flattenCCIndex(int reg) const
506 {
507 assert(reg >= 0);
508 return reg;
509 }
510
511 int
512 flattenMiscIndex(int reg) const
513 {
514 assert(reg >= 0);
515 int flat_idx = reg;
516
517 if (reg == MISCREG_SPSR) {
518 CPSR cpsr = miscRegs[MISCREG_CPSR];
519 switch (cpsr.mode) {
520 case MODE_EL0T:
521 warn("User mode does not have SPSR\n");
522 flat_idx = MISCREG_SPSR;
523 break;
524 case MODE_EL1T:
525 case MODE_EL1H:
526 flat_idx = MISCREG_SPSR_EL1;
527 break;
528 case MODE_EL2T:
529 case MODE_EL2H:
530 flat_idx = MISCREG_SPSR_EL2;
531 break;
532 case MODE_EL3T:
533 case MODE_EL3H:
534 flat_idx = MISCREG_SPSR_EL3;
535 break;
536 case MODE_USER:
537 warn("User mode does not have SPSR\n");
538 flat_idx = MISCREG_SPSR;
539 break;
540 case MODE_FIQ:
541 flat_idx = MISCREG_SPSR_FIQ;
542 break;
543 case MODE_IRQ:
544 flat_idx = MISCREG_SPSR_IRQ;
545 break;
546 case MODE_SVC:
547 flat_idx = MISCREG_SPSR_SVC;
548 break;
549 case MODE_MON:
550 flat_idx = MISCREG_SPSR_MON;
551 break;
552 case MODE_ABORT:
553 flat_idx = MISCREG_SPSR_ABT;
554 break;
555 case MODE_HYP:
556 flat_idx = MISCREG_SPSR_HYP;
557 break;
558 case MODE_UNDEFINED:
559 flat_idx = MISCREG_SPSR_UND;
560 break;
561 default:
562 warn("Trying to access SPSR in an invalid mode: %d\n",
563 cpsr.mode);
564 flat_idx = MISCREG_SPSR;
565 break;
566 }
567 } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
568 // Mutually exclusive CP15 register
569 switch (reg) {
570 case MISCREG_PRRR_MAIR0:
571 case MISCREG_PRRR_MAIR0_NS:
572 case MISCREG_PRRR_MAIR0_S:
573 {
574 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
575 // If the muxed reg has been flattened, work out the
576 // offset and apply it to the unmuxed reg
577 int idxOffset = reg - MISCREG_PRRR_MAIR0;
578 if (ttbcr.eae)
579 flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
580 idxOffset);
581 else
582 flat_idx = flattenMiscIndex(MISCREG_PRRR +
583 idxOffset);
584 }
585 break;
586 case MISCREG_NMRR_MAIR1:
587 case MISCREG_NMRR_MAIR1_NS:
588 case MISCREG_NMRR_MAIR1_S:
589 {
590 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
591 // If the muxed reg has been flattened, work out the
592 // offset and apply it to the unmuxed reg
593 int idxOffset = reg - MISCREG_NMRR_MAIR1;
594 if (ttbcr.eae)
595 flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
596 idxOffset);
597 else
598 flat_idx = flattenMiscIndex(MISCREG_NMRR +
599 idxOffset);
600 }
601 break;
602 case MISCREG_PMXEVTYPER_PMCCFILTR:
603 {
604 PMSELR pmselr = miscRegs[MISCREG_PMSELR];
605 if (pmselr.sel == 31)
606 flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
607 else
608 flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
609 }
610 break;
611 default:
612 panic("Unrecognized misc. register.\n");
613 break;
614 }
615 } else {
616 if (miscRegInfo[reg][MISCREG_BANKED]) {
617 bool secureReg = haveSecurity && !highestELIs64 &&
618 inSecureState(miscRegs[MISCREG_SCR],
619 miscRegs[MISCREG_CPSR]);
620 flat_idx += secureReg ? 2 : 1;
621 }
622 }
623 return flat_idx;
624 }
625
626 std::pair<int,int> getMiscIndices(int misc_reg) const
627 {
628 // Note: indexes of AArch64 registers are left unchanged
629 int flat_idx = flattenMiscIndex(misc_reg);
630
631 if (lookUpMiscReg[flat_idx].lower == 0) {
632 return std::make_pair(flat_idx, 0);
633 }
634
635 // do additional S/NS flattenings if mapped to NS while in S
636 bool S = haveSecurity && !highestELIs64 &&
637 inSecureState(miscRegs[MISCREG_SCR],
638 miscRegs[MISCREG_CPSR]);
639 int lower = lookUpMiscReg[flat_idx].lower;
640 int upper = lookUpMiscReg[flat_idx].upper;
641 // upper == 0, which is CPSR, is not MISCREG_BANKED_CHILD (no-op)
642 lower += S && miscRegInfo[lower][MISCREG_BANKED_CHILD];
643 upper += S && miscRegInfo[upper][MISCREG_BANKED_CHILD];
644 return std::make_pair(lower, upper);
645 }
646
647 void serialize(CheckpointOut &cp) const
648 {
649 DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
650 SERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
651
652 SERIALIZE_SCALAR(highestELIs64);
653 SERIALIZE_SCALAR(haveSecurity);
654 SERIALIZE_SCALAR(haveLPAE);
655 SERIALIZE_SCALAR(haveVirtualization);
656 SERIALIZE_SCALAR(haveLargeAsid64);
657 SERIALIZE_SCALAR(physAddrRange);
658 }
659 void unserialize(CheckpointIn &cp)
660 {
661 DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
662 UNSERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
663 CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
664 updateRegMap(tmp_cpsr);
665
666 UNSERIALIZE_SCALAR(highestELIs64);
667 UNSERIALIZE_SCALAR(haveSecurity);
668 UNSERIALIZE_SCALAR(haveLPAE);
669 UNSERIALIZE_SCALAR(haveVirtualization);
670 UNSERIALIZE_SCALAR(haveLargeAsid64);
671 UNSERIALIZE_SCALAR(physAddrRange);
672 }
673
674 void startup(ThreadContext *tc);
675
676 Enums::DecoderFlavour decoderFlavour() const { return _decoderFlavour; }
677
678 Enums::VecRegRenameMode
679 vecRegRenameMode() const
680 {
681 return _vecRegRenameMode;
682 }
683
684 /// Explicitly import the otherwise hidden startup
685 using SimObject::startup;
686
687 typedef ArmISAParams Params;
688
689 const Params *params() const;
690
691 ISA(Params *p);
692 };
693}
694
695template<>
696struct initRenameMode<ArmISA::ISA>
697{
698 static Enums::VecRegRenameMode mode(const ArmISA::ISA* isa)
699 {
700 return isa->vecRegRenameMode();
701 }
702 static bool equals(const ArmISA::ISA* isa1, const ArmISA::ISA* isa2)
703 {
704 return mode(isa1) == mode(isa2);
705 }
706};
707
708#endif
408
409
410 private:
411 inline void assert32(ThreadContext *tc) {
412 CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
413 assert(cpsr.width);
414 }
415
416 inline void assert64(ThreadContext *tc) {
417 CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
418 assert(!cpsr.width);
419 }
420
421 public:
422 void clear();
423
424 protected:
425 void clear32(const ArmISAParams *p, const SCTLR &sctlr_rst);
426 void clear64(const ArmISAParams *p);
427 void initID32(const ArmISAParams *p);
428 void initID64(const ArmISAParams *p);
429
430 public:
431 MiscReg readMiscRegNoEffect(int misc_reg) const;
432 MiscReg readMiscReg(int misc_reg, ThreadContext *tc);
433 void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
434 void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
435
436 RegId
437 flattenRegId(const RegId& regId) const
438 {
439 switch (regId.classValue()) {
440 case IntRegClass:
441 return RegId(IntRegClass, flattenIntIndex(regId.index()));
442 case FloatRegClass:
443 return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
444 case VecRegClass:
445 return RegId(VecRegClass, flattenVecIndex(regId.index()));
446 case VecElemClass:
447 return RegId(VecElemClass, flattenVecElemIndex(regId.index()));
448 case CCRegClass:
449 return RegId(CCRegClass, flattenCCIndex(regId.index()));
450 case MiscRegClass:
451 return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
452 }
453 return RegId();
454 }
455
456 int
457 flattenIntIndex(int reg) const
458 {
459 assert(reg >= 0);
460 if (reg < NUM_ARCH_INTREGS) {
461 return intRegMap[reg];
462 } else if (reg < NUM_INTREGS) {
463 return reg;
464 } else if (reg == INTREG_SPX) {
465 CPSR cpsr = miscRegs[MISCREG_CPSR];
466 ExceptionLevel el = opModeToEL(
467 (OperatingMode) (uint8_t) cpsr.mode);
468 if (!cpsr.sp && el != EL0)
469 return INTREG_SP0;
470 switch (el) {
471 case EL3:
472 return INTREG_SP3;
473 case EL2:
474 return INTREG_SP2;
475 case EL1:
476 return INTREG_SP1;
477 case EL0:
478 return INTREG_SP0;
479 default:
480 panic("Invalid exception level");
481 return 0; // Never happens.
482 }
483 } else {
484 return flattenIntRegModeIndex(reg);
485 }
486 }
487
488 int
489 flattenFloatIndex(int reg) const
490 {
491 assert(reg >= 0);
492 return reg;
493 }
494
495 int
496 flattenVecIndex(int reg) const
497 {
498 assert(reg >= 0);
499 return reg;
500 }
501
502 int
503 flattenVecElemIndex(int reg) const
504 {
505 assert(reg >= 0);
506 return reg;
507 }
508
509 int
510 flattenCCIndex(int reg) const
511 {
512 assert(reg >= 0);
513 return reg;
514 }
515
516 int
517 flattenMiscIndex(int reg) const
518 {
519 assert(reg >= 0);
520 int flat_idx = reg;
521
522 if (reg == MISCREG_SPSR) {
523 CPSR cpsr = miscRegs[MISCREG_CPSR];
524 switch (cpsr.mode) {
525 case MODE_EL0T:
526 warn("User mode does not have SPSR\n");
527 flat_idx = MISCREG_SPSR;
528 break;
529 case MODE_EL1T:
530 case MODE_EL1H:
531 flat_idx = MISCREG_SPSR_EL1;
532 break;
533 case MODE_EL2T:
534 case MODE_EL2H:
535 flat_idx = MISCREG_SPSR_EL2;
536 break;
537 case MODE_EL3T:
538 case MODE_EL3H:
539 flat_idx = MISCREG_SPSR_EL3;
540 break;
541 case MODE_USER:
542 warn("User mode does not have SPSR\n");
543 flat_idx = MISCREG_SPSR;
544 break;
545 case MODE_FIQ:
546 flat_idx = MISCREG_SPSR_FIQ;
547 break;
548 case MODE_IRQ:
549 flat_idx = MISCREG_SPSR_IRQ;
550 break;
551 case MODE_SVC:
552 flat_idx = MISCREG_SPSR_SVC;
553 break;
554 case MODE_MON:
555 flat_idx = MISCREG_SPSR_MON;
556 break;
557 case MODE_ABORT:
558 flat_idx = MISCREG_SPSR_ABT;
559 break;
560 case MODE_HYP:
561 flat_idx = MISCREG_SPSR_HYP;
562 break;
563 case MODE_UNDEFINED:
564 flat_idx = MISCREG_SPSR_UND;
565 break;
566 default:
567 warn("Trying to access SPSR in an invalid mode: %d\n",
568 cpsr.mode);
569 flat_idx = MISCREG_SPSR;
570 break;
571 }
572 } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
573 // Mutually exclusive CP15 register
574 switch (reg) {
575 case MISCREG_PRRR_MAIR0:
576 case MISCREG_PRRR_MAIR0_NS:
577 case MISCREG_PRRR_MAIR0_S:
578 {
579 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
580 // If the muxed reg has been flattened, work out the
581 // offset and apply it to the unmuxed reg
582 int idxOffset = reg - MISCREG_PRRR_MAIR0;
583 if (ttbcr.eae)
584 flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
585 idxOffset);
586 else
587 flat_idx = flattenMiscIndex(MISCREG_PRRR +
588 idxOffset);
589 }
590 break;
591 case MISCREG_NMRR_MAIR1:
592 case MISCREG_NMRR_MAIR1_NS:
593 case MISCREG_NMRR_MAIR1_S:
594 {
595 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
596 // If the muxed reg has been flattened, work out the
597 // offset and apply it to the unmuxed reg
598 int idxOffset = reg - MISCREG_NMRR_MAIR1;
599 if (ttbcr.eae)
600 flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
601 idxOffset);
602 else
603 flat_idx = flattenMiscIndex(MISCREG_NMRR +
604 idxOffset);
605 }
606 break;
607 case MISCREG_PMXEVTYPER_PMCCFILTR:
608 {
609 PMSELR pmselr = miscRegs[MISCREG_PMSELR];
610 if (pmselr.sel == 31)
611 flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
612 else
613 flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
614 }
615 break;
616 default:
617 panic("Unrecognized misc. register.\n");
618 break;
619 }
620 } else {
621 if (miscRegInfo[reg][MISCREG_BANKED]) {
622 bool secureReg = haveSecurity && !highestELIs64 &&
623 inSecureState(miscRegs[MISCREG_SCR],
624 miscRegs[MISCREG_CPSR]);
625 flat_idx += secureReg ? 2 : 1;
626 }
627 }
628 return flat_idx;
629 }
630
631 std::pair<int,int> getMiscIndices(int misc_reg) const
632 {
633 // Note: indexes of AArch64 registers are left unchanged
634 int flat_idx = flattenMiscIndex(misc_reg);
635
636 if (lookUpMiscReg[flat_idx].lower == 0) {
637 return std::make_pair(flat_idx, 0);
638 }
639
640 // do additional S/NS flattenings if mapped to NS while in S
641 bool S = haveSecurity && !highestELIs64 &&
642 inSecureState(miscRegs[MISCREG_SCR],
643 miscRegs[MISCREG_CPSR]);
644 int lower = lookUpMiscReg[flat_idx].lower;
645 int upper = lookUpMiscReg[flat_idx].upper;
646 // upper == 0, which is CPSR, is not MISCREG_BANKED_CHILD (no-op)
647 lower += S && miscRegInfo[lower][MISCREG_BANKED_CHILD];
648 upper += S && miscRegInfo[upper][MISCREG_BANKED_CHILD];
649 return std::make_pair(lower, upper);
650 }
651
652 void serialize(CheckpointOut &cp) const
653 {
654 DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
655 SERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
656
657 SERIALIZE_SCALAR(highestELIs64);
658 SERIALIZE_SCALAR(haveSecurity);
659 SERIALIZE_SCALAR(haveLPAE);
660 SERIALIZE_SCALAR(haveVirtualization);
661 SERIALIZE_SCALAR(haveLargeAsid64);
662 SERIALIZE_SCALAR(physAddrRange);
663 }
664 void unserialize(CheckpointIn &cp)
665 {
666 DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
667 UNSERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
668 CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
669 updateRegMap(tmp_cpsr);
670
671 UNSERIALIZE_SCALAR(highestELIs64);
672 UNSERIALIZE_SCALAR(haveSecurity);
673 UNSERIALIZE_SCALAR(haveLPAE);
674 UNSERIALIZE_SCALAR(haveVirtualization);
675 UNSERIALIZE_SCALAR(haveLargeAsid64);
676 UNSERIALIZE_SCALAR(physAddrRange);
677 }
678
679 void startup(ThreadContext *tc);
680
681 Enums::DecoderFlavour decoderFlavour() const { return _decoderFlavour; }
682
683 Enums::VecRegRenameMode
684 vecRegRenameMode() const
685 {
686 return _vecRegRenameMode;
687 }
688
689 /// Explicitly import the otherwise hidden startup
690 using SimObject::startup;
691
692 typedef ArmISAParams Params;
693
694 const Params *params() const;
695
696 ISA(Params *p);
697 };
698}
699
700template<>
701struct initRenameMode<ArmISA::ISA>
702{
703 static Enums::VecRegRenameMode mode(const ArmISA::ISA* isa)
704 {
705 return isa->vecRegRenameMode();
706 }
707 static bool equals(const ArmISA::ISA* isa1, const ArmISA::ISA* isa2)
708 {
709 return mode(isa1) == mode(isa2);
710 }
711};
712
713#endif