linux/arch/tile/include/uapi/arch/sim.h
<<
>>
Prefs
   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
  15/**
  16 * @file
  17 *
  18 * Provides an API for controlling the simulator at runtime.
  19 */
  20
  21/**
  22 * @addtogroup arch_sim
  23 * @{
  24 *
  25 * An API for controlling the simulator at runtime.
  26 *
  27 * The simulator's behavior can be modified while it is running.
  28 * For example, human-readable trace output can be enabled and disabled
  29 * around code of interest.
  30 *
  31 * There are two ways to modify simulator behavior:
  32 * programmatically, by calling various sim_* functions, and
  33 * interactively, by entering commands like "sim set functional true"
  34 * at the tile-monitor prompt.  Typing "sim help" at that prompt provides
  35 * a list of interactive commands.
  36 *
  37 * All interactive commands can also be executed programmatically by
  38 * passing a string to the sim_command function.
  39 */
  40
  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
  52/**
  53 * Return true if the current program is running under a simulator,
  54 * rather than on real hardware.  If running on hardware, other "sim_xxx()"
  55 * calls have no useful effect.
  56 */
  57static inline int
  58sim_is_simulator(void)
  59{
  60  return __insn_mfspr(SPR_SIM_CONTROL) != 0;
  61}
  62
  63
  64/**
  65 * Checkpoint the simulator state to a checkpoint file.
  66 *
  67 * The checkpoint file name is either the default or the name specified
  68 * on the command line with "--checkpoint-file".
  69 */
  70static __inline void
  71sim_checkpoint(void)
  72{
  73  __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_CHECKPOINT);
  74}
  75
  76
  77/**
  78 * Report whether or not various kinds of simulator tracing are enabled.
  79 *
  80 * @return The bitwise OR of these values:
  81 *
  82 * SIM_TRACE_CYCLES (--trace-cycles),
  83 * SIM_TRACE_ROUTER (--trace-router),
  84 * SIM_TRACE_REGISTER_WRITES (--trace-register-writes),
  85 * SIM_TRACE_DISASM (--trace-disasm),
  86 * SIM_TRACE_STALL_INFO (--trace-stall-info)
  87 * SIM_TRACE_MEMORY_CONTROLLER (--trace-memory-controller)
  88 * SIM_TRACE_L2_CACHE (--trace-l2)
  89 * SIM_TRACE_LINES (--trace-lines)
  90 */
  91static __inline unsigned int
  92sim_get_tracing(void)
  93{
  94  return __insn_mfspr(SPR_SIM_CONTROL) & SIM_TRACE_FLAG_MASK;
  95}
  96
  97
  98/**
  99 * Turn on or off different kinds of simulator tracing.
 100 *
 101 * @param mask Either one of these special values:
 102 *
 103 * SIM_TRACE_NONE (turns off tracing),
 104 * SIM_TRACE_ALL (turns on all possible tracing).
 105 *
 106 * or the bitwise OR of these values:
 107 *
 108 * SIM_TRACE_CYCLES (--trace-cycles),
 109 * SIM_TRACE_ROUTER (--trace-router),
 110 * SIM_TRACE_REGISTER_WRITES (--trace-register-writes),
 111 * SIM_TRACE_DISASM (--trace-disasm),
 112 * SIM_TRACE_STALL_INFO (--trace-stall-info)
 113 * SIM_TRACE_MEMORY_CONTROLLER (--trace-memory-controller)
 114 * SIM_TRACE_L2_CACHE (--trace-l2)
 115 * SIM_TRACE_LINES (--trace-lines)
 116 */
 117static __inline void
 118sim_set_tracing(unsigned int mask)
 119{
 120  __insn_mtspr(SPR_SIM_CONTROL, SIM_TRACE_SPR_ARG(mask));
 121}
 122
 123
 124/**
 125 * Request dumping of different kinds of simulator state.
 126 *
 127 * @param mask Either this special value:
 128 *
 129 * SIM_DUMP_ALL (dump all known state)
 130 *
 131 * or the bitwise OR of these values:
 132 *
 133 * SIM_DUMP_REGS (the register file),
 134 * SIM_DUMP_SPRS (the SPRs),
 135 * SIM_DUMP_ITLB (the iTLB),
 136 * SIM_DUMP_DTLB (the dTLB),
 137 * SIM_DUMP_L1I (the L1 I-cache),
 138 * SIM_DUMP_L1D (the L1 D-cache),
 139 * SIM_DUMP_L2 (the L2 cache),
 140 * SIM_DUMP_SNREGS (the switch register file),
 141 * SIM_DUMP_SNITLB (the switch iTLB),
 142 * SIM_DUMP_SNL1I (the switch L1 I-cache),
 143 * SIM_DUMP_BACKTRACE (the current backtrace)
 144 */
 145static __inline void
 146sim_dump(unsigned int mask)
 147{
 148  __insn_mtspr(SPR_SIM_CONTROL, SIM_DUMP_SPR_ARG(mask));
 149}
 150
 151
 152/**
 153 * Print a string to the simulator stdout.
 154 *
 155 * @param str The string to be written.
 156 */
 157static __inline void
 158sim_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 |
 166               (SIM_PUTC_FLUSH_BINARY << _SIM_CONTROL_OPERATOR_BITS));
 167}
 168
 169
 170/**
 171 * Print a string to the simulator stdout.
 172 *
 173 * @param str The string to be written (a newline is automatically added).
 174 */
 175static __inline void
 176sim_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 |
 184               (SIM_PUTC_FLUSH_STRING << _SIM_CONTROL_OPERATOR_BITS));
 185}
 186
 187
 188/**
 189 * Execute a simulator command string.
 190 *
 191 * Type 'sim help' at the tile-monitor prompt to learn what commands
 192 * are available.  Note the use of the tile-monitor "sim" command to
 193 * pass commands to the simulator.
 194 *
 195 * The argument to sim_command() does not include the leading "sim"
 196 * prefix used at the tile-monitor prompt; for example, you might call
 197 * sim_command("trace disasm").
 198 */
 199static __inline void
 200sim_command(const char* str)
 201{
 202  int c;
 203  do
 204  {
 205    c = *str++;
 206    __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_COMMAND |
 207                 (c << _SIM_CONTROL_OPERATOR_BITS));
 208  }
 209  while (c);
 210}
 211
 212
 213
 214#ifndef __DOXYGEN__
 215
 216/**
 217 * The underlying implementation of "_sim_syscall()".
 218 *
 219 * We use extra "and" instructions to ensure that all the values
 220 * we are passing to the simulator are actually valid in the registers
 221 * (i.e. returned from memory) prior to the SIM_CONTROL spr.
 222 */
 223static __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
 231static __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
 239static __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
 253static __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
 264static __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
 276static __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
 288/**
 289 * Make a special syscall to the simulator itself, if running under
 290 * simulation. This is used as the implementation of other functions
 291 * and should not be used outside this file.
 292 *
 293 * @param syscall_num The simulator syscall number.
 294 * @param nr The number of additional arguments provided.
 295 *
 296 * @return Varies by syscall.
 297 */
 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
 310static __inline int
 311sim_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
 322static __inline int
 323sim_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
 334/**
 335 * Return value from sim_query_watchpoint.
 336 */
 337struct SimQueryWatchpointStatus
 338{
 339  /**
 340   * 0 if a watchpoint fired, 1 if no watchpoint fired, or -1 for
 341   * error (meaning a bad process_id).
 342   */
 343  int syscall_status;
 344
 345  /**
 346   * The address of the watchpoint that fired (this is the address
 347   * passed to sim_add_watchpoint, not an address within that range
 348   * that actually triggered the watchpoint).
 349   */
 350  unsigned long address;
 351
 352  /** The arbitrary user_data installed by sim_add_watchpoint. */
 353  unsigned long user_data;
 354};
 355
 356
 357static __inline struct SimQueryWatchpointStatus
 358sim_query_watchpoint(unsigned int process_id)
 359{
 360  struct SimQueryWatchpointStatus status;
 361  long val = SIM_CONTROL_SYSCALL |
 362    (SIM_SYSCALL_QUERY_WATCHPOINT << _SIM_CONTROL_OPERATOR_BITS);
 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. */
 373static __inline void
 374sim_validate_lines_evicted(unsigned long long pa, unsigned long length)
 375{
 376#ifdef __LP64__
 377  _sim_syscall(SIM_SYSCALL_VALIDATE_LINES_EVICTED, 2, pa, length);
 378#else
 379  _sim_syscall(SIM_SYSCALL_VALIDATE_LINES_EVICTED, 4,
 380               0 /* dummy */, (long)(pa), (long)(pa >> 32), length);
 381#endif
 382}
 383
 384
 385/* Return the current CPU speed in cycles per second. */
 386static __inline long
 387sim_query_cpu_speed(void)
 388{
 389  return _sim_syscall(SIM_SYSCALL_QUERY_CPU_SPEED, 0);
 390}
 391
 392#endif /* !__DOXYGEN__ */
 393
 394
 395
 396
 397/**
 398 * Modify the shaping parameters of a shim.
 399 *
 400 * @param shim The shim to modify. One of:
 401 *   SIM_CONTROL_SHAPING_GBE_0
 402 *   SIM_CONTROL_SHAPING_GBE_1
 403 *   SIM_CONTROL_SHAPING_GBE_2
 404 *   SIM_CONTROL_SHAPING_GBE_3
 405 *   SIM_CONTROL_SHAPING_XGBE_0
 406 *   SIM_CONTROL_SHAPING_XGBE_1
 407 *
 408 * @param type The type of shaping. This should be the same type of
 409 * shaping that is already in place on the shim. One of:
 410 *   SIM_CONTROL_SHAPING_MULTIPLIER
 411 *   SIM_CONTROL_SHAPING_PPS
 412 *   SIM_CONTROL_SHAPING_BPS
 413 *
 414 * @param units The magnitude of the rate. One of:
 415 *   SIM_CONTROL_SHAPING_UNITS_SINGLE
 416 *   SIM_CONTROL_SHAPING_UNITS_KILO
 417 *   SIM_CONTROL_SHAPING_UNITS_MEGA
 418 *   SIM_CONTROL_SHAPING_UNITS_GIGA
 419 *
 420 * @param rate The rate to which to change it. This must fit in
 421 * SIM_CONTROL_SHAPING_RATE_BITS bits or a warning is issued and
 422 * the shaping is not changed.
 423 *
 424 * @return 0 if no problems were detected in the arguments to sim_set_shaping
 425 * or 1 if problems were detected (for example, rate does not fit in 17 bits).
 426 */
 427static __inline int
 428sim_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
 442/** Enable a set of mPIPE links.  Pass a -1 link_mask to enable all links. */
 443static __inline void
 444sim_enable_mpipe_links(unsigned mpipe, unsigned long link_mask)
 445{
 446  __insn_mtspr(SPR_SIM_CONTROL,
 447               (SIM_CONTROL_ENABLE_MPIPE_LINK_MAGIC_BYTE |
 448                (mpipe << 8) | (1 << 16) | ((uint_reg_t)link_mask << 32)));
 449}
 450
 451/** Disable a set of mPIPE links.  Pass a -1 link_mask to disable all links. */
 452static __inline void
 453sim_disable_mpipe_links(unsigned mpipe, unsigned long link_mask)
 454{
 455  __insn_mtspr(SPR_SIM_CONTROL,
 456               (SIM_CONTROL_ENABLE_MPIPE_LINK_MAGIC_BYTE |
 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
 482/**
 483 * Turn profiling on for the current task.
 484 *
 485 * Note that this has no effect if run in an environment without
 486 * profiling support (thus, the proper flags to the simulator must
 487 * be supplied).
 488 */
 489static __inline void
 490sim_profiler_enable(void)
 491{
 492  __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PROFILER_ENABLE);
 493}
 494
 495
 496/** Turn profiling off for the current task. */
 497static __inline void
 498sim_profiler_disable(void)
 499{
 500  __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PROFILER_DISABLE);
 501}
 502
 503
 504/**
 505 * Turn profiling on or off for the current task.
 506 *
 507 * @param enabled If true, turns on profiling. If false, turns it off.
 508 *
 509 * Note that this has no effect if run in an environment without
 510 * profiling support (thus, the proper flags to the simulator must
 511 * be supplied).
 512 */
 513static __inline void
 514sim_profiler_set_enabled(int enabled)
 515{
 516  int val =
 517    enabled ? SIM_CONTROL_PROFILER_ENABLE : SIM_CONTROL_PROFILER_DISABLE;
 518  __insn_mtspr(SPR_SIM_CONTROL, val);
 519}
 520
 521
 522/**
 523 * Return true if and only if profiling is currently enabled
 524 * for the current task.
 525 *
 526 * This returns false even if sim_profiler_enable() was called
 527 * if the current execution environment does not support profiling.
 528 */
 529static __inline int
 530sim_profiler_is_enabled(void)
 531{
 532  return ((__insn_mfspr(SPR_SIM_CONTROL) & SIM_PROFILER_ENABLED_MASK) != 0);
 533}
 534
 535
 536/**
 537 * Reset profiling counters to zero for the current task.
 538 *
 539 * Resetting can be done while profiling is enabled.  It does not affect
 540 * the chip-wide profiling counters.
 541 */
 542static __inline void
 543sim_profiler_clear(void)
 544{
 545  __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PROFILER_CLEAR);
 546}
 547
 548
 549/**
 550 * Enable specified chip-level profiling counters.
 551 *
 552 * Does not affect the per-task profiling counters.
 553 *
 554 * @param mask Either this special value:
 555 *
 556 * SIM_CHIP_ALL (enables all chip-level components).
 557 *
 558 * or the bitwise OR of these values:
 559 *
 560 * SIM_CHIP_MEMCTL (enable all memory controllers)
 561 * SIM_CHIP_XAUI (enable all XAUI controllers)
 562 * SIM_CHIP_MPIPE (enable all MPIPE controllers)
 563 */
 564static __inline void
 565sim_profiler_chip_enable(unsigned int mask)
 566{
 567  __insn_mtspr(SPR_SIM_CONTROL, SIM_PROFILER_CHIP_ENABLE_SPR_ARG(mask));
 568}
 569
 570
 571/**
 572 * Disable specified chip-level profiling counters.
 573 *
 574 * Does not affect the per-task profiling counters.
 575 *
 576 * @param mask Either this special value:
 577 *
 578 * SIM_CHIP_ALL (disables all chip-level components).
 579 *
 580 * or the bitwise OR of these values:
 581 *
 582 * SIM_CHIP_MEMCTL (disable all memory controllers)
 583 * SIM_CHIP_XAUI (disable all XAUI controllers)
 584 * SIM_CHIP_MPIPE (disable all MPIPE controllers)
 585 */
 586static __inline void
 587sim_profiler_chip_disable(unsigned int mask)
 588{
 589  __insn_mtspr(SPR_SIM_CONTROL, SIM_PROFILER_CHIP_DISABLE_SPR_ARG(mask));
 590}
 591
 592
 593/**
 594 * Reset specified chip-level profiling counters to zero.
 595 *
 596 * Does not affect the per-task profiling counters.
 597 *
 598 * @param mask Either this special value:
 599 *
 600 * SIM_CHIP_ALL (clears all chip-level components).
 601 *
 602 * or the bitwise OR of these values:
 603 *
 604 * SIM_CHIP_MEMCTL (clear all memory controllers)
 605 * SIM_CHIP_XAUI (clear all XAUI controllers)
 606 * SIM_CHIP_MPIPE (clear all MPIPE controllers)
 607 */
 608static __inline void
 609sim_profiler_chip_clear(unsigned int mask)
 610{
 611  __insn_mtspr(SPR_SIM_CONTROL, SIM_PROFILER_CHIP_CLEAR_SPR_ARG(mask));
 612}
 613
 614
 615/*
 616 * Event support.
 617 */
 618
 619#ifndef __DOXYGEN__
 620
 621static __inline void
 622sim_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
 629static __inline void
 630sim_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
 643/** @} */
 644