aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2010-10-14 16:00:11 -0400
committerChris Metcalf <cmetcalf@tilera.com>2010-10-15 15:36:54 -0400
commitbf65e440e8248f22b2eacf8d47961bb9d52260f7 (patch)
tree49189dfa1bc90732caedc1e872baed9fb360adf0
parent4fe938c5134fce1f25e1261eef6252fb47634962 (diff)
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>
-rw-r--r--arch/tile/include/arch/sim.h619
-rw-r--r--arch/tile/include/asm/system.h7
-rw-r--r--arch/tile/kernel/entry.S22
-rw-r--r--arch/tile/mm/homecache.c11
4 files changed, 622 insertions, 37 deletions
diff --git a/arch/tile/include/arch/sim.h b/arch/tile/include/arch/sim.h
new file mode 100644
index 00000000000..74b7c1624d3
--- /dev/null
+++ b/arch/tile/include/arch/sim.h
@@ -0,0 +1,619 @@
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; a newline is automatically added.
156 */
157static __inline void
158sim_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 */
182static __inline void
183sim_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 */
206static __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
214static __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
222static __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
236static __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
247static __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
259static __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
293static __inline int
294sim_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
305static __inline int
306sim_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 */
320struct 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
340static __inline struct SimQueryWatchpointStatus
341sim_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. */
356static __inline void
357sim_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 */
403static __inline int
404sim_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. */
419static __inline void
420sim_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. */
428static __inline void
429sim_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 */
465static __inline void
466sim_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. */
473static __inline void
474sim_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 */
489static __inline void
490sim_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 */
505static __inline int
506sim_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 */
518static __inline void
519sim_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 */
540static __inline void
541sim_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 */
562static __inline void
563sim_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 */
584static __inline void
585sim_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
597static __inline void
598sim_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
605static __inline void
606sim_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/** @} */
diff --git a/arch/tile/include/asm/system.h b/arch/tile/include/asm/system.h
index 96779c80590..fb7ff9574d7 100644
--- a/arch/tile/include/asm/system.h
+++ b/arch/tile/include/asm/system.h
@@ -217,13 +217,6 @@ int hardwall_deactivate(struct task_struct *task);
217} while (0) 217} while (0)
218#endif 218#endif
219 219
220/* Invoke the simulator "syscall" mechanism (see arch/tile/kernel/entry.S). */
221extern 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 * Kernel threads can check to see if they need to migrate their 221 * Kernel threads can check to see if they need to migrate their
229 * stack whenever they return from a context switch; for user 222 * stack whenever they return from a context switch; for user
diff --git a/arch/tile/kernel/entry.S b/arch/tile/kernel/entry.S
index 3d01383b1b0..80d13f013bb 100644
--- a/arch/tile/kernel/entry.S
+++ b/arch/tile/kernel/entry.S
@@ -25,28 +25,6 @@ STD_ENTRY(current_text_addr)
25 { move r0, lr; jrp lr } 25 { move r0, lr; jrp lr }
26 STD_ENDPROC(current_text_addr) 26 STD_ENDPROC(current_text_addr)
27 27
28STD_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 * Implement execve(). The i386 code has a note that forking from kernel 29 * Implement execve(). The i386 code has a note that forking from kernel
52 * space results in no copy on write until the execve, so we should be 30 * space results in no copy on write until the execve, so we should be
diff --git a/arch/tile/mm/homecache.c b/arch/tile/mm/homecache.c
index fb3b4a55cec..d78df3a6ee1 100644
--- a/arch/tile/mm/homecache.c
+++ b/arch/tile/mm/homecache.c
@@ -37,6 +37,8 @@
37#include <asm/pgalloc.h> 37#include <asm/pgalloc.h>
38#include <asm/homecache.h> 38#include <asm/homecache.h>
39 39
40#include <arch/sim.h>
41
40#include "migrate.h" 42#include "migrate.h"
41 43
42 44
@@ -217,13 +219,6 @@ static unsigned long cache_flush_length(unsigned long length)
217 return (length >= CHIP_L2_CACHE_SIZE()) ? HV_FLUSH_EVICT_L2 : length; 219 return (length >= CHIP_L2_CACHE_SIZE()) ? HV_FLUSH_EVICT_L2 : length;
218} 220}
219 221
220/* On the simulator, confirm lines have been evicted everywhere. */
221static void validate_lines_evicted(unsigned long pfn, size_t length)
222{
223 sim_syscall(SIM_SYSCALL_VALIDATE_LINES_EVICTED,
224 (HV_PhysAddr)pfn << PAGE_SHIFT, length);
225}
226
227/* Flush a page out of whatever cache(s) it is in. */ 222/* Flush a page out of whatever cache(s) it is in. */
228void homecache_flush_cache(struct page *page, int order) 223void homecache_flush_cache(struct page *page, int order)
229{ 224{
@@ -234,7 +229,7 @@ void homecache_flush_cache(struct page *page, int order)
234 229
235 homecache_mask(page, pages, &home_mask); 230 homecache_mask(page, pages, &home_mask);
236 flush_remote(pfn, length, &home_mask, 0, 0, 0, NULL, NULL, 0); 231 flush_remote(pfn, length, &home_mask, 0, 0, 0, NULL, NULL, 0);
237 validate_lines_evicted(pfn, pages * PAGE_SIZE); 232 sim_validate_lines_evicted(PFN_PHYS(pfn), pages * PAGE_SIZE);
238} 233}
239 234
240 235