GNU Linux-libre 4.14.254-gnu1
[releases.git] / arch / tile / include / uapi / arch / sim.h
1 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
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  */
58 static inline int
59 sim_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  */
71 static __inline void
72 sim_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  */
92 static __inline unsigned int
93 sim_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  */
118 static __inline void
119 sim_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  */
146 static __inline void
147 sim_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  *
156  * @param str The string to be written.
157  */
158 static __inline void
159 sim_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).
175  */
176 static __inline void
177 sim_print_string(const char* str)
178 {
179   for ( ; *str != '\0'; str++)
180   {
181     __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC |
182                  (*str << _SIM_CONTROL_OPERATOR_BITS));
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  */
200 static __inline void
201 sim_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  */
224 static __inline long _sim_syscall0(int val)
225 {
226   long result;
227   __asm__ __volatile__ ("mtspr SIM_CONTROL, r0"
228                         : "=R00" (result) : "R00" (val));
229   return result;
230 }
231
232 static __inline long _sim_syscall1(int val, long arg1)
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
240 static __inline long _sim_syscall2(int val, long arg1, long arg2)
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
254 static __inline long _sim_syscall3(int val, long arg1, long arg2, long arg3)
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
265 static __inline long _sim_syscall4(int val, long arg1, long arg2, long arg3,
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
277 static __inline long _sim_syscall5(int val, long arg1, long arg2, long arg3,
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
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( \
301     ((syscall_num) << _SIM_CONTROL_OPERATOR_BITS) | SIM_CONTROL_SYSCALL, \
302     ##args)
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
311 static __inline int
312 sim_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
323 static __inline int
324 sim_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  */
338 struct 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
358 static __inline struct SimQueryWatchpointStatus
359 sim_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. */
374 static __inline void
375 sim_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
386 /* Return the current CPU speed in cycles per second. */
387 static __inline long
388 sim_query_cpu_speed(void)
389 {
390   return _sim_syscall(SIM_SYSCALL_QUERY_CPU_SPEED, 0);
391 }
392
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  */
428 static __inline int
429 sim_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. */
444 static __inline void
445 sim_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. */
453 static __inline void
454 sim_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  */
490 static __inline void
491 sim_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. */
498 static __inline void
499 sim_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  */
514 static __inline void
515 sim_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  */
530 static __inline int
531 sim_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  */
543 static __inline void
544 sim_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  */
565 static __inline void
566 sim_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  */
587 static __inline void
588 sim_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  */
609 static __inline void
610 sim_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
622 static __inline void
623 sim_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
630 static __inline void
631 sim_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 /** @} */