patch-2.3.49 linux/arch/sparc64/kernel/smp.c
Next file: linux/arch/sparc64/kernel/sys_sparc32.c
Previous file: linux/arch/sparc64/kernel/process.c
Back to the patch index
Back to the overall index
- Lines: 155
- Date:
Thu Mar 2 10:13:16 2000
- Orig file:
v2.3.48/linux/arch/sparc64/kernel/smp.c
- Orig date:
Wed Feb 16 17:03:51 2000
diff -u --recursive --new-file v2.3.48/linux/arch/sparc64/kernel/smp.c linux/arch/sparc64/kernel/smp.c
@@ -119,6 +119,7 @@
void __init smp_callin(void)
{
int cpuid = hard_smp_processor_id();
+ unsigned long pstate;
inherit_locked_prom_mappings(0);
@@ -127,18 +128,37 @@
cpu_probe();
- /* Master did this already, now is the time for us to do it. */
+ /* Guarentee that the following sequences execute
+ * uninterrupted.
+ */
+ __asm__ __volatile__("rdpr %%pstate, %0\n\t"
+ "wrpr %0, %1, %%pstate"
+ : "=r" (pstate)
+ : "i" (PSTATE_IE));
+
+ /* Set things up so user can access tick register for profiling
+ * purposes. Also workaround BB_ERRATA_1 by doing a dummy
+ * read back of %tick after writing it.
+ */
__asm__ __volatile__("
sethi %%hi(0x80000000), %%g1
- sllx %%g1, 32, %%g1
- rd %%tick, %%g2
+ ba,pt %%xcc, 1f
+ sllx %%g1, 32, %%g1
+ .align 64
+1: rd %%tick, %%g2
add %%g2, 6, %%g2
andn %%g2, %%g1, %%g2
wrpr %%g2, 0, %%tick
-" : /* no outputs */
+ rdpr %%tick, %%g0"
+ : /* no outputs */
: /* no inputs */
: "g1", "g2");
+ /* Restore PSTATE_IE. */
+ __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
+ : /* no outputs */
+ : "r" (pstate));
+
smp_setup_percpu_timer();
__sti();
@@ -598,7 +618,7 @@
void smp_percpu_timer_interrupt(struct pt_regs *regs)
{
- unsigned long compare, tick;
+ unsigned long compare, tick, pstate;
int cpu = smp_processor_id();
int user = user_mode(regs);
@@ -664,27 +684,87 @@
prof_counter(cpu) = prof_multiplier(cpu);
}
+ /* Guarentee that the following sequences execute
+ * uninterrupted.
+ */
+ __asm__ __volatile__("rdpr %%pstate, %0\n\t"
+ "wrpr %0, %1, %%pstate"
+ : "=r" (pstate)
+ : "i" (PSTATE_IE));
+
+ /* Workaround for Spitfire Errata (#54 I think??), I discovered
+ * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch
+ * number 103640.
+ *
+ * On Blackbird writes to %tick_cmpr can fail, the
+ * workaround seems to be to execute the wr instruction
+ * at the start of an I-cache line, and perform a dummy
+ * read back from %tick_cmpr right after writing to it. -DaveM
+ *
+ * Just to be anal we add a workaround for Spitfire
+ * Errata 50 by preventing pipeline bypasses on the
+ * final read of the %tick register into a compare
+ * instruction. The Errata 50 description states
+ * that %tick is not prone to this bug, but I am not
+ * taking any chances.
+ */
__asm__ __volatile__("rd %%tick_cmpr, %0\n\t"
- "add %0, %2, %0\n\t"
- "wr %0, 0x0, %%tick_cmpr\n\t"
- "rd %%tick, %1"
+ "ba,pt %%xcc, 1f\n\t"
+ " add %0, %2, %0\n\t"
+ ".align 64\n"
+ "1: wr %0, 0x0, %%tick_cmpr\n\t"
+ "rd %%tick_cmpr, %%g0\n\t"
+ "rd %%tick, %1\n\t"
+ "mov %1, %1"
: "=&r" (compare), "=r" (tick)
: "r" (current_tick_offset));
+
+ /* Restore PSTATE_IE. */
+ __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
+ : /* no outputs */
+ : "r" (pstate));
} while (tick >= compare);
}
static void __init smp_setup_percpu_timer(void)
{
int cpu = smp_processor_id();
+ unsigned long pstate;
prof_counter(cpu) = prof_multiplier(cpu) = 1;
- __asm__ __volatile__("rd %%tick, %%g1\n\t"
- "add %%g1, %0, %%g1\n\t"
- "wr %%g1, 0x0, %%tick_cmpr"
+ /* Guarentee that the following sequences execute
+ * uninterrupted.
+ */
+ __asm__ __volatile__("rdpr %%pstate, %0\n\t"
+ "wrpr %0, %1, %%pstate"
+ : "=r" (pstate)
+ : "i" (PSTATE_IE));
+
+ /* Workaround for Spitfire Errata (#54 I think??), I discovered
+ * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch
+ * number 103640.
+ *
+ * On Blackbird writes to %tick_cmpr can fail, the
+ * workaround seems to be to execute the wr instruction
+ * at the start of an I-cache line, and perform a dummy
+ * read back from %tick_cmpr right after writing to it. -DaveM
+ */
+ __asm__ __volatile__("
+ rd %%tick, %%g1
+ ba,pt %%xcc, 1f
+ add %%g1, %0, %%g1
+ .align 64
+ 1: wr %%g1, 0x0, %%tick_cmpr
+ rd %%tick_cmpr, %%g0"
+ : /* no outputs */
+ : "r" (current_tick_offset)
+ : "g1");
+
+ /* Restore PSTATE_IE. */
+ __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
: /* no outputs */
- : "r" (current_tick_offset)
- : "g1");
+ : "r" (pstate));
}
void __init smp_tick_init(void)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)