Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arch/tile: add Tilera's <arch/sim.h> header as an open-source header

This change adds one of the Tilera standard <arch> headers to the set
of headers shipped with Linux. The <arch/sim.h> header provides
methods for programmatically interacting with the Tilera simulator.

The current <arch/sim.h> provides inline assembly for the _sim_syscall
function, so the declaration and definition previously provided
manually in Linux are no longer needed. We now use the standard
sim_validate_lines_evicted() method from <arch/sim.h> rather than
rolling our own direct call to sim_syscall().

Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>

+622 -37
+619
arch/tile/include/arch/sim.h
··· 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 + */ 57 + static inline int 58 + sim_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 + */ 70 + static __inline void 71 + sim_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 + */ 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 + 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 + */ 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 + 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 + */ 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 + 152 + /** 153 + * Print a string to the simulator stdout. 154 + * 155 + * @param str The string to be written; a newline is automatically added. 156 + */ 157 + static __inline void 158 + sim_print_string(const char* str) 159 + { 160 + int i; 161 + for (i = 0; str[i] != 0; i++) 162 + { 163 + __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC | 164 + (str[i] << _SIM_CONTROL_OPERATOR_BITS)); 165 + } 166 + __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC | 167 + (SIM_PUTC_FLUSH_STRING << _SIM_CONTROL_OPERATOR_BITS)); 168 + } 169 + 170 + 171 + /** 172 + * Execute a simulator command string. 173 + * 174 + * Type 'sim help' at the tile-monitor prompt to learn what commands 175 + * are available. Note the use of the tile-monitor "sim" command to 176 + * pass commands to the simulator. 177 + * 178 + * The argument to sim_command() does not include the leading "sim" 179 + * prefix used at the tile-monitor prompt; for example, you might call 180 + * sim_command("trace disasm"). 181 + */ 182 + static __inline void 183 + sim_command(const char* str) 184 + { 185 + int c; 186 + do 187 + { 188 + c = *str++; 189 + __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_COMMAND | 190 + (c << _SIM_CONTROL_OPERATOR_BITS)); 191 + } 192 + while (c); 193 + } 194 + 195 + 196 + 197 + #ifndef __DOXYGEN__ 198 + 199 + /** 200 + * The underlying implementation of "_sim_syscall()". 201 + * 202 + * We use extra "and" instructions to ensure that all the values 203 + * we are passing to the simulator are actually valid in the registers 204 + * (i.e. returned from memory) prior to the SIM_CONTROL spr. 205 + */ 206 + static __inline int _sim_syscall0(int val) 207 + { 208 + long result; 209 + __asm__ __volatile__ ("mtspr SIM_CONTROL, r0" 210 + : "=R00" (result) : "R00" (val)); 211 + return result; 212 + } 213 + 214 + static __inline int _sim_syscall1(int val, long arg1) 215 + { 216 + long result; 217 + __asm__ __volatile__ ("{ and zero, r1, r1; mtspr SIM_CONTROL, r0 }" 218 + : "=R00" (result) : "R00" (val), "R01" (arg1)); 219 + return result; 220 + } 221 + 222 + static __inline int _sim_syscall2(int val, long arg1, long arg2) 223 + { 224 + long result; 225 + __asm__ __volatile__ ("{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }" 226 + : "=R00" (result) 227 + : "R00" (val), "R01" (arg1), "R02" (arg2)); 228 + return result; 229 + } 230 + 231 + /* Note that _sim_syscall3() and higher are technically at risk of 232 + receiving an interrupt right before the mtspr bundle, in which case 233 + the register values for arguments 3 and up may still be in flight 234 + to the core from a stack frame reload. */ 235 + 236 + static __inline int _sim_syscall3(int val, long arg1, long arg2, long arg3) 237 + { 238 + long result; 239 + __asm__ __volatile__ ("{ and zero, r3, r3 };" 240 + "{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }" 241 + : "=R00" (result) 242 + : "R00" (val), "R01" (arg1), "R02" (arg2), 243 + "R03" (arg3)); 244 + return result; 245 + } 246 + 247 + static __inline int _sim_syscall4(int val, long arg1, long arg2, long arg3, 248 + long arg4) 249 + { 250 + long result; 251 + __asm__ __volatile__ ("{ and zero, r3, r4 };" 252 + "{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }" 253 + : "=R00" (result) 254 + : "R00" (val), "R01" (arg1), "R02" (arg2), 255 + "R03" (arg3), "R04" (arg4)); 256 + return result; 257 + } 258 + 259 + static __inline int _sim_syscall5(int val, long arg1, long arg2, long arg3, 260 + long arg4, long arg5) 261 + { 262 + long result; 263 + __asm__ __volatile__ ("{ and zero, r3, r4; and zero, r5, r5 };" 264 + "{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }" 265 + : "=R00" (result) 266 + : "R00" (val), "R01" (arg1), "R02" (arg2), 267 + "R03" (arg3), "R04" (arg4), "R05" (arg5)); 268 + return result; 269 + } 270 + 271 + 272 + /** 273 + * Make a special syscall to the simulator itself, if running under 274 + * simulation. This is used as the implementation of other functions 275 + * and should not be used outside this file. 276 + * 277 + * @param syscall_num The simulator syscall number. 278 + * @param nr The number of additional arguments provided. 279 + * 280 + * @return Varies by syscall. 281 + */ 282 + #define _sim_syscall(syscall_num, nr, args...) \ 283 + _sim_syscall##nr( \ 284 + ((syscall_num) << _SIM_CONTROL_OPERATOR_BITS) | SIM_CONTROL_SYSCALL, args) 285 + 286 + 287 + /* Values for the "access_mask" parameters below. */ 288 + #define SIM_WATCHPOINT_READ 1 289 + #define SIM_WATCHPOINT_WRITE 2 290 + #define SIM_WATCHPOINT_EXECUTE 4 291 + 292 + 293 + static __inline int 294 + sim_add_watchpoint(unsigned int process_id, 295 + unsigned long address, 296 + unsigned long size, 297 + unsigned int access_mask, 298 + unsigned long user_data) 299 + { 300 + return _sim_syscall(SIM_SYSCALL_ADD_WATCHPOINT, 5, process_id, 301 + address, size, access_mask, user_data); 302 + } 303 + 304 + 305 + static __inline int 306 + sim_remove_watchpoint(unsigned int process_id, 307 + unsigned long address, 308 + unsigned long size, 309 + unsigned int access_mask, 310 + unsigned long user_data) 311 + { 312 + return _sim_syscall(SIM_SYSCALL_REMOVE_WATCHPOINT, 5, process_id, 313 + address, size, access_mask, user_data); 314 + } 315 + 316 + 317 + /** 318 + * Return value from sim_query_watchpoint. 319 + */ 320 + struct SimQueryWatchpointStatus 321 + { 322 + /** 323 + * 0 if a watchpoint fired, 1 if no watchpoint fired, or -1 for 324 + * error (meaning a bad process_id). 325 + */ 326 + int syscall_status; 327 + 328 + /** 329 + * The address of the watchpoint that fired (this is the address 330 + * passed to sim_add_watchpoint, not an address within that range 331 + * that actually triggered the watchpoint). 332 + */ 333 + unsigned long address; 334 + 335 + /** The arbitrary user_data installed by sim_add_watchpoint. */ 336 + unsigned long user_data; 337 + }; 338 + 339 + 340 + static __inline struct SimQueryWatchpointStatus 341 + sim_query_watchpoint(unsigned int process_id) 342 + { 343 + struct SimQueryWatchpointStatus status; 344 + long val = SIM_CONTROL_SYSCALL | 345 + (SIM_SYSCALL_QUERY_WATCHPOINT << _SIM_CONTROL_OPERATOR_BITS); 346 + __asm__ __volatile__ ("{ and zero, r1, r1; mtspr SIM_CONTROL, r0 }" 347 + : "=R00" (status.syscall_status), 348 + "=R01" (status.address), 349 + "=R02" (status.user_data) 350 + : "R00" (val), "R01" (process_id)); 351 + return status; 352 + } 353 + 354 + 355 + /* On the simulator, confirm lines have been evicted everywhere. */ 356 + static __inline void 357 + sim_validate_lines_evicted(unsigned long long pa, unsigned long length) 358 + { 359 + #ifdef __LP64__ 360 + _sim_syscall(SIM_SYSCALL_VALIDATE_LINES_EVICTED, 2, pa, length); 361 + #else 362 + _sim_syscall(SIM_SYSCALL_VALIDATE_LINES_EVICTED, 4, 363 + 0 /* dummy */, (long)(pa), (long)(pa >> 32), length); 364 + #endif 365 + } 366 + 367 + 368 + #endif /* !__DOXYGEN__ */ 369 + 370 + 371 + 372 + 373 + /** 374 + * Modify the shaping parameters of a shim. 375 + * 376 + * @param shim The shim to modify. One of: 377 + * SIM_CONTROL_SHAPING_GBE_0 378 + * SIM_CONTROL_SHAPING_GBE_1 379 + * SIM_CONTROL_SHAPING_GBE_2 380 + * SIM_CONTROL_SHAPING_GBE_3 381 + * SIM_CONTROL_SHAPING_XGBE_0 382 + * SIM_CONTROL_SHAPING_XGBE_1 383 + * 384 + * @param type The type of shaping. This should be the same type of 385 + * shaping that is already in place on the shim. One of: 386 + * SIM_CONTROL_SHAPING_MULTIPLIER 387 + * SIM_CONTROL_SHAPING_PPS 388 + * SIM_CONTROL_SHAPING_BPS 389 + * 390 + * @param units The magnitude of the rate. One of: 391 + * SIM_CONTROL_SHAPING_UNITS_SINGLE 392 + * SIM_CONTROL_SHAPING_UNITS_KILO 393 + * SIM_CONTROL_SHAPING_UNITS_MEGA 394 + * SIM_CONTROL_SHAPING_UNITS_GIGA 395 + * 396 + * @param rate The rate to which to change it. This must fit in 397 + * SIM_CONTROL_SHAPING_RATE_BITS bits or a warning is issued and 398 + * the shaping is not changed. 399 + * 400 + * @return 0 if no problems were detected in the arguments to sim_set_shaping 401 + * or 1 if problems were detected (for example, rate does not fit in 17 bits). 402 + */ 403 + static __inline int 404 + sim_set_shaping(unsigned shim, 405 + unsigned type, 406 + unsigned units, 407 + unsigned rate) 408 + { 409 + if ((rate & ~((1 << SIM_CONTROL_SHAPING_RATE_BITS) - 1)) != 0) 410 + return 1; 411 + 412 + __insn_mtspr(SPR_SIM_CONTROL, SIM_SHAPING_SPR_ARG(shim, type, units, rate)); 413 + return 0; 414 + } 415 + 416 + #ifdef __tilegx__ 417 + 418 + /** Enable a set of mPIPE links. Pass a -1 link_mask to enable all links. */ 419 + static __inline void 420 + sim_enable_mpipe_links(unsigned mpipe, unsigned long link_mask) 421 + { 422 + __insn_mtspr(SPR_SIM_CONTROL, 423 + (SIM_CONTROL_ENABLE_MPIPE_LINK_MAGIC_BYTE | 424 + (mpipe << 8) | (1 << 16) | ((uint_reg_t)link_mask << 32))); 425 + } 426 + 427 + /** Disable a set of mPIPE links. Pass a -1 link_mask to disable all links. */ 428 + static __inline void 429 + sim_disable_mpipe_links(unsigned mpipe, unsigned long link_mask) 430 + { 431 + __insn_mtspr(SPR_SIM_CONTROL, 432 + (SIM_CONTROL_ENABLE_MPIPE_LINK_MAGIC_BYTE | 433 + (mpipe << 8) | (0 << 16) | ((uint_reg_t)link_mask << 32))); 434 + } 435 + 436 + #endif /* __tilegx__ */ 437 + 438 + 439 + /* 440 + * An API for changing "functional" mode. 441 + */ 442 + 443 + #ifndef __DOXYGEN__ 444 + 445 + #define sim_enable_functional() \ 446 + __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_ENABLE_FUNCTIONAL) 447 + 448 + #define sim_disable_functional() \ 449 + __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_DISABLE_FUNCTIONAL) 450 + 451 + #endif /* __DOXYGEN__ */ 452 + 453 + 454 + /* 455 + * Profiler support. 456 + */ 457 + 458 + /** 459 + * Turn profiling on for the current task. 460 + * 461 + * Note that this has no effect if run in an environment without 462 + * profiling support (thus, the proper flags to the simulator must 463 + * be supplied). 464 + */ 465 + static __inline void 466 + sim_profiler_enable(void) 467 + { 468 + __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PROFILER_ENABLE); 469 + } 470 + 471 + 472 + /** Turn profiling off for the current task. */ 473 + static __inline void 474 + sim_profiler_disable(void) 475 + { 476 + __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PROFILER_DISABLE); 477 + } 478 + 479 + 480 + /** 481 + * Turn profiling on or off for the current task. 482 + * 483 + * @param enabled If true, turns on profiling. If false, turns it off. 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 + */ 489 + static __inline void 490 + sim_profiler_set_enabled(int enabled) 491 + { 492 + int val = 493 + enabled ? SIM_CONTROL_PROFILER_ENABLE : SIM_CONTROL_PROFILER_DISABLE; 494 + __insn_mtspr(SPR_SIM_CONTROL, val); 495 + } 496 + 497 + 498 + /** 499 + * Return true if and only if profiling is currently enabled 500 + * for the current task. 501 + * 502 + * This returns false even if sim_profiler_enable() was called 503 + * if the current execution environment does not support profiling. 504 + */ 505 + static __inline int 506 + sim_profiler_is_enabled(void) 507 + { 508 + return ((__insn_mfspr(SPR_SIM_CONTROL) & SIM_PROFILER_ENABLED_MASK) != 0); 509 + } 510 + 511 + 512 + /** 513 + * Reset profiling counters to zero for the current task. 514 + * 515 + * Resetting can be done while profiling is enabled. It does not affect 516 + * the chip-wide profiling counters. 517 + */ 518 + static __inline void 519 + sim_profiler_clear(void) 520 + { 521 + __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PROFILER_CLEAR); 522 + } 523 + 524 + 525 + /** 526 + * Enable specified chip-level profiling counters. 527 + * 528 + * Does not affect the per-task profiling counters. 529 + * 530 + * @param mask Either this special value: 531 + * 532 + * SIM_CHIP_ALL (enables all chip-level components). 533 + * 534 + * or the bitwise OR of these values: 535 + * 536 + * SIM_CHIP_MEMCTL (enable all memory controllers) 537 + * SIM_CHIP_XAUI (enable all XAUI controllers) 538 + * SIM_CHIP_MPIPE (enable all MPIPE controllers) 539 + */ 540 + static __inline void 541 + sim_profiler_chip_enable(unsigned int mask) 542 + { 543 + __insn_mtspr(SPR_SIM_CONTROL, SIM_PROFILER_CHIP_ENABLE_SPR_ARG(mask)); 544 + } 545 + 546 + 547 + /** 548 + * Disable specified chip-level profiling counters. 549 + * 550 + * Does not affect the per-task profiling counters. 551 + * 552 + * @param mask Either this special value: 553 + * 554 + * SIM_CHIP_ALL (disables all chip-level components). 555 + * 556 + * or the bitwise OR of these values: 557 + * 558 + * SIM_CHIP_MEMCTL (disable all memory controllers) 559 + * SIM_CHIP_XAUI (disable all XAUI controllers) 560 + * SIM_CHIP_MPIPE (disable all MPIPE controllers) 561 + */ 562 + static __inline void 563 + sim_profiler_chip_disable(unsigned int mask) 564 + { 565 + __insn_mtspr(SPR_SIM_CONTROL, SIM_PROFILER_CHIP_DISABLE_SPR_ARG(mask)); 566 + } 567 + 568 + 569 + /** 570 + * Reset specified chip-level profiling counters to zero. 571 + * 572 + * Does not affect the per-task profiling counters. 573 + * 574 + * @param mask Either this special value: 575 + * 576 + * SIM_CHIP_ALL (clears all chip-level components). 577 + * 578 + * or the bitwise OR of these values: 579 + * 580 + * SIM_CHIP_MEMCTL (clear all memory controllers) 581 + * SIM_CHIP_XAUI (clear all XAUI controllers) 582 + * SIM_CHIP_MPIPE (clear all MPIPE controllers) 583 + */ 584 + static __inline void 585 + sim_profiler_chip_clear(unsigned int mask) 586 + { 587 + __insn_mtspr(SPR_SIM_CONTROL, SIM_PROFILER_CHIP_CLEAR_SPR_ARG(mask)); 588 + } 589 + 590 + 591 + /* 592 + * Event support. 593 + */ 594 + 595 + #ifndef __DOXYGEN__ 596 + 597 + static __inline void 598 + sim_event_begin(unsigned int x) 599 + { 600 + #if defined(__tile__) && !defined(__NO_EVENT_SPR__) 601 + __insn_mtspr(SPR_EVENT_BEGIN, x); 602 + #endif 603 + } 604 + 605 + static __inline void 606 + sim_event_end(unsigned int x) 607 + { 608 + #if defined(__tile__) && !defined(__NO_EVENT_SPR__) 609 + __insn_mtspr(SPR_EVENT_END, x); 610 + #endif 611 + } 612 + 613 + #endif /* !__DOXYGEN__ */ 614 + 615 + #endif /* !__ASSEMBLER__ */ 616 + 617 + #endif /* !__ARCH_SIM_H__ */ 618 + 619 + /** @} */
-7
arch/tile/include/asm/system.h
··· 217 217 } while (0) 218 218 #endif 219 219 220 - /* Invoke the simulator "syscall" mechanism (see arch/tile/kernel/entry.S). */ 221 - extern int _sim_syscall(int syscall_num, ...); 222 - #define sim_syscall(syscall_num, ...) \ 223 - _sim_syscall(SIM_CONTROL_SYSCALL + \ 224 - ((syscall_num) << _SIM_CONTROL_OPERATOR_BITS), \ 225 - ## __VA_ARGS__) 226 - 227 220 /* 228 221 * Kernel threads can check to see if they need to migrate their 229 222 * stack whenever they return from a context switch; for user
-22
arch/tile/kernel/entry.S
··· 25 25 { move r0, lr; jrp lr } 26 26 STD_ENDPROC(current_text_addr) 27 27 28 - STD_ENTRY(_sim_syscall) 29 - /* 30 - * Wait for r0-r9 to be ready (and lr on the off chance we 31 - * want the syscall to locate its caller), then make a magic 32 - * simulator syscall. 33 - * 34 - * We carefully stall until the registers are readable in case they 35 - * are the target of a slow load, etc. so that tile-sim will 36 - * definitely be able to read all of them inside the magic syscall. 37 - * 38 - * Technically this is wrong for r3-r9 and lr, since an interrupt 39 - * could come in and restore the registers with a slow load right 40 - * before executing the mtspr. We may need to modify tile-sim to 41 - * explicitly stall for this case, but we do not yet have 42 - * a way to implement such a stall. 43 - */ 44 - { and zero, lr, r9 ; and zero, r8, r7 } 45 - { and zero, r6, r5 ; and zero, r4, r3 } 46 - { and zero, r2, r1 ; mtspr SIM_CONTROL, r0 } 47 - { jrp lr } 48 - STD_ENDPROC(_sim_syscall) 49 - 50 28 /* 51 29 * Implement execve(). The i386 code has a note that forking from kernel 52 30 * space results in no copy on write until the execve, so we should be
+3 -8
arch/tile/mm/homecache.c
··· 37 37 #include <asm/pgalloc.h> 38 38 #include <asm/homecache.h> 39 39 40 + #include <arch/sim.h> 41 + 40 42 #include "migrate.h" 41 43 42 44 ··· 219 217 return (length >= CHIP_L2_CACHE_SIZE()) ? HV_FLUSH_EVICT_L2 : length; 220 218 } 221 219 222 - /* On the simulator, confirm lines have been evicted everywhere. */ 223 - static void validate_lines_evicted(unsigned long pfn, size_t length) 224 - { 225 - sim_syscall(SIM_SYSCALL_VALIDATE_LINES_EVICTED, 226 - (HV_PhysAddr)pfn << PAGE_SHIFT, length); 227 - } 228 - 229 220 /* Flush a page out of whatever cache(s) it is in. */ 230 221 void homecache_flush_cache(struct page *page, int order) 231 222 { ··· 229 234 230 235 homecache_mask(page, pages, &home_mask); 231 236 flush_remote(pfn, length, &home_mask, 0, 0, 0, NULL, NULL, 0); 232 - validate_lines_evicted(pfn, pages * PAGE_SIZE); 237 + sim_validate_lines_evicted(PFN_PHYS(pfn), pages * PAGE_SIZE); 233 238 } 234 239 235 240