[OpenBIOS] [PATCHv2 11/11] SPARC64: switch entry.S over to use existing context macros
Mark Cave-Ayland
mark.cave-ayland at ilande.co.uk
Sun Aug 28 18:24:56 CEST 2016
This also requires aligning the CPU context struct as defined in cpustate.h.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
---
arch/sparc64/context.c | 6 +--
arch/sparc64/context.h | 7 +--
arch/sparc64/entry.S | 17 ++++++-
arch/sparc64/switch.S | 129 ++++++++++++++++++------------------------------
4 files changed, 70 insertions(+), 89 deletions(-)
diff --git a/arch/sparc64/context.c b/arch/sparc64/context.c
index 823116f..5ab0045 100644
--- a/arch/sparc64/context.c
+++ b/arch/sparc64/context.c
@@ -24,7 +24,6 @@ void __exit_context(void); /* assembly routine */
* to start us up.
*/
static struct context main_ctx = {
- .regs[REG_SP] = (uint64_t) &_estack - STACK_BIAS - 96,
.pc = (uint64_t) start_main,
.npc = (uint64_t) start_main + 4,
.return_addr = (uint64_t) __exit_context,
@@ -76,7 +75,8 @@ init_context(uint8_t *stack, uint64_t stack_size, int num_params)
ctx = (struct context *)
(stack_top - ALIGN_SIZE(sizeof(*ctx) + num_params*sizeof(uint64_t), sizeof(uint64_t)));
- memset(ctx, 0, sizeof(*ctx));
+ /* Use valid window state from startup */
+ memcpy(ctx, &main_ctx, sizeof(struct context));
/* Fill in reasonable default for flat memory model */
ctx->regs[REG_SP] = virt_to_phys(stack_top - STACK_BIAS - 192);
@@ -95,7 +95,7 @@ struct context *switch_to(struct context *ctx)
save = __context;
__context = ctx;
//asm ("pushl %cs; call __switch_context");
- asm ("call __switch_context_nosave; nop");
+ asm ("call __switch_context; nop");
ret = __context;
__context = (struct context *)save;
return ret;
diff --git a/arch/sparc64/context.h b/arch/sparc64/context.h
index 2756fa1..a047b9c 100644
--- a/arch/sparc64/context.h
+++ b/arch/sparc64/context.h
@@ -5,12 +5,13 @@
struct context {
/* General registers */
- uint64_t regs[32];
+ uint64_t regs[154];
uint64_t pc;
uint64_t npc;
-#define REG_O0 8
-#define REG_SP 14
+#define REG_O0 14
+#define REG_SP 20
#define SP_LOC(ctx) (&(ctx)->regs[REG_SP])
+ uint64_t tregs[20];
/* Flags */
/* Optional stack contents */
uint64_t return_addr;
diff --git a/arch/sparc64/entry.S b/arch/sparc64/entry.S
index d03128a..3a46d89 100644
--- a/arch/sparc64/entry.S
+++ b/arch/sparc64/entry.S
@@ -11,6 +11,7 @@
#include <asm/asi.h>
#include "pstate.h"
#include "lsu.h"
+#include "cpustate.h"
#define NO_QEMU_PROTOS
#define NO_OPENBIOS_PROTOS
#include "arch/common/fw_cfg.h"
@@ -264,6 +265,20 @@ lowmem:
/* Finally, turn on traps so that we can call c-code. */
wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate
+ /* Set up a default context */
+ setx __context, %g2, %g1
+ ldx [%g1], %g1
+
+ SAVE_CPU_GENERAL_STATE(entry)
+ SAVE_CPU_WINDOW_STATE(entry)
+
+ /* Set up local stack pointer */
+ setx _estack - 2047, %o2, %sp
+
+ /* And for the main context */
+ add %sp, - 192 - 0x500, %g2
+ stx %g2, [%g1 + 0xa0]
+
! 100 Hz timer
setx TICK_INT_DIS, %g2, %g1
rd %tick, %g2
@@ -276,7 +291,7 @@ lowmem:
* Main context is statically defined in C.
*/
- call __switch_context_nosave
+ call __switch_context
nop
/* We get here when the main context switches back to
diff --git a/arch/sparc64/switch.S b/arch/sparc64/switch.S
index d2cc7be..e6c63f0 100644
--- a/arch/sparc64/switch.S
+++ b/arch/sparc64/switch.S
@@ -1,5 +1,6 @@
#include "pstate.h"
#include <asm/asi.h>
+#include "cpustate.h"
#define ASI_BP ASI_M_BYPASS
#define REGWIN_SZ 0x40
@@ -22,47 +23,36 @@
* this routine to get back to the original context.
*/
-/* XXX: totally bogus for sparc, need to save and restore all windows */
__switch_context:
-
/* make sure caller's windows are on caller's stack */
flushw;
/* Save everything in current stack */
-
- setx __context, %g2, %g1
- stx %g3, [%g1 + 24]
- stx %g4, [%g1 + 32]
- stx %g5, [%g1 + 40]
- stx %g6, [%g1 + 48]
- stx %g7, [%g1 + 56]
-
- stx %o0, [%g1 + 64]
- stx %o1, [%g1 + 72]
- stx %o2, [%g1 + 80]
- stx %o3, [%g1 + 88]
- stx %o4, [%g1 + 96]
- stx %o5, [%g1 + 104]
- stx %o6, [%g1 + 112]
- stx %o7, [%g1 + 120]
-
- stx %l0, [%g1 + 128]
- stx %l1, [%g1 + 136]
- stx %l2, [%g1 + 144]
- stx %l3, [%g1 + 152]
- stx %l4, [%g1 + 160]
- stx %l5, [%g1 + 168]
- stx %l6, [%g1 + 176]
- stx %l7, [%g1 + 184]
-
- stx %i0, [%g1 + 192]
- stx %i1, [%g1 + 200]
- stx %i2, [%g1 + 208]
- stx %i3, [%g1 + 216]
- stx %i4, [%g1 + 224]
- stx %i5, [%g1 + 232]
- stx %i6, [%g1 + 240]
- stx %i7, [%g1 + 248]
+ stx %g1, [%sp + 2047 - 192 - 0x500 + 0x30]
+ stx %g2, [%sp + 2047 - 192 - 0x500 + 0x38]
+ stx %g3, [%sp + 2047 - 192 - 0x500 + 0x40]
+ stx %g4, [%sp + 2047 - 192 - 0x500 + 0x48]
+ stx %g5, [%sp + 2047 - 192 - 0x500 + 0x50]
+ stx %g6, [%sp + 2047 - 192 - 0x500 + 0x58]
+ stx %g7, [%sp + 2047 - 192 - 0x500 + 0x60]
+
+ mov %sp, %g1
+ add %g1, 2047 - 192 - 0x500, %g1
+
+ /* Return PC value */
+ mov %o7, %g2
+ add %g2, 0x8, %g2
+ stx %g2, [%g1 + 0x4d0]
+
+ SAVE_CPU_STATE(switch)
+
+ /* swap context */
+ setx __context, %g2, %g3
+ ldx [%g3], %g2
+ stx %g1, [%g3]
+ mov %g2, %g1
+
+ ba __set_context
__switch_context_nosave:
/* Interrupts are not allowed... */
@@ -72,53 +62,28 @@ __switch_context_nosave:
*/
setx __context, %g2, %g1
ldx [%g1], %g1
- ldx [%g1 + 16], %g2
- ldx [%g1 + 24], %g3
- ldx [%g1 + 32], %g4
- ldx [%g1 + 40], %g5
- ldx [%g1 + 48], %g6
- ldx [%g1 + 56], %g7
-
- ldx [%g1 + 64], %o0
- ldx [%g1 + 72], %o1
- ldx [%g1 + 80], %o2
- ldx [%g1 + 88], %o3
- ldx [%g1 + 96], %o4
- ldx [%g1 + 104], %o5
- ldx [%g1 + 112], %o6
- ldx [%g1 + 120], %o7
-
- ldx [%g1 + 128], %l0
- ldx [%g1 + 136], %l1
- ldx [%g1 + 144], %l2
- ldx [%g1 + 152], %l3
- ldx [%g1 + 160], %l4
- ldx [%g1 + 168], %l5
- ldx [%g1 + 176], %l6
- ldx [%g1 + 184], %l7
-
- ldx [%g1 + 192], %i0
- ldx [%g1 + 200], %i1
- ldx [%g1 + 208], %i2
- ldx [%g1 + 216], %i3
- ldx [%g1 + 224], %i4
- ldx [%g1 + 232], %i5
- ldx [%g1 + 240], %i6
- ldx [%g1 + 248], %i7
-
- ldx [%g1 + 256], %g1
- /* Finally, load new %pc */
- jmp %g1
- clr %g1
+
+__set_context:
+ RESTORE_CPU_STATE(switch)
+
+ /* Restore globals */
+ mov %g1, %g2
+ add %g2, 0x30, %g2
+ stx %g2, [%sp + 2047 - 192]
+
+ ldx [%g1 + 0x38], %g2
+ ldx [%g1 + 0x40], %g3
+ ldx [%g1 + 0x48], %g4
+ ldx [%g1 + 0x50], %g5
+ ldx [%g1 + 0x58], %g6
+ ldx [%g1 + 0x60], %g7
+
+ /* Finally, load new %pc */
+ ldx [%g1 + 0x4d0], %g1
+ jmpl %g1, %o7
+ ldx [%sp + 2047 - 192], %g1
__exit_context:
/* Get back to the original context */
- call __switch_context
- nop
-
- /* We get here if the other context attempt to switch to this
- * dead context. This should not happen. */
-
-halt:
- b halt
+ ba __switch_context
nop
--
1.7.10.4
More information about the OpenBIOS
mailing list