[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