arch-arm: Stop "using namespace std"
[gem5.git] / src / arch / arm / system.cc
1 /*
2 * Copyright (c) 2010, 2012-2013, 2015,2017-2020 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) 2002-2006 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
41 #include "arch/arm/system.hh"
42
43 #include <iostream>
44
45 #include "arch/arm/fs_workload.hh"
46 #include "arch/arm/semihosting.hh"
47 #include "base/loader/object_file.hh"
48 #include "base/loader/symtab.hh"
49 #include "cpu/thread_context.hh"
50 #include "dev/arm/fvp_base_pwr_ctrl.hh"
51 #include "dev/arm/gic_v2.hh"
52 #include "mem/physical.hh"
53
54 using namespace Linux;
55 using namespace ArmISA;
56
57 ArmSystem::ArmSystem(const Params &p)
58 : System(p),
59 _haveSecurity(p.have_security),
60 _haveLPAE(p.have_lpae),
61 _haveVirtualization(p.have_virtualization),
62 _haveCrypto(p.have_crypto),
63 _genericTimer(nullptr),
64 _gic(nullptr),
65 _pwrCtrl(nullptr),
66 _highestELIs64(p.highest_el_is_64),
67 _physAddrRange64(p.phys_addr_range_64),
68 _haveLargeAsid64(p.have_large_asid_64),
69 _haveTME(p.have_tme),
70 _haveSVE(p.have_sve),
71 _sveVL(p.sve_vl),
72 _haveLSE(p.have_lse),
73 _havePAN(p.have_pan),
74 _haveSecEL2(p.have_secel2),
75 semihosting(p.semihosting),
76 multiProc(p.multi_proc)
77 {
78 if (p.auto_reset_addr) {
79 _resetAddr = workload->getEntry();
80 } else {
81 _resetAddr = p.reset_addr;
82 warn_if(workload->getEntry() != _resetAddr,
83 "Workload entry point %#x and reset address %#x are different",
84 workload->getEntry(), _resetAddr);
85 }
86
87 bool wl_is_64 = (workload->getArch() == Loader::Arm64);
88 if (wl_is_64 != _highestELIs64) {
89 warn("Highest ARM exception-level set to AArch%d but the workload "
90 "is for AArch%d. Assuming you wanted these to match.",
91 _highestELIs64 ? 64 : 32, wl_is_64 ? 64 : 32);
92 _highestELIs64 = wl_is_64;
93 }
94
95 if (_highestELIs64 && (
96 _physAddrRange64 < 32 ||
97 _physAddrRange64 > MaxPhysAddrRange ||
98 (_physAddrRange64 % 4 != 0 && _physAddrRange64 != 42))) {
99 fatal("Invalid physical address range (%d)\n", _physAddrRange64);
100 }
101 }
102
103 bool
104 ArmSystem::haveSecurity(ThreadContext *tc)
105 {
106 return FullSystem? getArmSystem(tc)->haveSecurity() : false;
107 }
108
109 bool
110 ArmSystem::haveLPAE(ThreadContext *tc)
111 {
112 return FullSystem? getArmSystem(tc)->haveLPAE() : false;
113 }
114
115 bool
116 ArmSystem::haveVirtualization(ThreadContext *tc)
117 {
118 return FullSystem? getArmSystem(tc)->haveVirtualization() : false;
119 }
120
121 bool
122 ArmSystem::highestELIs64(ThreadContext *tc)
123 {
124 return FullSystem? getArmSystem(tc)->highestELIs64() : true;
125 }
126
127 ExceptionLevel
128 ArmSystem::highestEL(ThreadContext *tc)
129 {
130 return FullSystem? getArmSystem(tc)->highestEL() : EL1;
131 }
132
133 bool
134 ArmSystem::haveEL(ThreadContext *tc, ExceptionLevel el)
135 {
136 switch (el) {
137 case EL0:
138 case EL1:
139 return true;
140 case EL2:
141 return haveVirtualization(tc);
142 case EL3:
143 return haveSecurity(tc);
144 default:
145 warn("Unimplemented Exception Level\n");
146 return false;
147 }
148 }
149
150 bool
151 ArmSystem::haveTME(ThreadContext *tc)
152 {
153 return getArmSystem(tc)->haveTME();
154 }
155
156 Addr
157 ArmSystem::resetAddr(ThreadContext *tc)
158 {
159 return getArmSystem(tc)->resetAddr();
160 }
161
162 uint8_t
163 ArmSystem::physAddrRange(ThreadContext *tc)
164 {
165 return getArmSystem(tc)->physAddrRange();
166 }
167
168 Addr
169 ArmSystem::physAddrMask(ThreadContext *tc)
170 {
171 return getArmSystem(tc)->physAddrMask();
172 }
173
174 bool
175 ArmSystem::haveLargeAsid64(ThreadContext *tc)
176 {
177 return getArmSystem(tc)->haveLargeAsid64();
178 }
179
180 bool
181 ArmSystem::haveSemihosting(ThreadContext *tc)
182 {
183 return FullSystem && getArmSystem(tc)->haveSemihosting();
184 }
185
186 bool
187 ArmSystem::callSemihosting64(ThreadContext *tc, bool gem5_ops)
188 {
189 return getArmSystem(tc)->semihosting->call64(tc, gem5_ops);
190 }
191
192 bool
193 ArmSystem::callSemihosting32(ThreadContext *tc, bool gem5_ops)
194 {
195 return getArmSystem(tc)->semihosting->call32(tc, gem5_ops);
196 }
197
198 bool
199 ArmSystem::callSemihosting(ThreadContext *tc, bool gem5_ops)
200 {
201 if (ArmISA::inAArch64(tc))
202 return callSemihosting64(tc, gem5_ops);
203 else
204 return callSemihosting32(tc, gem5_ops);
205 }
206
207 void
208 ArmSystem::callSetStandByWfi(ThreadContext *tc)
209 {
210 if (FVPBasePwrCtrl *pwr_ctrl = getArmSystem(tc)->getPowerController())
211 pwr_ctrl->setStandByWfi(tc);
212 }
213
214 void
215 ArmSystem::callClearStandByWfi(ThreadContext *tc)
216 {
217 if (FVPBasePwrCtrl *pwr_ctrl = getArmSystem(tc)->getPowerController())
218 pwr_ctrl->clearStandByWfi(tc);
219 }
220
221 bool
222 ArmSystem::callSetWakeRequest(ThreadContext *tc)
223 {
224 if (FVPBasePwrCtrl *pwr_ctrl = getArmSystem(tc)->getPowerController())
225 return pwr_ctrl->setWakeRequest(tc);
226 else
227 return true;
228 }
229
230 void
231 ArmSystem::callClearWakeRequest(ThreadContext *tc)
232 {
233 if (FVPBasePwrCtrl *pwr_ctrl = getArmSystem(tc)->getPowerController())
234 pwr_ctrl->clearWakeRequest(tc);
235 }