[OpenBIOS] r508 - trunk/openbios-devel/arch/sparc64

svn at openbios.org svn at openbios.org
Sat Jul 11 14:25:26 CEST 2009


Author: blueswirl
Date: 2009-07-11 14:25:26 +0200 (Sat, 11 Jul 2009)
New Revision: 508

Modified:
   trunk/openbios-devel/arch/sparc64/aoutload.c
   trunk/openbios-devel/arch/sparc64/boot.c
   trunk/openbios-devel/arch/sparc64/boot.h
   trunk/openbios-devel/arch/sparc64/build.xml
   trunk/openbios-devel/arch/sparc64/context.c
   trunk/openbios-devel/arch/sparc64/context.h
   trunk/openbios-devel/arch/sparc64/switch.S
Log:
sparc64: fix registers dealing with client (Igor Kovalenko)

Signed-off-by: igor.v.kovalenko at gmail.com


Modified: trunk/openbios-devel/arch/sparc64/aoutload.c
===================================================================
--- trunk/openbios-devel/arch/sparc64/aoutload.c	2009-07-11 12:23:24 UTC (rev 507)
+++ trunk/openbios-devel/arch/sparc64/aoutload.c	2009-07-11 12:25:26 UTC (rev 508)
@@ -125,19 +125,10 @@
     debug("entry point is %#lx\n", start);
     printf("Jumping to entry point...\n");
 
-#if 1
     {
-        int (*entry)(unsigned long p1, unsigned long p2, unsigned long p3,
-                      unsigned long p4, unsigned long p5);
-        extern int of_client_interface( int *params );
-
-        entry = (void *) addr_fixup(start);
-
-        __asm__ __volatile__("clr %i3\n");
-
-        image_retval = entry(0, 0, 0, 0, (unsigned long)&of_client_interface);
+    	extern int sparc64_of_client_interface( int *params );
+    	image_retval = start_client_image(addr_fixup(start), (uint64_t)&sparc64_of_client_interface);
     }
-#endif
 
     printf("Image returned with return value %#x\n", image_retval);
     retval = 0;

