aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-06 00:29:28 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:11:48 -0500
commit936f482af1743141d637483ec10eb881537c26dc (patch)
tree913da89a4d9f4038c510c9ecf2f5957b0f6d167f /arch/sparc64
parent6e02493a7f33ac89e698b980a657d77ab2749eaf (diff)
[SPARC64]: Add initial code to twiddle %gl on trap entry/exit.
Instead of setting/clearing PSTATE_AG we have to change the %gl register value on sun4v. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/kernel/etrap.S17
-rw-r--r--arch/sparc64/kernel/rtrap.S16
-rw-r--r--arch/sparc64/kernel/setup.c20
-rw-r--r--arch/sparc64/kernel/vmlinux.lds.S3
4 files changed, 53 insertions, 3 deletions
diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S
index f2556146a735..4d644949ad49 100644
--- a/arch/sparc64/kernel/etrap.S
+++ b/arch/sparc64/kernel/etrap.S
@@ -102,7 +102,14 @@ etrap_save: save %g2, -STACK_BIAS, %sp
1022: mov %g4, %l4 1022: mov %g4, %l4
103 mov %g5, %l5 103 mov %g5, %l5
104 add %g7, 4, %l2 104 add %g7, 4, %l2
105 wrpr %g0, ETRAP_PSTATE1, %pstate 105
106 /* Go to trap time globals so we can save them. */
107661: wrpr %g0, ETRAP_PSTATE1, %pstate
108 .section .gl_1insn_patch, "ax"
109 .word 661b
110 SET_GL(0)
111 .previous
112
106 stx %g1, [%sp + PTREGS_OFF + PT_V9_G1] 113 stx %g1, [%sp + PTREGS_OFF + PT_V9_G1]
107 stx %g2, [%sp + PTREGS_OFF + PT_V9_G2] 114 stx %g2, [%sp + PTREGS_OFF + PT_V9_G2]
108 sllx %l7, 24, %l7 115 sllx %l7, 24, %l7
@@ -195,9 +202,15 @@ etraptl1: /* Save tstate/tpc/tnpc of TL 1-->4 and the tl register itself.
195 rdpr %tt, %g3 202 rdpr %tt, %g3
196 stx %g3, [%g2 + STACK_BIAS + 0x78] 203 stx %g3, [%g2 + STACK_BIAS + 0x78]
197 204
198 wrpr %g1, %tl
199 stx %g1, [%g2 + STACK_BIAS + 0x80] 205 stx %g1, [%g2 + STACK_BIAS + 0x80]
200 206
207 wrpr %g0, 1, %tl
208661: nop
209 .section .gl_1insn_patch, "ax"
210 .word 661b
211 SET_GL(1)
212 .previous
213
201 rdpr %tstate, %g1 214 rdpr %tstate, %g1
202 sub %g2, STACKFRAME_SZ + TRACEREG_SZ - STACK_BIAS, %g2 215 sub %g2, STACKFRAME_SZ + TRACEREG_SZ - STACK_BIAS, %g2
203 ba,pt %xcc, 1b 216 ba,pt %xcc, 1b
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index ecfbbdc56125..e6130956307f 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -230,7 +230,14 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
2301: 2301:
231 ldx [%sp + PTREGS_OFF + PT_V9_G6], %g6 231 ldx [%sp + PTREGS_OFF + PT_V9_G6], %g6
232 ldx [%sp + PTREGS_OFF + PT_V9_G7], %g7 232 ldx [%sp + PTREGS_OFF + PT_V9_G7], %g7
233 wrpr %g0, RTRAP_PSTATE_AG_IRQOFF, %pstate 233
234 /* Normal globals are restored, go to trap globals. */
235661: wrpr %g0, RTRAP_PSTATE_AG_IRQOFF, %pstate
236 .section .gl_1insn_patch, "ax"
237 .word 661b
238 SET_GL(1)
239 .previous
240
234 ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0 241 ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0
235 ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1 242 ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1
236 243
@@ -304,6 +311,13 @@ user_rtt_fill_fixup:
304 mov %g6, %l1 311 mov %g6, %l1
305 wrpr %g0, 0x0, %tl 312 wrpr %g0, 0x0, %tl
306 wrpr %g0, RTRAP_PSTATE, %pstate 313 wrpr %g0, RTRAP_PSTATE, %pstate
314
315661: nop
316 .section .gl_1insn_patch, "ax"
317 .word 661b
318 SET_GL(0)
319 .previous
320
307 mov %l1, %g6 321 mov %l1, %g6
308 ldx [%g6 + TI_TASK], %g4 322 ldx [%g6 + TI_TASK], %g4
309 LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3) 323 LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 2918ed3eb1ba..aaab319ad885 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -545,6 +545,24 @@ static void __init per_cpu_patch(void)
545#endif 545#endif
546} 546}
547 547
548static void __init gl_patch(void)
549{
550 struct gl_1insn_patch_entry *p;
551
552 if (tlb_type != hypervisor)
553 return;
554
555 p = &__gl_1insn_patch;
556 while (p < &__gl_1insn_patch_end) {
557 unsigned long addr = p->addr;
558
559 *(unsigned int *) (addr + 0) = p->insn;
560 __asm__ __volatile__("flush %0" : : "r" (addr + 0));
561
562 p++;
563 }
564}
565
548void __init setup_arch(char **cmdline_p) 566void __init setup_arch(char **cmdline_p)
549{ 567{
550 /* Initialize PROM console and command line. */ 568 /* Initialize PROM console and command line. */
@@ -567,6 +585,8 @@ void __init setup_arch(char **cmdline_p)
567 */ 585 */
568 per_cpu_patch(); 586 per_cpu_patch();
569 587
588 gl_patch();
589
570 boot_flags_init(*cmdline_p); 590 boot_flags_init(*cmdline_p);
571 591
572 idprom_init(); 592 idprom_init();
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S
index 1639d9c935c3..482d1ed87f4d 100644
--- a/arch/sparc64/kernel/vmlinux.lds.S
+++ b/arch/sparc64/kernel/vmlinux.lds.S
@@ -77,6 +77,9 @@ SECTIONS
77 __cpuid_patch = .; 77 __cpuid_patch = .;
78 .cpuid_patch : { *(.cpuid_patch) } 78 .cpuid_patch : { *(.cpuid_patch) }
79 __cpuid_patch_end = .; 79 __cpuid_patch_end = .;
80 __gl_1insn_patch = .;
81 .gl_1insn_patch : { *(.gl_1insn_patch) }
82 __gl_1insn_patch_end = .;
80 . = ALIGN(8192); 83 . = ALIGN(8192);
81 __initramfs_start = .; 84 __initramfs_start = .;
82 .init.ramfs : { *(.init.ramfs) } 85 .init.ramfs : { *(.init.ramfs) }