License cleanup: add SPDX license identifier to uapi header files with a license
[linux-2.6-block.git] / arch / tile / include / uapi / arch / sim.h
CommitLineData
e2be04c7 1/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
bf65e440
CM
2/*
3 * Copyright 2010 Tilera Corporation. All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation, version 2.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for
13 * more details.
14 */
15
16/**
17 * @file
18 *
19 * Provides an API for controlling the simulator at runtime.
20 */
21
22/**
23 * @addtogroup arch_sim
24 * @{
25 *
26 * An API for controlling the simulator at runtime.
27 *
28 * The simulator's behavior can be modified while it is running.
29 * For example, human-readable trace output can be enabled and disabled
30 * around code of interest.
31 *
32 * There are two ways to modify simulator behavior:
33 * programmatically, by calling various sim_* functions, and
34 * interactively, by entering commands like "sim set functional true"
35 * at the tile-monitor prompt. Typing "sim help" at that prompt provides
36 * a list of interactive commands.
37 *
38 * All interactive commands can also be executed programmatically by
39 * passing a string to the sim_command function.
40 */
41
42#ifndef __ARCH_SIM_H__
43#define __ARCH_SIM_H__
44
45#include <arch/sim_def.h>
46#include <arch/abi.h>
47
48#ifndef __ASSEMBLER__
49
50#include <arch/spr_def.h>
51
52
53/**
54 * Return true if the current program is running under a simulator,
55 * rather than on real hardware. If running on hardware, other "sim_xxx()"
56 * calls have no useful effect.
57 */
58static inline int
59sim_is_simulator(void)
60{
61 return __insn_mfspr(SPR_SIM_CONTROL) != 0;
62}
63
64
65/**
66 * Checkpoint the simulator state to a checkpoint file.
67 *
68 * The checkpoint file name is either the default or the name specified
69 * on the command line with "--checkpoint-file".
70 */
71static __inline void
72sim_checkpoint(void)
73{
74 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_CHECKPOINT);
75}
76
77
78/**
79 * Report whether or not various kinds of simulator tracing are enabled.
80 *
81 * @return The bitwise OR of these values:
82 *
83 * SIM_TRACE_CYCLES (--trace-cycles),
84 * SIM_TRACE_ROUTER (--trace-router),
85 * SIM_TRACE_REGISTER_WRITES (--trace-register-writes),
86 * SIM_TRACE_DISASM (--trace-disasm),
87 * SIM_TRACE_STALL_INFO (--trace-stall-info)
88 * SIM_TRACE_MEMORY_CONTROLLER (--trace-memory-controller)
89 * SIM_TRACE_L2_CACHE (--trace-l2)
90 * SIM_TRACE_LINES (--trace-lines)
91 */
92static __inline unsigned int
93sim_get_tracing(void)
94{
95 return __insn_mfspr(SPR_SIM_CONTROL) & SIM_TRACE_FLAG_MASK;
96}
97
98
99/**
100 * Turn on or off different kinds of simulator tracing.
101 *
102 * @param mask Either one of these special values:
103 *
104 * SIM_TRACE_NONE (turns off tracing),
105 * SIM_TRACE_ALL (turns on all possible tracing).
106 *
107 * or the bitwise OR of these values:
108 *
109 * SIM_TRACE_CYCLES (--trace-cycles),
110 * SIM_TRACE_ROUTER (--trace-router),
111 * SIM_TRACE_REGISTER_WRITES (--trace-register-writes),
112 * SIM_TRACE_DISASM (--trace-disasm),
113 * SIM_TRACE_STALL_INFO (--trace-stall-info)
114 * SIM_TRACE_MEMORY_CONTROLLER (--trace-memory-controller)
115 * SIM_TRACE_L2_CACHE (--trace-l2)
116 * SIM_TRACE_LINES (--trace-lines)
117 */
118static __inline void
119sim_set_tracing(unsigned int mask)
120{
121 __insn_mtspr(SPR_SIM_CONTROL, SIM_TRACE_SPR_ARG(mask));
122}
123
124
125/**
126 * Request dumping of different kinds of simulator state.
127 *
128 * @param mask Either this special value:
129 *
130 * SIM_DUMP_ALL (dump all known state)
131 *
132 * or the bitwise OR of these values:
133 *
134 * SIM_DUMP_REGS (the register file),
135 * SIM_DUMP_SPRS (the SPRs),
136 * SIM_DUMP_ITLB (the iTLB),
137 * SIM_DUMP_DTLB (the dTLB),
138 * SIM_DUMP_L1I (the L1 I-cache),
139 * SIM_DUMP_L1D (the L1 D-cache),
140 * SIM_DUMP_L2 (the L2 cache),
141 * SIM_DUMP_SNREGS (the switch register file),
142 * SIM_DUMP_SNITLB (the switch iTLB),
143 * SIM_DUMP_SNL1I (the switch L1 I-cache),
144 * SIM_DUMP_BACKTRACE (the current backtrace)
145 */
146static __inline void
147sim_dump(unsigned int mask)
148{
149 __insn_mtspr(SPR_SIM_CONTROL, SIM_DUMP_SPR_ARG(mask));
150}
151
152
153/**
154 * Print a string to the simulator stdout.
155 *
a5c149c8
CM
156 * @param str The string to be written.
157 */
158static __inline void
159sim_print(const char* str)
160{
161 for ( ; *str != '\0'; str++)
162 {
163 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC |
164 (*str << _SIM_CONTROL_OPERATOR_BITS));
165 }
166 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC |
167 (SIM_PUTC_FLUSH_BINARY << _SIM_CONTROL_OPERATOR_BITS));
168}
169
170
171/**
172 * Print a string to the simulator stdout.
173 *
174 * @param str The string to be written (a newline is automatically added).
bf65e440
CM
175 */
176static __inline void
177sim_print_string(const char* str)
178{
a5c149c8 179 for ( ; *str != '\0'; str++)
bf65e440
CM
180 {
181 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC |
a5c149c8 182 (*str << _SIM_CONTROL_OPERATOR_BITS));
bf65e440
CM
183 }
184 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC |
185 (SIM_PUTC_FLUSH_STRING << _SIM_CONTROL_OPERATOR_BITS));
186}
187
188
189/**
190 * Execute a simulator command string.
191 *
192 * Type 'sim help' at the tile-monitor prompt to learn what commands
193 * are available. Note the use of the tile-monitor "sim" command to
194 * pass commands to the simulator.
195 *
196 * The argument to sim_command() does not include the leading "sim"
197 * prefix used at the tile-monitor prompt; for example, you might call
198 * sim_command("trace disasm").
199 */
200static __inline void
201sim_command(const char* str)
202{
203 int c;
204 do
205 {
206 c = *str++;
207 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_COMMAND |
208 (c << _SIM_CONTROL_OPERATOR_BITS));
209 }
210 while (c);
211}
212
213
214
215#ifndef __DOXYGEN__
216
217/**
218 * The underlying implementation of "_sim_syscall()".
219 *
220 * We use extra "and" instructions to ensure that all the values
221 * we are passing to the simulator are actually valid in the registers
222 * (i.e. returned from memory) prior to the SIM_CONTROL spr.
223 */
a5c149c8 224static __inline long _sim_syscall0(int val)
bf65e440
CM
225{
226 long result;
227 __asm__ __volatile__ ("mtspr SIM_CONTROL, r0"
228 : "=R00" (result) : "R00" (val));
229 return result;
230}
231
a5c149c8 232static __inline long _sim_syscall1(int val, long arg1)
bf65e440
CM
233{
234 long result;
235 __asm__ __volatile__ ("{ and zero, r1, r1; mtspr SIM_CONTROL, r0 }"
236 : "=R00" (result) : "R00" (val), "R01" (arg1));
237 return result;
238}
239
a5c149c8 240static __inline long _sim_syscall2(int val, long arg1, long arg2)
bf65e440
CM
241{
242 long result;
243 __asm__ __volatile__ ("{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }"
244 : "=R00" (result)
245 : "R00" (val), "R01" (arg1), "R02" (arg2));
246 return result;
247}
248
249/* Note that _sim_syscall3() and higher are technically at risk of
250 receiving an interrupt right before the mtspr bundle, in which case
251 the register values for arguments 3 and up may still be in flight
252 to the core from a stack frame reload. */
253
a5c149c8 254static __inline long _sim_syscall3(int val, long arg1, long arg2, long arg3)
bf65e440
CM
255{
256 long result;
257 __asm__ __volatile__ ("{ and zero, r3, r3 };"
258 "{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }"
259 : "=R00" (result)
260 : "R00" (val), "R01" (arg1), "R02" (arg2),
261 "R03" (arg3));
262 return result;
263}
264
a5c149c8 265static __inline long _sim_syscall4(int val, long arg1, long arg2, long arg3,
bf65e440
CM
266 long arg4)
267{
268 long result;
269 __asm__ __volatile__ ("{ and zero, r3, r4 };"
270 "{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }"
271 : "=R00" (result)
272 : "R00" (val), "R01" (arg1), "R02" (arg2),
273 "R03" (arg3), "R04" (arg4));
274 return result;
275}
276
a5c149c8 277static __inline long _sim_syscall5(int val, long arg1, long arg2, long arg3,
bf65e440
CM
278 long arg4, long arg5)
279{
280 long result;
281 __asm__ __volatile__ ("{ and zero, r3, r4; and zero, r5, r5 };"
282 "{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }"
283 : "=R00" (result)
284 : "R00" (val), "R01" (arg1), "R02" (arg2),
285 "R03" (arg3), "R04" (arg4), "R05" (arg5));
286 return result;
287}
288
bf65e440
CM
289/**
290 * Make a special syscall to the simulator itself, if running under
291 * simulation. This is used as the implementation of other functions
292 * and should not be used outside this file.
293 *
294 * @param syscall_num The simulator syscall number.
295 * @param nr The number of additional arguments provided.
296 *
297 * @return Varies by syscall.
298 */
299#define _sim_syscall(syscall_num, nr, args...) \
300 _sim_syscall##nr( \
a5c149c8
CM
301 ((syscall_num) << _SIM_CONTROL_OPERATOR_BITS) | SIM_CONTROL_SYSCALL, \
302 ##args)
bf65e440
CM
303
304
305/* Values for the "access_mask" parameters below. */
306#define SIM_WATCHPOINT_READ 1
307#define SIM_WATCHPOINT_WRITE 2
308#define SIM_WATCHPOINT_EXECUTE 4
309
310
311static __inline int
312sim_add_watchpoint(unsigned int process_id,
313 unsigned long address,
314 unsigned long size,
315 unsigned int access_mask,
316 unsigned long user_data)
317{
318 return _sim_syscall(SIM_SYSCALL_ADD_WATCHPOINT, 5, process_id,
319 address, size, access_mask, user_data);
320}
321
322
323static __inline int
324sim_remove_watchpoint(unsigned int process_id,
325 unsigned long address,
326 unsigned long size,
327 unsigned int access_mask,
328 unsigned long user_data)
329{
330 return _sim_syscall(SIM_SYSCALL_REMOVE_WATCHPOINT, 5, process_id,
331 address, size, access_mask, user_data);
332}
333
334
335/**
336 * Return value from sim_query_watchpoint.
337 */
338struct SimQueryWatchpointStatus
339{
340 /**
341 * 0 if a watchpoint fired, 1 if no watchpoint fired, or -1 for
342 * error (meaning a bad process_id).
343 */
344 int syscall_status;
345
346 /**
347 * The address of the watchpoint that fired (this is the address
348 * passed to sim_add_watchpoint, not an address within that range
349 * that actually triggered the watchpoint).
350 */
351 unsigned long address;
352
353 /** The arbitrary user_data installed by sim_add_watchpoint. */
354 unsigned long user_data;
355};
356
357
358static __inline struct SimQueryWatchpointStatus
359sim_query_watchpoint(unsigned int process_id)
360{
361 struct SimQueryWatchpointStatus status;
362 long val = SIM_CONTROL_SYSCALL |
363 (SIM_SYSCALL_QUERY_WATCHPOINT << _SIM_CONTROL_OPERATOR_BITS);
364 __asm__ __volatile__ ("{ and zero, r1, r1; mtspr SIM_CONTROL, r0 }"
365 : "=R00" (status.syscall_status),
366 "=R01" (status.address),
367 "=R02" (status.user_data)
368 : "R00" (val), "R01" (process_id));
369 return status;
370}
371
372
373/* On the simulator, confirm lines have been evicted everywhere. */
374static __inline void
375sim_validate_lines_evicted(unsigned long long pa, unsigned long length)
376{
377#ifdef __LP64__
378 _sim_syscall(SIM_SYSCALL_VALIDATE_LINES_EVICTED, 2, pa, length);
379#else
380 _sim_syscall(SIM_SYSCALL_VALIDATE_LINES_EVICTED, 4,
381 0 /* dummy */, (long)(pa), (long)(pa >> 32), length);
382#endif
383}
384
385
a5c149c8
CM
386/* Return the current CPU speed in cycles per second. */
387static __inline long
388sim_query_cpu_speed(void)
389{
390 return _sim_syscall(SIM_SYSCALL_QUERY_CPU_SPEED, 0);
391}
392
bf65e440
CM
393#endif /* !__DOXYGEN__ */
394
395
396
397
398/**
399 * Modify the shaping parameters of a shim.
400 *
401 * @param shim The shim to modify. One of:
402 * SIM_CONTROL_SHAPING_GBE_0
403 * SIM_CONTROL_SHAPING_GBE_1
404 * SIM_CONTROL_SHAPING_GBE_2
405 * SIM_CONTROL_SHAPING_GBE_3
406 * SIM_CONTROL_SHAPING_XGBE_0
407 * SIM_CONTROL_SHAPING_XGBE_1
408 *
409 * @param type The type of shaping. This should be the same type of
410 * shaping that is already in place on the shim. One of:
411 * SIM_CONTROL_SHAPING_MULTIPLIER
412 * SIM_CONTROL_SHAPING_PPS
413 * SIM_CONTROL_SHAPING_BPS
414 *
415 * @param units The magnitude of the rate. One of:
416 * SIM_CONTROL_SHAPING_UNITS_SINGLE
417 * SIM_CONTROL_SHAPING_UNITS_KILO
418 * SIM_CONTROL_SHAPING_UNITS_MEGA
419 * SIM_CONTROL_SHAPING_UNITS_GIGA
420 *
421 * @param rate The rate to which to change it. This must fit in
422 * SIM_CONTROL_SHAPING_RATE_BITS bits or a warning is issued and
423 * the shaping is not changed.
424 *
425 * @return 0 if no problems were detected in the arguments to sim_set_shaping
426 * or 1 if problems were detected (for example, rate does not fit in 17 bits).
427 */
428static __inline int
429sim_set_shaping(unsigned shim,
430 unsigned type,
431 unsigned units,
432 unsigned rate)
433{
434 if ((rate & ~((1 << SIM_CONTROL_SHAPING_RATE_BITS) - 1)) != 0)
435 return 1;
436
437 __insn_mtspr(SPR_SIM_CONTROL, SIM_SHAPING_SPR_ARG(shim, type, units, rate));
438 return 0;
439}
440
441#ifdef __tilegx__
442
443/** Enable a set of mPIPE links. Pass a -1 link_mask to enable all links. */
444static __inline void
445sim_enable_mpipe_links(unsigned mpipe, unsigned long link_mask)
446{
447 __insn_mtspr(SPR_SIM_CONTROL,
448 (SIM_CONTROL_ENABLE_MPIPE_LINK_MAGIC_BYTE |
449 (mpipe << 8) | (1 << 16) | ((uint_reg_t)link_mask << 32)));
450}
451
452/** Disable a set of mPIPE links. Pass a -1 link_mask to disable all links. */
453static __inline void
454sim_disable_mpipe_links(unsigned mpipe, unsigned long link_mask)
455{
456 __insn_mtspr(SPR_SIM_CONTROL,
457 (SIM_CONTROL_ENABLE_MPIPE_LINK_MAGIC_BYTE |
458 (mpipe << 8) | (0 << 16) | ((uint_reg_t)link_mask << 32)));
459}
460
461#endif /* __tilegx__ */
462
463
464/*
465 * An API for changing "functional" mode.
466 */
467
468#ifndef __DOXYGEN__
469
470#define sim_enable_functional() \
471 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_ENABLE_FUNCTIONAL)
472
473#define sim_disable_functional() \
474 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_DISABLE_FUNCTIONAL)
475
476#endif /* __DOXYGEN__ */
477
478
479/*
480 * Profiler support.
481 */
482
483/**
484 * Turn profiling on for the current task.
485 *
486 * Note that this has no effect if run in an environment without
487 * profiling support (thus, the proper flags to the simulator must
488 * be supplied).
489 */
490static __inline void
491sim_profiler_enable(void)
492{
493 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PROFILER_ENABLE);
494}
495
496
497/** Turn profiling off for the current task. */
498static __inline void
499sim_profiler_disable(void)
500{
501 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PROFILER_DISABLE);
502}
503
504
505/**
506 * Turn profiling on or off for the current task.
507 *
508 * @param enabled If true, turns on profiling. If false, turns it off.
509 *
510 * Note that this has no effect if run in an environment without
511 * profiling support (thus, the proper flags to the simulator must
512 * be supplied).
513 */
514static __inline void
515sim_profiler_set_enabled(int enabled)
516{
517 int val =
518 enabled ? SIM_CONTROL_PROFILER_ENABLE : SIM_CONTROL_PROFILER_DISABLE;
519 __insn_mtspr(SPR_SIM_CONTROL, val);
520}
521
522
523/**
524 * Return true if and only if profiling is currently enabled
525 * for the current task.
526 *
527 * This returns false even if sim_profiler_enable() was called
528 * if the current execution environment does not support profiling.
529 */
530static __inline int
531sim_profiler_is_enabled(void)
532{
533 return ((__insn_mfspr(SPR_SIM_CONTROL) & SIM_PROFILER_ENABLED_MASK) != 0);
534}
535
536
537/**
538 * Reset profiling counters to zero for the current task.
539 *
540 * Resetting can be done while profiling is enabled. It does not affect
541 * the chip-wide profiling counters.
542 */
543static __inline void
544sim_profiler_clear(void)
545{
546 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PROFILER_CLEAR);
547}
548
549
550/**
551 * Enable specified chip-level profiling counters.
552 *
553 * Does not affect the per-task profiling counters.
554 *
555 * @param mask Either this special value:
556 *
557 * SIM_CHIP_ALL (enables all chip-level components).
558 *
559 * or the bitwise OR of these values:
560 *
561 * SIM_CHIP_MEMCTL (enable all memory controllers)
562 * SIM_CHIP_XAUI (enable all XAUI controllers)
563 * SIM_CHIP_MPIPE (enable all MPIPE controllers)
564 */
565static __inline void
566sim_profiler_chip_enable(unsigned int mask)
567{
568 __insn_mtspr(SPR_SIM_CONTROL, SIM_PROFILER_CHIP_ENABLE_SPR_ARG(mask));
569}
570
571
572/**
573 * Disable specified chip-level profiling counters.
574 *
575 * Does not affect the per-task profiling counters.
576 *
577 * @param mask Either this special value:
578 *
579 * SIM_CHIP_ALL (disables all chip-level components).
580 *
581 * or the bitwise OR of these values:
582 *
583 * SIM_CHIP_MEMCTL (disable all memory controllers)
584 * SIM_CHIP_XAUI (disable all XAUI controllers)
585 * SIM_CHIP_MPIPE (disable all MPIPE controllers)
586 */
587static __inline void
588sim_profiler_chip_disable(unsigned int mask)
589{
590 __insn_mtspr(SPR_SIM_CONTROL, SIM_PROFILER_CHIP_DISABLE_SPR_ARG(mask));
591}
592
593
594/**
595 * Reset specified chip-level profiling counters to zero.
596 *
597 * Does not affect the per-task profiling counters.
598 *
599 * @param mask Either this special value:
600 *
601 * SIM_CHIP_ALL (clears all chip-level components).
602 *
603 * or the bitwise OR of these values:
604 *
605 * SIM_CHIP_MEMCTL (clear all memory controllers)
606 * SIM_CHIP_XAUI (clear all XAUI controllers)
607 * SIM_CHIP_MPIPE (clear all MPIPE controllers)
608 */
609static __inline void
610sim_profiler_chip_clear(unsigned int mask)
611{
612 __insn_mtspr(SPR_SIM_CONTROL, SIM_PROFILER_CHIP_CLEAR_SPR_ARG(mask));
613}
614
615
616/*
617 * Event support.
618 */
619
620#ifndef __DOXYGEN__
621
622static __inline void
623sim_event_begin(unsigned int x)
624{
625#if defined(__tile__) && !defined(__NO_EVENT_SPR__)
626 __insn_mtspr(SPR_EVENT_BEGIN, x);
627#endif
628}
629
630static __inline void
631sim_event_end(unsigned int x)
632{
633#if defined(__tile__) && !defined(__NO_EVENT_SPR__)
634 __insn_mtspr(SPR_EVENT_END, x);
635#endif
636}
637
638#endif /* !__DOXYGEN__ */
639
640#endif /* !__ASSEMBLER__ */
641
642#endif /* !__ARCH_SIM_H__ */
643
644/** @} */