Modified: trunk/openbios-devel/arch/sparc64/boot.c
===================================================================
--- trunk/openbios-devel/arch/sparc64/boot.c	2009-07-11 12:23:24 UTC (rev 507)
+++ trunk/openbios-devel/arch/sparc64/boot.c	2009-07-11 12:25:26 UTC (rev 508)
@@ -26,11 +26,11 @@
         if (kernel_size) {
             void (*entry)(unsigned long p1, unsigned long p2, unsigned long p3,
                           unsigned long p4, unsigned long p5);
-            extern int of_client_interface( int *params );
+            extern int sparc64_of_client_interface( int *params );
 
             printk("[sparc64] Kernel already loaded\n");
             entry = (void *) (unsigned long)kernel_image;
-            entry(0, 0, 0, 0, (unsigned long)&of_client_interface);
+            entry(0, 0, 0, 0, (unsigned long)&sparc64_of_client_interface);
         }
 
 	if(!path) {

Modified: trunk/openbios-devel/arch/sparc64/boot.h
===================================================================
--- trunk/openbios-devel/arch/sparc64/boot.h	2009-07-11 12:23:24 UTC (rev 507)
+++ trunk/openbios-devel/arch/sparc64/boot.h	2009-07-11 12:25:26 UTC (rev 508)
@@ -22,8 +22,9 @@
 int fcode_load(const char *filename);
 
 // context.c
-extern struct context *__context;
+extern struct context * volatile __context;
 uint64_t start_elf(uint64_t entry_point, uint64_t param);
+uint64_t start_client_image(uint64_t entry_point, uint64_t cif_handler);
 
 // boot.c
 extern struct sys_info sys_info;

Modified: trunk/openbios-devel/arch/sparc64/build.xml
===================================================================
--- trunk/openbios-devel/arch/sparc64/build.xml	2009-07-11 12:23:24 UTC (rev 507)
+++ trunk/openbios-devel/arch/sparc64/build.xml	2009-07-11 12:25:26 UTC (rev 508)
@@ -29,6 +29,10 @@
   <rule><![CDATA[ $(SRCDIR)/arch/sparc64/vectors.S
 	$(CC) $$EXTRACFLAGS $(AS_FLAGS) $(CFLAGS) $(INCLUDES) -c -o $@ $^]]></rule>
  </executable>
+ <executable name="target/arch/sparc64/call-client.o" target="target">
+  <rule><![CDATA[ $(SRCDIR)/arch/sparc64/call-client.S
+	$(CC) $$EXTRACFLAGS $(AS_FLAGS) $(CFLAGS) $(INCLUDES) -c -o $@ $^]]></rule>
+ </executable>
 
  <executable name="openbios-plain.elf" target="target" condition="IMAGE_ELF">
   <rule>
@@ -39,6 +43,7 @@
   <object source="plainboot.c"/>
   <external-object source="target/arch/sparc64/vectors.o"/>
   <external-object source="target/arch/sparc64/entry.o"/>
+  <external-object source="target/arch/sparc64/call-client.o"/>
   <external-object source="libsparc64.a"/>
   <external-object source="libbootstrap.a"/>
   <external-object source="libdrivers.a"/>
@@ -77,6 +82,7 @@
   <external-object source="target/arch/sparc64/vectors.o"/>
   <external-object source="target/arch/sparc64/entry.o"/>
   <external-object source="target/arch/sparc64/builtin.o"/>
+  <external-object source="target/arch/sparc64/call-client.o"/>
   <external-object source="libsparc64.a"/>
   <external-object source="libbootstrap.a"/>
   <external-object source="libdrivers.a"/>

Modified: trunk/openbios-devel/arch/sparc64/context.c
===================================================================
--- trunk/openbios-devel/arch/sparc64/context.c	2009-07-11 12:23:24 UTC (rev 507)
+++ trunk/openbios-devel/arch/sparc64/context.c	2009-07-11 12:25:26 UTC (rev 508)
@@ -10,7 +10,7 @@
 #include "boot.h"
 
 #define MAIN_STACK_SIZE 16384
-#define IMAGE_STACK_SIZE 4096
+#define IMAGE_STACK_SIZE 4096*2
 
 #define debug printk
 
@@ -23,7 +23,7 @@
  * to start us up.
  */
 static struct context main_ctx = {
-    .regs[REG_SP] = (uint64_t) &_estack - 2047 - 96,
+    .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,
@@ -31,7 +31,7 @@
 
 /* This is used by assembly routine to load/store the context which
  * it is to switch/switched.  */
-struct context *__context = &main_ctx;
+struct context * volatile __context = &main_ctx;
 
 /* Stack for loaded ELF image */
 static uint8_t image_stack[IMAGE_STACK_SIZE];
@@ -62,19 +62,25 @@
     __context = boot_ctx;
 }
 
+static uint64_t ALIGN_SIZE(uint64_t x, uint64_t a)
+{
+    return (x + a - 1) & ~(a-1);
+}
+
 /* Setup a new context using the given stack.
  */
 struct context *
 init_context(uint8_t *stack, uint64_t stack_size, int num_params)
 {
     struct context *ctx;
+    uint8_t *stack_top = stack + stack_size;
 
     ctx = (struct context *)
-	(stack + stack_size - (sizeof(*ctx) + num_params*sizeof(uint32_t)));
+	(stack_top - ALIGN_SIZE(sizeof(*ctx) + num_params*sizeof(uint64_t), sizeof(uint64_t)));
     memset(ctx, 0, sizeof(*ctx));
 
     /* Fill in reasonable default for flat memory model */
-    ctx->regs[REG_SP] = virt_to_phys(SP_LOC(ctx));
+    ctx->regs[REG_SP] = virt_to_phys(stack_top - STACK_BIAS - 192);
     ctx->return_addr = virt_to_phys(__exit_context);
 
     return ctx;
@@ -85,10 +91,11 @@
 {
     struct context *save, *ret;
 
-    debug("switching to new context:\n");
+    debug("switching to new context: entry point %#llx stack 0x%016llx\n", ctx->pc, ctx->regs[REG_SP]);
     save = __context;
     __context = ctx;
     //asm ("pushl %cs; call __switch_context");
+    asm ("call __switch_context_nosave; nop");
     ret = __context;
     __context = save;
     return ret;
@@ -109,3 +116,18 @@
     //return ctx->eax;
     return 0;
 }
+
+/* Start client image */
+uint64_t start_client_image(uint64_t entry_point, uint64_t cif_handler)
+{
+    struct context *ctx;
+
+    ctx = init_context(image_stack, sizeof image_stack, 0);
+    ctx->pc  = entry_point;
+    ctx->npc = entry_point+4;
+    ctx->regs[REG_O0+4] = cif_handler;
+
+    ctx = switch_to(ctx);
+
+    return 0;
+}

Modified: trunk/openbios-devel/arch/sparc64/context.h
===================================================================
--- trunk/openbios-devel/arch/sparc64/context.h	2009-07-11 12:23:24 UTC (rev 507)
+++ trunk/openbios-devel/arch/sparc64/context.h	2009-07-11 12:25:26 UTC (rev 508)
@@ -1,6 +1,8 @@
 #ifndef SPARC64_CONTEXT_H
 #define SPARC64_CONTEXT_H
 
+#define STACK_BIAS             2047
+
 struct context {
     /* General registers */
     uint64_t regs[32];

Modified: trunk/openbios-devel/arch/sparc64/switch.S
===================================================================
--- trunk/openbios-devel/arch/sparc64/switch.S	2009-07-11 12:23:24 UTC (rev 507)
+++ trunk/openbios-devel/arch/sparc64/switch.S	2009-07-11 12:25:26 UTC (rev 508)
@@ -24,7 +24,12 @@
 
 /* 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]
@@ -61,7 +66,8 @@
 
 __switch_context_nosave:
 	/* Interrupts are not allowed... */
-
+	/* make sure caller's windows are on caller's stack */
+	flushw
 	/* Load all registers
 	 */
 	setx	__context, %g2, %g1




More information about the OpenBIOS mailing list