diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-02-06 00:29:28 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 04:11:48 -0500 |
commit | 936f482af1743141d637483ec10eb881537c26dc (patch) | |
tree | 913da89a4d9f4038c510c9ecf2f5957b0f6d167f /arch/sparc64/kernel | |
parent | 6e02493a7f33ac89e698b980a657d77ab2749eaf (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/kernel')
-rw-r--r-- | arch/sparc64/kernel/etrap.S | 17 | ||||
-rw-r--r-- | arch/sparc64/kernel/rtrap.S | 16 | ||||
-rw-r--r-- | arch/sparc64/kernel/setup.c | 20 | ||||
-rw-r--r-- | arch/sparc64/kernel/vmlinux.lds.S | 3 |
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 | |||
102 | 2: mov %g4, %l4 | 102 | 2: 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. */ | ||
107 | 661: 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 | ||
208 | 661: 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 | |||
230 | 1: | 230 | 1: |
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. */ | ||
235 | 661: 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 | |||
315 | 661: 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 | ||
548 | static 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 | |||
548 | void __init setup_arch(char **cmdline_p) | 566 | void __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) } |