[OpenBIOS] [commit] r827 - trunk/openbios-devel/arch/sparc32

repository service svn at openbios.org
Sun Aug 1 16:37:05 CEST 2010


Author: blueswirl
Date: Sun Aug  1 16:37:04 2010
New Revision: 827
URL: http://tracker.coreboot.org/trac/openbios/changeset/827

Log:
sparc32: fix context switching

Remove old hack to jump to loaded code and use switch_to().

Use FLUSH_ALL_KERNEL_WINDOWS macro from Linux.

Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

Modified:
   trunk/openbios-devel/arch/sparc32/boot.c
   trunk/openbios-devel/arch/sparc32/context.c
   trunk/openbios-devel/arch/sparc32/switch.S

Modified: trunk/openbios-devel/arch/sparc32/boot.c
==============================================================================
--- trunk/openbios-devel/arch/sparc32/boot.c	Sun Aug  1 13:03:45 2010	(r826)
+++ trunk/openbios-devel/arch/sparc32/boot.c	Sun Aug  1 16:37:04 2010	(r827)
@@ -15,6 +15,7 @@
 #include "libopenbios/forth_load.h"
 #include "openprom.h"
 #include "boot.h"
+#include "context.h"
 
 uint32_t kernel_image;
 uint32_t kernel_size;
@@ -22,8 +23,6 @@
 uint32_t cmdline_size;
 char boot_device;
 static const void *romvec;
