Commit 936f482a authored by David S. Miller's avatar David S. Miller

[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: default avatarDavid S. Miller <davem@davemloft.net>
parent 6e02493a
...@@ -102,7 +102,14 @@ etrap_save: save %g2, -STACK_BIAS, %sp ...@@ -102,7 +102,14 @@ etrap_save: save %g2, -STACK_BIAS, %sp
2: mov %g4, %l4 2: mov %g4, %l4
mov %g5, %l5 mov %g5, %l5
add %g7, 4, %l2 add %g7, 4, %l2
wrpr %g0, ETRAP_PSTATE1, %pstate
/* Go to trap time globals so we can save them. */
661: wrpr %g0, ETRAP_PSTATE1, %pstate
.section .gl_1insn_patch, "ax"
.word 661b
SET_GL(0)
.previous
stx %g1, [%sp + PTREGS_OFF + PT_V9_G1] stx %g1, [%sp + PTREGS_OFF + PT_V9_G1]
stx %g2, [%sp + PTREGS_OFF + PT_V9_G2] stx %g2, [%sp + PTREGS_OFF + PT_V9_G2]
sllx %l7, 24, %l7 sllx %l7, 24, %l7
...@@ -195,9 +202,15 @@ etraptl1: /* Save tstate/tpc/tnpc of TL 1-->4 and the tl register itself. ...@@ -195,9 +202,15 @@ etraptl1: /* Save tstate/tpc/tnpc of TL 1-->4 and the tl register itself.
rdpr %tt, %g3 rdpr %tt, %g3
stx %g3, [%g2 + STACK_BIAS + 0x78] stx %g3, [%g2 + STACK_BIAS + 0x78]
wrpr %g1, %tl
stx %g1, [%g2 + STACK_BIAS + 0x80] stx %g1, [%g2 + STACK_BIAS + 0x80]
wrpr %g0, 1, %tl
661: nop
.section .gl_1insn_patch, "ax"
.word 661b
SET_GL(1)
.previous
rdpr %tstate, %g1 rdpr %tstate, %g1
sub %g2, STACKFRAME_SZ + TRACEREG_SZ - STACK_BIAS, %g2 sub %g2, STACKFRAME_SZ + TRACEREG_SZ - STACK_BIAS, %g2
ba,pt %xcc, 1b ba,pt %xcc, 1b
......
...@@ -230,7 +230,14 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 ...@@ -230,7 +230,14 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
1: 1:
ldx [%sp + PTREGS_OFF + PT_V9_G6], %g6 ldx [%sp + PTREGS_OFF + PT_V9_G6], %g6
ldx [%sp + PTREGS_OFF + PT_V9_G7], %g7 ldx [%sp + PTREGS_OFF + PT_V9_G7], %g7
wrpr %g0, RTRAP_PSTATE_AG_IRQOFF, %pstate
/* Normal globals are restored, go to trap globals. */
661: wrpr %g0, RTRAP_PSTATE_AG_IRQOFF, %pstate
.section .gl_1insn_patch, "ax"
.word 661b
SET_GL(1)
.previous
ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0 ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0
ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1 ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1
...@@ -304,6 +311,13 @@ user_rtt_fill_fixup: ...@@ -304,6 +311,13 @@ user_rtt_fill_fixup:
mov %g6, %l1 mov %g6, %l1
wrpr %g0, 0x0, %tl wrpr %g0, 0x0, %tl
wrpr %g0, RTRAP_PSTATE, %pstate wrpr %g0, RTRAP_PSTATE, %pstate
661: nop
.section .gl_1insn_patch, "ax"
.word 661b
SET_GL(0)
.previous
mov %l1, %g6 mov %l1, %g6
ldx [%g6 + TI_TASK], %g4 ldx [%g6 + TI_TASK], %g4
LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3) LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
......
...@@ -545,6 +545,24 @@ static void __init per_cpu_patch(void) ...@@ -545,6 +545,24 @@ static void __init per_cpu_patch(void)
#endif #endif
} }
static void __init gl_patch(void)
{
struct gl_1insn_patch_entry *p;
if (tlb_type != hypervisor)
return;
p = &__gl_1insn_patch;
while (p < &__gl_1insn_patch_end) {
unsigned long addr = p->addr;
*(unsigned int *) (addr + 0) = p->insn;
__asm__ __volatile__("flush %0" : : "r" (addr + 0));
p++;
}
}
void __init setup_arch(char **cmdline_p) void __init setup_arch(char **cmdline_p)
{ {
/* Initialize PROM console and command line. */ /* Initialize PROM console and command line. */
...@@ -567,6 +585,8 @@ void __init setup_arch(char **cmdline_p) ...@@ -567,6 +585,8 @@ void __init setup_arch(char **cmdline_p)
*/ */
per_cpu_patch(); per_cpu_patch();
gl_patch();
boot_flags_init(*cmdline_p); boot_flags_init(*cmdline_p);
idprom_init(); idprom_init();
......
...@@ -77,6 +77,9 @@ SECTIONS ...@@ -77,6 +77,9 @@ SECTIONS
__cpuid_patch = .; __cpuid_patch = .;
.cpuid_patch : { *(.cpuid_patch) } .cpuid_patch : { *(.cpuid_patch) }
__cpuid_patch_end = .; __cpuid_patch_end = .;
__gl_1insn_patch = .;
.gl_1insn_patch : { *(.gl_1insn_patch) }
__gl_1insn_patch_end = .;
. = ALIGN(8192); . = ALIGN(8192);
__initramfs_start = .; __initramfs_start = .;
.init.ramfs : { *(.init.ramfs) } .init.ramfs : { *(.init.ramfs) }
......
...@@ -73,6 +73,11 @@ struct cpuid_patch_entry { ...@@ -73,6 +73,11 @@ struct cpuid_patch_entry {
extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end; extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end;
#endif #endif
struct gl_1insn_patch_entry {
unsigned int addr;
unsigned int insn;
};
extern struct gl_1insn_patch_entry __gl_1insn_patch, __gl_1insn_patch_end;
#endif /* !(__ASSEMBLY__) */ #endif /* !(__ASSEMBLY__) */
#define TRAP_PER_CPU_THREAD 0x00 #define TRAP_PER_CPU_THREAD 0x00
......
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
#include <asm/pstate.h> #include <asm/pstate.h>
/* wrpr %g0, val, %gl */
#define SET_GL(val) \
.word 0xa1902000 | val
#define KERNBASE 0x400000 #define KERNBASE 0x400000
#define PTREGS_OFF (STACK_BIAS + STACKFRAME_SZ) #define PTREGS_OFF (STACK_BIAS + STACKFRAME_SZ)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment