Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sim.h
Go to the documentation of this file.
1 /*
2  * Copyright 2010 Tilera Corporation. All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation, version 2.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11  * NON INFRINGEMENT. See the GNU General Public License for
12  * more details.
13  */
14 
41 #ifndef __ARCH_SIM_H__
42 #define __ARCH_SIM_H__
43 
44 #include <arch/sim_def.h>
45 #include <arch/abi.h>
46 
47 #ifndef __ASSEMBLER__
48 
49 #include <arch/spr_def.h>
50 
51 
57 static inline int
58 sim_is_simulator(void)
59 {
60  return __insn_mfspr(SPR_SIM_CONTROL) != 0;
61 }
62 
63 
70 static __inline void
71 sim_checkpoint(void)
72 {
74 }
75 
76 
91 static __inline unsigned int
92 sim_get_tracing(void)
93 {
94  return __insn_mfspr(SPR_SIM_CONTROL) & SIM_TRACE_FLAG_MASK;
95 }
96 
97 
117 static __inline void
118 sim_set_tracing(unsigned int mask)
119 {
120  __insn_mtspr(SPR_SIM_CONTROL, SIM_TRACE_SPR_ARG(mask));
121 }
122 
123 
145 static __inline void
146 sim_dump(unsigned int mask)
147 {
148  __insn_mtspr(SPR_SIM_CONTROL, SIM_DUMP_SPR_ARG(mask));
149 }
150 
151 
157 static __inline void
158 sim_print(const char* str)
159 {
160  for ( ; *str != '\0'; str++)
161  {
162  __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC |
163  (*str << _SIM_CONTROL_OPERATOR_BITS));
164  }
165  __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC |
167 }
168 
169 
175 static __inline void
176 sim_print_string(const char* str)
177 {
178  for ( ; *str != '\0'; str++)
179  {
180  __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC |
181  (*str << _SIM_CONTROL_OPERATOR_BITS));
182  }
183  __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC |
185 }
186 
187 
199 static __inline void
200 sim_command(const char* str)
201 {
202  int c;
203  do
204  {
205  c = *str++;
206  __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_COMMAND |
208  }
209  while (c);
210 }
211 
212 
213 
214 #ifndef __DOXYGEN__
215 
223 static __inline long _sim_syscall0(int val)
224 {
225  long result;
226  __asm__ __volatile__ ("mtspr SIM_CONTROL, r0"
227  : "=R00" (result) : "R00" (val));
228  return result;
229 }
230 
231 static __inline long _sim_syscall1(int val, long arg1)
232 {
233  long result;
234  __asm__ __volatile__ ("{ and zero, r1, r1; mtspr SIM_CONTROL, r0 }"
235  : "=R00" (result) : "R00" (val), "R01" (arg1));
236  return result;
237 }
238 
239 static __inline long _sim_syscall2(int val, long arg1, long arg2)
240 {
241  long result;
242  __asm__ __volatile__ ("{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }"
243  : "=R00" (result)
244  : "R00" (val), "R01" (arg1), "R02" (arg2));
245  return result;
246 }
247 
248 /* Note that _sim_syscall3() and higher are technically at risk of
249  receiving an interrupt right before the mtspr bundle, in which case
250  the register values for arguments 3 and up may still be in flight
251  to the core from a stack frame reload. */
252 
253 static __inline long _sim_syscall3(int val, long arg1, long arg2, long arg3)
254 {
255  long result;
256  __asm__ __volatile__ ("{ and zero, r3, r3 };"
257  "{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }"
258  : "=R00" (result)
259  : "R00" (val), "R01" (arg1), "R02" (arg2),
260  "R03" (arg3));
261  return result;
262 }
263 
264 static __inline long _sim_syscall4(int val, long arg1, long arg2, long arg3,
265  long arg4)
266 {
267  long result;
268  __asm__ __volatile__ ("{ and zero, r3, r4 };"
269  "{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }"
270  : "=R00" (result)
271  : "R00" (val), "R01" (arg1), "R02" (arg2),
272  "R03" (arg3), "R04" (arg4));
273  return result;
274 }
275 
276 static __inline long _sim_syscall5(int val, long arg1, long arg2, long arg3,
277  long arg4, long arg5)
278 {
279  long result;
280  __asm__ __volatile__ ("{ and zero, r3, r4; and zero, r5, r5 };"
281  "{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }"
282  : "=R00" (result)
283  : "R00" (val), "R01" (arg1), "R02" (arg2),
284  "R03" (arg3), "R04" (arg4), "R05" (arg5));
285  return result;
286 }
287 
298 #define _sim_syscall(syscall_num, nr, args...) \
299  _sim_syscall##nr( \
300  ((syscall_num) << _SIM_CONTROL_OPERATOR_BITS) | SIM_CONTROL_SYSCALL, \
301  ##args)
302 
303 
304 /* Values for the "access_mask" parameters below. */
305 #define SIM_WATCHPOINT_READ 1
306 #define SIM_WATCHPOINT_WRITE 2
307 #define SIM_WATCHPOINT_EXECUTE 4
308 
309 
310 static __inline int
311 sim_add_watchpoint(unsigned int process_id,
312  unsigned long address,
313  unsigned long size,
314  unsigned int access_mask,
315  unsigned long user_data)
316 {
317  return _sim_syscall(SIM_SYSCALL_ADD_WATCHPOINT, 5, process_id,
318  address, size, access_mask, user_data);
319 }
320 
321 
322 static __inline int
323 sim_remove_watchpoint(unsigned int process_id,
324  unsigned long address,
325  unsigned long size,
326  unsigned int access_mask,
327  unsigned long user_data)
328 {
329  return _sim_syscall(SIM_SYSCALL_REMOVE_WATCHPOINT, 5, process_id,
330  address, size, access_mask, user_data);
331 }
332 
333 
338 {
344 
350  unsigned long address;
351 
353  unsigned long user_data;
354 };
355 
356 
358 sim_query_watchpoint(unsigned int process_id)
359 {
360  struct SimQueryWatchpointStatus status;
361  long val = SIM_CONTROL_SYSCALL |
363  __asm__ __volatile__ ("{ and zero, r1, r1; mtspr SIM_CONTROL, r0 }"
364  : "=R00" (status.syscall_status),
365  "=R01" (status.address),
366  "=R02" (status.user_data)
367  : "R00" (val), "R01" (process_id));
368  return status;
369 }
370 
371 
372 /* On the simulator, confirm lines have been evicted everywhere. */
373 static __inline void
374 sim_validate_lines_evicted(unsigned long long pa, unsigned long length)
375 {
376 #ifdef __LP64__
378 #else
380  0 /* dummy */, (long)(pa), (long)(pa >> 32), length);
381 #endif
382 }
383 
384 
385 /* Return the current CPU speed in cycles per second. */
386 static __inline long
387 sim_query_cpu_speed(void)
388 {
390 }
391 
392 #endif /* !__DOXYGEN__ */
393 
394 
395 
396 
427 static __inline int
428 sim_set_shaping(unsigned shim,
429  unsigned type,
430  unsigned units,
431  unsigned rate)
432 {
433  if ((rate & ~((1 << SIM_CONTROL_SHAPING_RATE_BITS) - 1)) != 0)
434  return 1;
435 
436  __insn_mtspr(SPR_SIM_CONTROL, SIM_SHAPING_SPR_ARG(shim, type, units, rate));
437  return 0;
438 }
439 
440 #ifdef __tilegx__
441 
443 static __inline void
444 sim_enable_mpipe_links(unsigned mpipe, unsigned long link_mask)
445 {
446  __insn_mtspr(SPR_SIM_CONTROL,
448  (mpipe << 8) | (1 << 16) | ((uint_reg_t)link_mask << 32)));
449 }
450 
452 static __inline void
453 sim_disable_mpipe_links(unsigned mpipe, unsigned long link_mask)
454 {
455  __insn_mtspr(SPR_SIM_CONTROL,
457  (mpipe << 8) | (0 << 16) | ((uint_reg_t)link_mask << 32)));
458 }
459 
460 #endif /* __tilegx__ */
461 
462 
463 /*
464  * An API for changing "functional" mode.
465  */
466 
467 #ifndef __DOXYGEN__
468 
469 #define sim_enable_functional() \
470  __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_ENABLE_FUNCTIONAL)
471 
472 #define sim_disable_functional() \
473  __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_DISABLE_FUNCTIONAL)
474 
475 #endif /* __DOXYGEN__ */
476 
477 
478 /*
479  * Profiler support.
480  */
481 
489 static __inline void
490 sim_profiler_enable(void)
491 {
493 }
494 
495 
497 static __inline void
498 sim_profiler_disable(void)
499 {
501 }
502 
503 
513 static __inline void
514 sim_profiler_set_enabled(int enabled)
515 {
516  int val =
518  __insn_mtspr(SPR_SIM_CONTROL, val);
519 }
520 
521 
529 static __inline int
530 sim_profiler_is_enabled(void)
531 {
532  return ((__insn_mfspr(SPR_SIM_CONTROL) & SIM_PROFILER_ENABLED_MASK) != 0);
533 }
534 
535 
542 static __inline void
543 sim_profiler_clear(void)
544 {
546 }
547 
548 
564 static __inline void
565 sim_profiler_chip_enable(unsigned int mask)
566 {
568 }
569 
570 
586 static __inline void
587 sim_profiler_chip_disable(unsigned int mask)
588 {
590 }
591 
592 
608 static __inline void
609 sim_profiler_chip_clear(unsigned int mask)
610 {
612 }
613 
614 
615 /*
616  * Event support.
617  */
618 
619 #ifndef __DOXYGEN__
620 
621 static __inline void
622 sim_event_begin(unsigned int x)
623 {
624 #if defined(__tile__) && !defined(__NO_EVENT_SPR__)
625  __insn_mtspr(SPR_EVENT_BEGIN, x);
626 #endif
627 }
628 
629 static __inline void
630 sim_event_end(unsigned int x)
631 {
632 #if defined(__tile__) && !defined(__NO_EVENT_SPR__)
633  __insn_mtspr(SPR_EVENT_END, x);
634 #endif
635 }
636 
637 #endif /* !__DOXYGEN__ */
638 
639 #endif /* !__ASSEMBLER__ */
640 
641 #endif /* !__ARCH_SIM_H__ */
642