-static int (*entry)(const void *romvec_ptr, int p2, int p3, int p4, int p5);
-
 
 static int try_path(const char *path, char *param)
 {
@@ -107,22 +106,22 @@
 	switch (type) {
 		case 0x0:
 			/* Start ELF boot image */
-			entry = (void *) address;
-			image_retval = entry(romvec, 0, 0, 0, 0);
+			image_retval = start_elf((unsigned long)address,
+                                                 (unsigned long)romvec);
 
 			break;
 
 		case 0x1:
 			/* Start ELF image */
-			entry = (void *) address;
-			image_retval = entry(romvec, 0, 0, 0, 0);
+			image_retval = start_elf((unsigned long)address,
+                                                 (unsigned long)romvec);
 
 			break;
 
 		case 0x5:
 			/* Start a.out image */
-			entry = (void *) address;
-			image_retval = entry(romvec, 0, 0, 0, 0);
+			image_retval = start_elf((unsigned long)address,
+                                                 (unsigned long)romvec);
 
 			break;
 
@@ -211,8 +210,7 @@
 
         if (kernel_size) {
             printk("[sparc] Kernel already loaded\n");
-            entry = (void *) kernel_image;
-            entry(romvec, 0, 0, 0, 0);
+            start_elf(kernel_image, (unsigned long)romvec);
         }
 
 	printk("[sparc] Booting file '%s' ", path);

Modified: trunk/openbios-devel/arch/sparc32/context.c
==============================================================================
--- trunk/openbios-devel/arch/sparc32/context.c	Sun Aug  1 13:03:45 2010	(r826)
+++ trunk/openbios-devel/arch/sparc32/context.c	Sun Aug  1 16:37:04 2010	(r827)
@@ -83,14 +83,24 @@
 /* Switch to another context. */
 struct context *switch_to(struct context *ctx)
 {
-    struct context *save, *ret;
+    volatile struct context *save;
+    struct context *ret;
 
     debug("switching to new context:\n");
     save = __context;
     __context = ctx;
-    //asm ("pushl %cs; call __switch_context");
+    asm __volatile__ ("\n\tcall __switch_context"
+                      "\n\tnop" ::: "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+                      "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
+                      "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+                      "i0", "i1", "i2", "i3", "i4", "i5", "i7",
+                      "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9",
+                      "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19",
+                      "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29",
+                      "f30", "f31",
+                      "memory");
     ret = __context;
-    __context = save;
+    __context = (struct context *)save;
     return ret;
 }
 
@@ -102,10 +112,7 @@
     ctx = init_context(image_stack, sizeof image_stack, 1);
     ctx->pc = entry_point;
     ctx->param[0] = param;
-    //ctx->eax = 0xe1fb007;
-    //ctx->ebx = param;
 
     ctx = switch_to(ctx);
-    //return ctx->eax;
-    return 0;
+    return ctx->regs[REG_O0];
 }

Modified: trunk/openbios-devel/arch/sparc32/switch.S
==============================================================================
--- trunk/openbios-devel/arch/sparc32/switch.S	Sun Aug  1 13:03:45 2010	(r826)
+++ trunk/openbios-devel/arch/sparc32/switch.S	Sun Aug  1 16:37:04 2010	(r827)
@@ -8,6 +8,16 @@
 	.text
 	.align	4
 
+#define STACKFRAME_SZ     0x60
+
+/* These are just handy. */
+#define _SV	save	%sp, -STACKFRAME_SZ, %sp
+#define _RS     restore
+
+#define FLUSH_ALL_KERNEL_WINDOWS \
+	_SV; _SV; _SV; _SV; _SV; _SV; _SV; \
+	_RS; _RS; _RS; _RS; _RS; _RS; _RS;
+
 /*
  * Switch execution context
  * This saves registers in the stack, then
@@ -18,45 +28,48 @@
  * this routine to get back to the original context.
  */
 
-/* XXX: totally bogus for sparc, need to save and restore all windows */
 __switch_context:
-	/* Save everything in current stack */
-	set	__context, %g1
-        st      %g2, [%g1 + 8]
-        st      %g3, [%g1 + 12]
-        st      %g4, [%g1 + 16]
-        st      %g5, [%g1 + 20]
-        st      %g6, [%g1 + 24]
-        st      %g7, [%g1 + 28]
-
-        st      %o0, [%g1 + 32]
-        st      %o1, [%g1 + 36]
-        st      %o2, [%g1 + 40]
-        st      %o3, [%g1 + 44]
-        st      %o4, [%g1 + 48]
-        st      %o5, [%g1 + 52]
-        st      %o6, [%g1 + 56]
-        st      %o7, [%g1 + 60]
-
-        st      %l0, [%g1 + 64]
-        st      %l1, [%g1 + 68]
-        st      %l2, [%g1 + 72]
-        st      %l3, [%g1 + 76]
-        st      %l4, [%g1 + 80]
-        st      %l5, [%g1 + 84]
-        st      %l6, [%g1 + 88]
-        st      %l7, [%g1 + 92]
-
-        st      %i0, [%g1 + 96]
-        st      %i1, [%g1 + 100]
-        st      %i2, [%g1 + 104]
-        st      %i3, [%g1 + 108]
-        st      %i4, [%g1 + 112]
-        st      %i5, [%g1 + 116]
-        st      %i6, [%g1 + 120]
-        st      %i7, [%g1 + 124]
+        FLUSH_ALL_KERNEL_WINDOWS
+	/* Save everything in stack */
+        st      %fp, [%fp + 120 -144]
+        add     %fp, -144, %fp
+        st      %g1, [%fp + 4]
+        st      %g2, [%fp + 8]
+        st      %g3, [%fp + 12]
+        st      %g4, [%fp + 16]
+        st      %g5, [%fp + 20]
+        st      %g6, [%fp + 24]
+        st      %g7, [%fp + 28]
+
+        st      %o0, [%fp + 32]
+        st      %o1, [%fp + 36]
+        st      %o2, [%fp + 40]
+        st      %o3, [%fp + 44]
+        st      %o4, [%fp + 48]
+        st      %o5, [%fp + 52]
+        st      %sp, [%fp + 56]
+        st      %o7, [%fp + 60]
+
+        st      %l0, [%fp + 64]
+        st      %l1, [%fp + 68]
+        st      %l2, [%fp + 72]
+        st      %l3, [%fp + 76]
+        st      %l4, [%fp + 80]
+        st      %l5, [%fp + 84]
+        st      %l6, [%fp + 88]
+        st      %l7, [%fp + 92]
+
+        st      %i0, [%fp + 96]
+        st      %i1, [%fp + 100]
+        st      %i2, [%fp + 104]
+        st      %i3, [%fp + 108]
+        st      %i4, [%fp + 112]
+        st      %i5, [%fp + 116]
+        st      %i7, [%fp + 124]
+
+        /* ctx->return_address:  Return to caller */
+        st      %o7, [%fp + 128]
 
-__switch_context_nosave:
 	/* Interrupts are not allowed... */
 
 	/* Turn on Supervisor, EnableFloating, and all the PIL bits.
@@ -67,49 +80,62 @@
 	wr	%g2, 0x0, %psr
 #endif
 
-	/* Load all registers
-	 */
+__switch_context_nosave:
 	set	__context, %g1
-        ld      [%g1], %g1
-        ld      [%g1 + 8], %g2
-        ld      [%g1 + 12], %g3
-        ld      [%g1 + 16], %g4
-        ld      [%g1 + 20], %g5
-        ld      [%g1 + 24], %g6
-        ld      [%g1 + 28], %g7
-
-        ld      [%g1 + 32], %o0
-        ld      [%g1 + 36], %o1
-        ld      [%g1 + 40], %o2
-        ld      [%g1 + 44], %o3
-        ld      [%g1 + 48], %o4
-        ld      [%g1 + 52], %o5
-        ld      [%g1 + 56], %o6
-        ld      [%g1 + 60], %o7
-
-        ld      [%g1 + 64], %l0
-        ld      [%g1 + 68], %l1
-        ld      [%g1 + 72], %l2
-        ld      [%g1 + 76], %l3
-        ld      [%g1 + 80], %l4
-        ld      [%g1 + 84], %l5
-        ld      [%g1 + 88], %l6
-        ld      [%g1 + 92], %l7
-
-        ld      [%g1 + 96], %i0
-        ld      [%g1 + 100], %i1
-        ld      [%g1 + 104], %i2
-        ld      [%g1 + 108], %i3
-        ld      [%g1 + 112], %i4
-        ld      [%g1 + 116], %i5
-        ld      [%g1 + 120], %i6
-        ld      [%g1 + 124], %i7
-
-        ld      [%g1 + 128], %g1
-       	/* Finally, load new %pc */
+        /* Swap ctx pointer with %fp */
+        swap      [%g1], %fp
+	/* Load all registers */
+        /* offset 0: %g0, no need to load */
+        ld      [%fp + 4], %g1
+        ld      [%fp + 8], %g2
+        ld      [%fp + 12], %g3
+        ld      [%fp + 16], %g4
+        ld      [%fp + 20], %g5
+        ld      [%fp + 24], %g6
+        ld      [%fp + 28], %g7
+
+        /* offset 32: %o0, loaded from ctx->param */
+        ld      [%fp + 36], %o1
+        ld      [%fp + 40], %o2
+        ld      [%fp + 44], %o3
+        ld      [%fp + 48], %o4
+        ld      [%fp + 52], %o5
+        ld      [%fp + 56], %sp
+        /* offset 60: %o7, loaded from ctx->return_addr */
+
+        ld      [%fp + 64], %l0
+        ld      [%fp + 68], %l1
+        ld      [%fp + 72], %l2
+        ld      [%fp + 76], %l3
+        ld      [%fp + 80], %l4
+        ld      [%fp + 84], %l5
+        ld      [%fp + 88], %l6
+        ld      [%fp + 92], %l7
+
+        ld      [%fp + 96], %i0
+        ld      [%fp + 100], %i1
+        ld      [%fp + 104], %i2
+        ld      [%fp + 108], %i3
+        ld      [%fp + 112], %i4
+        ld      [%fp + 116], %i5
+        ld      [%fp + 124], %i7
+
+        /* ctx->return_addr */
+        ld      [%fp + 136], %o7
+
+        /* ctx->param */
+        ld      [%fp + 140], %o0
+
+        /* ctx->pc, save %g1 to %y and load to %g1 */
+        mov     %g1, %y
+        ld      [%fp + 128], %g1
+        /* %fp last */
+        ld      [%fp + 120], %fp
+        /* Finally, get the new %pc from %g1 and restore %g1*/
         jmp     %g1
-         clr    %g1
+         mov    %y, %g1
 
+        FLUSH_ALL_KERNEL_WINDOWS
 __exit_context:
 	/* Get back to the original context */
 	call	__switch_context



More information about the OpenBIOS mailing list