e5c4fe59201497b08d89ef60127f6217c9d5ae12
[gem5.git] / src / sim / pseudo_inst.hh
1 /*
2 * Copyright (c) 2012 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) 2003-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 #ifndef __SIM_PSEUDO_INST_HH__
42 #define __SIM_PSEUDO_INST_HH__
43
44 #include <gem5/asm/generic/m5ops.h>
45
46 class ThreadContext;
47
48 #include "arch/pseudo_inst.hh"
49 #include "arch/utility.hh"
50 #include "base/bitfield.hh"
51 #include "base/types.hh" // For Tick and Addr data types.
52 #include "debug/PseudoInst.hh"
53 #include "sim/guest_abi.hh"
54
55 struct PseudoInstABI
56 {
57 using State = int;
58 };
59
60 namespace GuestABI
61 {
62
63 template <>
64 struct Argument<PseudoInstABI, uint64_t>
65 {
66 static uint64_t
67 get(ThreadContext *tc, PseudoInstABI::State &state)
68 {
69 uint64_t result =
70 TheISA::getArgument(tc, state, sizeof(uint64_t), false);
71 state++;
72 return result;
73 }
74 };
75
76 } // namespace GuestABI
77
78 namespace PseudoInst
79 {
80
81 static inline void
82 decodeAddrOffset(Addr offset, uint8_t &func)
83 {
84 func = bits(offset, 15, 8);
85 }
86
87 void arm(ThreadContext *tc);
88 void quiesce(ThreadContext *tc);
89 void quiesceSkip(ThreadContext *tc);
90 void quiesceNs(ThreadContext *tc, uint64_t ns);
91 void quiesceCycles(ThreadContext *tc, uint64_t cycles);
92 uint64_t quiesceTime(ThreadContext *tc);
93 uint64_t readfile(ThreadContext *tc, Addr vaddr, uint64_t len,
94 uint64_t offset);
95 uint64_t writefile(ThreadContext *tc, Addr vaddr, uint64_t len,
96 uint64_t offset, Addr filenameAddr);
97 void loadsymbol(ThreadContext *xc);
98 void addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr);
99 uint64_t initParam(ThreadContext *xc, uint64_t key_str1, uint64_t key_str2);
100 uint64_t rpns(ThreadContext *tc);
101 void wakeCPU(ThreadContext *tc, uint64_t cpuid);
102 void m5exit(ThreadContext *tc, Tick delay);
103 void m5fail(ThreadContext *tc, Tick delay, uint64_t code);
104 uint64_t m5sum(ThreadContext *tc, uint64_t a, uint64_t b, uint64_t c,
105 uint64_t d, uint64_t e, uint64_t f);
106 void resetstats(ThreadContext *tc, Tick delay, Tick period);
107 void dumpstats(ThreadContext *tc, Tick delay, Tick period);
108 void dumpresetstats(ThreadContext *tc, Tick delay, Tick period);
109 void m5checkpoint(ThreadContext *tc, Tick delay, Tick period);
110 void debugbreak(ThreadContext *tc);
111 void switchcpu(ThreadContext *tc);
112 void workbegin(ThreadContext *tc, uint64_t workid, uint64_t threadid);
113 void workend(ThreadContext *tc, uint64_t workid, uint64_t threadid);
114 void m5Syscall(ThreadContext *tc);
115 void togglesync(ThreadContext *tc);
116 void triggerWorkloadEvent(ThreadContext *tc);
117
118 /**
119 * Execute a decoded M5 pseudo instruction
120 *
121 * The ISA-specific code is responsible to decode the pseudo inst
122 * function number and subfunction number. After that has been done,
123 * the rest of the instruction can be implemented in an ISA-agnostic
124 * manner using the ISA-specific getArguments functions.
125 *
126 * @param func M5 pseudo op major function number (see utility/m5/m5ops.h)
127 * @param result A reference to a uint64_t to store a result in.
128 * @return Whether the pseudo instruction was recognized/handled.
129 */
130
131 template <typename ABI, bool store_ret>
132 bool
133 pseudoInstWork(ThreadContext *tc, uint8_t func, uint64_t &result)
134 {
135 DPRINTF(PseudoInst, "PseudoInst::pseudoInst(%i)\n", func);
136
137 result = 0;
138
139 switch (func) {
140 case M5OP_ARM:
141 invokeSimcall<ABI>(tc, arm);
142 return true;
143
144 case M5OP_QUIESCE:
145 invokeSimcall<ABI>(tc, quiesce);
146 return true;
147
148 case M5OP_QUIESCE_NS:
149 invokeSimcall<ABI>(tc, quiesceNs);
150 return true;
151
152 case M5OP_QUIESCE_CYCLE:
153 invokeSimcall<ABI>(tc, quiesceCycles);
154 return true;
155
156 case M5OP_QUIESCE_TIME:
157 result = invokeSimcall<ABI, store_ret>(tc, quiesceTime);
158 return true;
159
160 case M5OP_RPNS:
161 result = invokeSimcall<ABI, store_ret>(tc, rpns);
162 return true;
163
164 case M5OP_WAKE_CPU:
165 invokeSimcall<ABI>(tc, wakeCPU);
166 return true;
167
168 case M5OP_EXIT:
169 invokeSimcall<ABI>(tc, m5exit);
170 return true;
171
172 case M5OP_FAIL:
173 invokeSimcall<ABI>(tc, m5fail);
174 return true;
175
176 // M5OP_SUM is for sanity checking the gem5 op interface.
177 case M5OP_SUM:
178 result = invokeSimcall<ABI, store_ret>(tc, m5sum);
179 return true;
180
181 case M5OP_INIT_PARAM:
182 result = invokeSimcall<ABI, store_ret>(tc, initParam);
183 return true;
184
185 case M5OP_LOAD_SYMBOL:
186 invokeSimcall<ABI>(tc, loadsymbol);
187 return true;
188
189 case M5OP_RESET_STATS:
190 invokeSimcall<ABI>(tc, resetstats);
191 return true;
192
193 case M5OP_DUMP_STATS:
194 invokeSimcall<ABI>(tc, dumpstats);
195 return true;
196
197 case M5OP_DUMP_RESET_STATS:
198 invokeSimcall<ABI>(tc, dumpresetstats);
199 return true;
200
201 case M5OP_CHECKPOINT:
202 invokeSimcall<ABI>(tc, m5checkpoint);
203 return true;
204
205 case M5OP_WRITE_FILE:
206 result = invokeSimcall<ABI, store_ret>(tc, writefile);
207 return true;
208
209 case M5OP_READ_FILE:
210 result = invokeSimcall<ABI, store_ret>(tc, readfile);
211 return true;
212
213 case M5OP_DEBUG_BREAK:
214 invokeSimcall<ABI>(tc, debugbreak);
215 return true;
216
217 case M5OP_SWITCH_CPU:
218 invokeSimcall<ABI>(tc, switchcpu);
219 return true;
220
221 case M5OP_ADD_SYMBOL:
222 invokeSimcall<ABI>(tc, addsymbol);
223 return true;
224
225 case M5OP_PANIC:
226 panic("M5 panic instruction called at %s\n", tc->pcState());
227
228 case M5OP_WORK_BEGIN:
229 invokeSimcall<ABI>(tc, workbegin);
230 return true;
231
232 case M5OP_WORK_END:
233 invokeSimcall<ABI>(tc, workend);
234 return true;
235
236 case M5OP_RESERVED1:
237 case M5OP_RESERVED2:
238 case M5OP_RESERVED3:
239 case M5OP_RESERVED4:
240 case M5OP_RESERVED5:
241 warn("Unimplemented m5 op (%#x)\n", func);
242 return false;
243
244 /* SE mode functions */
245 case M5OP_SE_SYSCALL:
246 invokeSimcall<ABI>(tc, m5Syscall);
247 return true;
248
249 case M5OP_SE_PAGE_FAULT:
250 invokeSimcall<ABI>(tc, TheISA::m5PageFault);
251 return true;
252
253 /* dist-gem5 functions */
254 case M5OP_DIST_TOGGLE_SYNC:
255 invokeSimcall<ABI>(tc, togglesync);
256 return true;
257
258 case M5OP_WORKLOAD:
259 invokeSimcall<ABI>(tc, triggerWorkloadEvent);
260 return true;
261
262 default:
263 warn("Unhandled m5 op: %#x\n", func);
264 return false;
265 }
266 }
267
268 template <typename ABI, bool store_ret=false>
269 bool
270 pseudoInst(ThreadContext *tc, uint8_t func, uint64_t &result)
271 {
272 return pseudoInstWork<ABI, store_ret>(tc, func, result);
273 }
274
275 template <typename ABI, bool store_ret=true>
276 bool
277 pseudoInst(ThreadContext *tc, uint8_t func)
278 {
279 uint64_t result;
280 return pseudoInstWork<ABI, store_ret>(tc, func, result);
281 }
282
283 } // namespace PseudoInst
284
285 #endif // __SIM_PSEUDO_INST_HH__