unsigned long cache_decay_ticks;
extern unsigned long cheetah_tune_scheduling(void);
-extern unsigned long timer_ticks_per_usec_quotient;
static void __init smp_tune_scheduling(void)
{
*((volatile unsigned long *)p);
/* Now the real measurement. */
- __asm__ __volatile__("
- b,pt %%xcc, 1f
- rd %%tick, %0
-
- .align 64
-1: ldx [%2 + 0x000], %%g1
- ldx [%2 + 0x040], %%g2
- ldx [%2 + 0x080], %%g3
- ldx [%2 + 0x0c0], %%g5
- add %2, 0x100, %2
- cmp %2, %4
- bne,pt %%xcc, 1b
- nop
-
- rd %%tick, %1"
- : "=&r" (tick1), "=&r" (tick2), "=&r" (flush_base)
- : "2" (flush_base), "r" (flush_base + ecache_size)
- : "g1", "g2", "g3", "g5");
+ if (!SPARC64_USE_STICK) {
+ __asm__ __volatile__("b,pt %%xcc, 1f\n\t"
+ " rd %%tick, %0\n\t"
+ ".align 64\n"
+ "1:\tldx [%2 + 0x000], %%g1\n\t"
+ "ldx [%2 + 0x040], %%g2\n\t"
+ "ldx [%2 + 0x080], %%g3\n\t"
+ "ldx [%2 + 0x0c0], %%g5\n\t"
+ "add %2, 0x100, %2\n\t"
+ "cmp %2, %4\n\t"
+ "bne,pt %%xcc, 1b\n\t"
+ " nop\n\t"
+ "rd %%tick, %1\n\t"
+ : "=&r" (tick1), "=&r" (tick2), "=&r" (flush_base)
+ : "2" (flush_base), "r" (flush_base + ecache_size)
+ : "g1", "g2", "g3", "g5");
+ } else {
+ __asm__ __volatile__("b,pt %%xcc, 1f\n\t"
+ " rd %%asr24, %0\n\t"
+ ".align 64\n"
+ "1:\tldx [%2 + 0x000], %%g1\n\t"
+ "ldx [%2 + 0x040], %%g2\n\t"
+ "ldx [%2 + 0x080], %%g3\n\t"
+ "ldx [%2 + 0x0c0], %%g5\n\t"
+ "add %2, 0x100, %2\n\t"
+ "cmp %2, %4\n\t"
+ "bne,pt %%xcc, 1b\n\t"
+ " nop\n\t"
+ "rd %%asr24, %1\n\t"
+ : "=&r" (tick1), "=&r" (tick2), "=&r" (flush_base)
+ : "2" (flush_base), "r" (flush_base + ecache_size)
+ : "g1", "g2", "g3", "g5");
+ }
__restore_flags(flags);
(ecache_size << 1));
}
report:
- /* Convert cpu ticks to jiffie ticks. */
- cache_decay_ticks = ((long)cacheflush_time * timer_ticks_per_usec_quotient);
- cache_decay_ticks >>= 32UL;
- cache_decay_ticks = (cache_decay_ticks * HZ) / 1000;
+ /* Convert ticks/sticks to jiffies. */
+ cache_decay_ticks = cacheflush_time / timer_tick_offset;
printk("Using heuristic of %ld cycles, %ld ticks.\n",
cacheflush_time, cache_decay_ticks);
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/mm.h>
+#include <linux/init.h>
#include <asm/delay.h>
#include <asm/system.h>
extern unsigned int cheetah_cee_trap_vector[], cheetah_cee_trap_vector_tl1[];
extern unsigned int cheetah_deferred_trap_vector[], cheetah_deferred_trap_vector_tl1[];
-void cheetah_ecache_flush_init(void)
+void __init cheetah_ecache_flush_init(void)
{
unsigned long largest_size, smallest_linesize, order;
char type[16];
}
#ifdef CONFIG_SMP
-unsigned long cheetah_tune_scheduling(void)
+unsigned long __init cheetah_tune_scheduling(void)
{
unsigned long tick1, tick2, raw;
+ unsigned long flush_base = ecache_flush_physbase;
+ unsigned long flush_linesize = ecache_flush_linesize;
+ unsigned long flush_size = ecache_flush_size;
+
+ /* Run through the whole cache to guarentee the timed loop
+ * is really displacing cache lines.
+ */
+ __asm__ __volatile__("1: subcc %0, %4, %0\n\t"
+ " bne,pt %%xcc, 1b\n\t"
+ " ldxa [%2 + %0] %3, %%g0\n\t"
+ : "=&r" (flush_size)
+ : "0" (flush_size), "r" (flush_base),
+ "i" (ASI_PHYS_USE_EC), "r" (flush_linesize));
+
+ /* The flush area is 2 X Ecache-size, so cut this in half for
+ * the timed loop.
+ */
+ flush_base = ecache_flush_physbase;
+ flush_linesize = ecache_flush_linesize;
+ flush_size = ecache_flush_size >> 1;
__asm__ __volatile__("rd %%tick, %0" : "=r" (tick1));
- cheetah_flush_ecache();
+
+ __asm__ __volatile__("1: subcc %0, %4, %0\n\t"
+ " bne,pt %%xcc, 1b\n\t"
+ " ldxa [%2 + %0] %3, %%g0\n\t"
+ : "=&r" (flush_size)
+ : "0" (flush_size), "r" (flush_base),
+ "i" (ASI_PHYS_USE_EC), "r" (flush_linesize));
+
__asm__ __volatile__("rd %%tick, %0" : "=r" (tick2));
raw = (tick2 - tick1);
/* "Recoverable" here means we try to yank the page from ever
* being newly used again. This depends upon a few things:
* 1) Must be main memory, and AFAR must be valid.
- * 2) If we trapped from use, OK.
+ * 2) If we trapped from user, OK.
* 3) Else, if we trapped from kernel we must find exception
* table entry (ie. we have to have been accessing user
* space).
extern void thread_info_offsets_are_bolixed_dave(void);
/* Only invoked on boot processor. */
-void trap_init(void)
+void __init trap_init(void)
{
/* Compile time sanity check. */
if (TI_TASK != offsetof(struct thread_info, task) ||