All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] qemu Makefile.target cpu-all.h cpu-exec.c dynge...
@ 2007-05-05 19:23 Thiemo Seufer
  2007-05-07 20:23 ` [Qemu-devel] [PATCH] " Stefan Weil
  0 siblings, 1 reply; 7+ messages in thread
From: Thiemo Seufer @ 2007-05-05 19:23 UTC (permalink / raw)
  To: qemu-devel

CVSROOT:	/sources/qemu
Module name:	qemu
Changes by:	Thiemo Seufer <ths>	07/05/05 19:23:11

Modified files:
	.              : Makefile.target cpu-all.h cpu-exec.c 
	                 dyngen-exec.h dyngen.c dyngen.h exec-all.h 

Log message:
	Some bits of Linux/MIPS host support, still segfaulty.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/Makefile.target?cvsroot=qemu&r1=1.167&r2=1.168
http://cvs.savannah.gnu.org/viewcvs/qemu/cpu-all.h?cvsroot=qemu&r1=1.69&r2=1.70
http://cvs.savannah.gnu.org/viewcvs/qemu/cpu-exec.c?cvsroot=qemu&r1=1.101&r2=1.102
http://cvs.savannah.gnu.org/viewcvs/qemu/dyngen-exec.h?cvsroot=qemu&r1=1.34&r2=1.35
http://cvs.savannah.gnu.org/viewcvs/qemu/dyngen.c?cvsroot=qemu&r1=1.49&r2=1.50
http://cvs.savannah.gnu.org/viewcvs/qemu/dyngen.h?cvsroot=qemu&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/qemu/exec-all.h?cvsroot=qemu&r1=1.51&r2=1.52

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] qemu Makefile.target cpu-all.h cpu-exec.c dynge...
  2007-05-05 19:23 [Qemu-devel] qemu Makefile.target cpu-all.h cpu-exec.c dynge Thiemo Seufer
@ 2007-05-07 20:23 ` Stefan Weil
  2007-05-07 20:27   ` Stefan Weil
                     ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Stefan Weil @ 2007-05-07 20:23 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1398 bytes --]

Hello Thiemo,

here is a (partially crude) patch which mixes your code with
my own MIPS host extension and code parts from a MIPS host
made by Johannes E. Schindelin 2 years ago.

Using this new code I was able to start a Linux kernel
using qemu-system-mipsel running in an emulated MALTA machine.

I could also start a simple i386 application (/bin/echo)
with qemu-i386 (until it failed with the usual libc / tls problems).

When I started to write MIPS host, I found it difficult to
get all locations which needed new code. To make it easier for
new ports, I changed sequences of #if ... #endif, #if ... #endif
into #if ... #elif ... #elif ... #else #error #endif.

Other changes include some smaller spelling corrections.

Most important was Johannes code for testandset and PARAMn.

The patch still includes your relocation code, but it is disabled
and uses my own code. I had no time to check or try the differences.

Fabrice, could you please update the status web page and add
"experimental MIPS host support" (otherwise still more people might
start to re-invent the code) :-).

Stefan

Thiemo Seufer schrieb:
> CVSROOT: /sources/qemu
> Module name: qemu
> Changes by: Thiemo Seufer <ths> 07/05/05 19:23:11
>
> Modified files:
> . : Makefile.target cpu-all.h cpu-exec.c
> dyngen-exec.h dyngen.c dyngen.h exec-all.h
>
> Log message:
> Some bits of Linux/MIPS host support, still segfaulty.


[-- Attachment #2: mipshost.patch --]
[-- Type: text/x-diff, Size: 19599 bytes --]

diff --rec -u -x .svn -x CVS head/cpu-all.h mipshost/cpu-all.h
--- head/cpu-all.h	2007-05-06 11:19:42.000000000 +0200
+++ mipshost/cpu-all.h	2007-05-07 21:24:08.000000000 +0200
@@ -1045,8 +1045,9 @@
 
 #else
 /* The host CPU doesn't have an easily accessible cycle counter.
-   Just return a monotonically increasing vlue.  This will be totally wrong,
+   Just return a monotonically increasing value.  This will be totally wrong,
    but hopefully better than nothing.  */
+#warning host without cycle counter
 static inline int64_t cpu_get_real_ticks (void)
 {
     static int64_t ticks = 0;
diff --rec -u -x .svn -x CVS head/dyngen.c mipshost/dyngen.c
--- head/dyngen.c	2007-05-06 11:19:44.000000000 +0200
+++ mipshost/dyngen.c	2007-05-07 20:37:11.000000000 +0200
@@ -1653,18 +1653,22 @@
 #define INSN_RETURN     0x03e00008
 #define INSN_NOP        0x00000000
 
-        uint8_t *p = p_end;
-
-        if (p < (p_start + 0x8)) {
+        uint8_t *p = (void *)(p_end - 8);
+        if (p == p_start) {
             error("empty code for %s", name);
-        } else {
-            uint32_t end_insn1, end_insn2;
-
-            p -= 0x8;
-            end_insn1 = get32((uint32_t *)(p + 0x0));
-            end_insn2 = get32((uint32_t *)(p + 0x4));
-            if (end_insn1 != INSN_RETURN && end_insn2 != INSN_NOP)
-                error("jr ra not found at end of %s", name);
+        } else if (get32((uint32_t *)(p)) != INSN_RETURN) {
+            error("jr ra expected near the end of %s", name);
+        } else if (get32((uint32_t *)(p + 4)) != INSN_NOP) {
+            error("nop expected at the end of %s", name);
+        } else if ((get32((uint32_t *)(p_start)) >> 16) == 0x3c1c &&
+                  (get32((uint32_t *)(p_start + 4)) >> 16) == 0x279c &&
+                  get32((uint32_t *)(p_start + 8)) == 0x0399e021) {
+            /* Skip prologue
+               lui      gp,nn
+               addiu    gp,gp,nn
+               addu     gp,gp,t9 */
+            p_start += 12;
+            start_offset += 12;
         }
         copy_size = p - p_start;
     }
@@ -1727,9 +1731,7 @@
             if (offset >= start_offset &&
                 offset < start_offset + (p_end - p_start)) {
                 sym_name = get_rel_sym_name(rel);
-                if(!sym_name)
-                    continue;
-                if (*sym_name && 
+                if (sym_name && *sym_name && 
                     !strstart(sym_name, "__op_param", NULL) &&
                     !strstart(sym_name, "__op_jmp", NULL) &&
                     !strstart(sym_name, "__op_gen_label", NULL)) {
@@ -1740,9 +1742,8 @@
 				sym_name+1, sym_name);
 			continue;
 		    }
-#endif
-#if defined(__APPLE__)
-/* set __attribute((unused)) on darwin because we wan't to avoid warning when we don't use the symbol */
+#elif defined(__APPLE__)
+/* set __attribute((unused)) on darwin because we want to avoid warning when we don't use the symbol */
                     fprintf(outfile, "extern char %s __attribute__((unused));\n", sym_name);
 #elif defined(HOST_IA64)
 			if (ELF64_R_TYPE(rel->r_info) != R_IA64_PCREL21B)
@@ -1754,7 +1755,7 @@
 				fprintf(outfile, "    extern char %s;\n",
 					sym_name);
 #else
-                    fprintf(outfile, "extern char %s;\n", sym_name);
+                    fprintf(outfile, "    extern char %s;\n", sym_name);
 #endif
                 }
             }
@@ -1828,7 +1829,7 @@
             }
         }
 
-        /* load parameres in variables */
+        /* load parameters in variables */
         for(i = 0; i < nb_args; i++) {
             fprintf(outfile, "    param%d = *opparam_ptr++;\n", i + 1);
         }
@@ -2512,6 +2513,78 @@
             }
 #elif defined(HOST_MIPS)
             {
+#ifdef CONFIG_FORMAT_ELF
+                char xname[256];
+                for(i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
+                    host_ulong r_offset = rel->r_offset;
+                    if (r_offset >= start_offset &&
+                        r_offset < start_offset + copy_size) {
+                        int reloc_offset = r_offset - start_offset;
+#if defined(WORDS_BIGENDIAN)
+                        int reloc_offset_lsb = reloc_offset + 2;
+#else
+                        int reloc_offset_lsb = reloc_offset;
+#endif
+                        int addend = get32((uint32_t *)(text + r_offset));
+                        int type = ELF32_R_TYPE(rel->r_info);
+                        sym_name = get_rel_sym_name(rel);
+                        get_reloc_expr(xname, sizeof(xname), sym_name);
+                        switch(type) {
+                        case R_MIPS_HI16:
+                            fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (uint16_t)((uint32_t)(%s) >> 16); // r_offset = %d // R_MIPS_HI16\n", 
+                                    reloc_offset_lsb, xname, r_offset);
+                            break;
+                        case R_MIPS_LO16:
+                            fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (uint16_t)(%s); // r_offset = %d // R_MIPS_LO16\n", 
+                                    reloc_offset_lsb, xname, r_offset);
+                            break;
+                        case R_MIPS_GOT16:
+                            /* No need to relocate. */
+                            fprintf(outfile, "    (void)%s; // reloc_offset = %d, r_offset = %d // R_MIPS_GOT16\n", 
+                                    xname, reloc_offset, r_offset);
+                            break;
+                        case R_MIPS_PC16:
+                            fprintf(outfile, "    /* R_MIPS_PC16 RELOC, offset 0x%x, name %s */\n",
+                                    rel->r_offset, sym_name);
+                            fprintf(outfile,
+                                    "    *(uint32_t *)(gen_code_ptr + 0x%x) = "
+                                    "(0x%x & ~0xffff) "
+                                    "| ((0x%x + ((%s - (*(uint32_t *)(gen_code_ptr + 0x%x))) >> 2)) "
+                                    "   & 0xffff);\n",
+                                    reloc_offset, addend, addend, name, reloc_offset);
+                            break;
+                        case R_MIPS_CALL16:
+                            /* No need to relocate. */
+                            fprintf(outfile, "    (void)%s; // reloc_offset = %d, r_offset = %d // R_MIPS_CALL16\n", 
+                                    xname, reloc_offset, r_offset);
+                            break;
+                        case R_MIPS_GOTHI16:
+                            fprintf(outfile, "#error unsupported mips relocation R_MIPS_GOTHI16\n");
+                            break;
+                        case R_MIPS_GOTLO16:
+                            fprintf(outfile, "#error unsupported mips relocation R_MIPS_GOTLO16\n");
+                            break;
+                        case R_MIPS_CALLHI16:
+                            fprintf(outfile, "#warning untested mips relocation R_MIPS_CALLHI16\n");
+                            fprintf(outfile, "    (void)%s; // reloc_offset = %d, r_offset = %d // R_MIPS_CALLHI16\n", 
+                                    xname, reloc_offset, r_offset);
+                            break;
+                        case R_MIPS_CALLLO16:
+                            fprintf(outfile, "#warning untested mips relocation R_MIPS_CALLLO16\n");
+                            fprintf(outfile, "    (void)%s; // reloc_offset = %d, r_offset = %d // R_MIPS_CALLLO16\n", 
+                                    xname, reloc_offset, r_offset);
+                            break;
+                        default:
+                            error("unsupported mips relocation (%d) for %s in %s\n", type, sym_name, name);
+                        }
+                    }
+                }
+#else
+#error unsupport object format
+#endif
+            }
+#elif defined(HOST_MIPS)
+            {
                 for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
 		    if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {
                         char name[256];
@@ -2548,16 +2621,6 @@
 				    " | (%s & 0xffff);\n",
                                     reloc_offset, reloc_offset, name);
 			    break;
-			case R_MIPS_PC16:
-                            fprintf(outfile, "    /* R_MIPS_PC16 RELOC, offset 0x%x, name %s */\n",
-				    rel->r_offset, sym_name);
-                            fprintf(outfile,
-				    "    *(uint32_t *)(gen_code_ptr + 0x%x) = "
-				    "(0x%x & ~0xffff) "
-				    "| ((0x%x + ((%s - (*(uint32_t *)(gen_code_ptr + 0x%x))) >> 2)) "
-				    "   & 0xffff);\n",
-                                    reloc_offset, addend, addend, name, reloc_offset);
-			    break;
 			case R_MIPS_GOT16:
 			case R_MIPS_CALL16:
                             fprintf(outfile, "    /* R_MIPS_GOT16 RELOC, offset 0x%x, name %s */\n",
diff --rec -u -x .svn -x CVS head/dyngen-exec.h mipshost/dyngen-exec.h
--- head/dyngen-exec.h	2007-05-06 11:19:42.000000000 +0200
+++ mipshost/dyngen-exec.h	2007-05-07 20:02:40.000000000 +0200
@@ -89,21 +89,19 @@
 #undef NULL
 #define NULL 0
 
-#ifdef __i386__
+#if defined(__i386__)
 #define AREG0 "ebp"
 #define AREG1 "ebx"
 #define AREG2 "esi"
 #define AREG3 "edi"
-#endif
-#ifdef __x86_64__
+#elif defined(__x86_64__)
 #define AREG0 "r14"
 #define AREG1 "r15"
 #define AREG2 "r12"
 #define AREG3 "r13"
 //#define AREG4 "rbp"
 //#define AREG5 "rbx"
-#endif
-#ifdef __powerpc__
+#elif defined(__powerpc__)
 #define AREG0 "r27"
 #define AREG1 "r24"
 #define AREG2 "r25"
@@ -121,14 +119,12 @@
 #endif
 #define USE_INT_TO_FLOAT_HELPERS
 #define BUGGY_GCC_DIV64
-#endif
-#ifdef __arm__
+#elif defined(__arm__)
 #define AREG0 "r7"
 #define AREG1 "r4"
 #define AREG2 "r5"
 #define AREG3 "r6"
-#endif
-#ifdef __mips__
+#elif defined(__mips__)
 #define AREG0 "fp"
 #define AREG1 "s0"
 #define AREG2 "s1"
@@ -138,8 +134,7 @@
 #define AREG6 "s5"
 #define AREG7 "s6"
 #define AREG8 "s7"
-#endif
-#ifdef __sparc__
+#elif defined(__sparc__)
 #ifdef HOST_SOLARIS
 #define AREG0 "g2"
 #define AREG1 "g3"
@@ -168,14 +163,12 @@
 #endif
 #endif
 #define USE_FP_CONVERT
-#endif
-#ifdef __s390__
+#elif defined(__s390__)
 #define AREG0 "r10"
 #define AREG1 "r7"
 #define AREG2 "r8"
 #define AREG3 "r9"
-#endif
-#ifdef __alpha__
+#elif defined(__alpha__)
 /* Note $15 is the frame pointer, so anything in op-i386.c that would
    require a frame pointer, like alloca, would probably loose.  */
 #define AREG0 "$15"
@@ -185,19 +178,19 @@
 #define AREG4 "$12"
 #define AREG5 "$13"
 #define AREG6 "$14"
-#endif
-#ifdef __mc68000
+#elif defined(__mc68000)
 #define AREG0 "%a5"
 #define AREG1 "%a4"
 #define AREG2 "%d7"
 #define AREG3 "%d6"
 #define AREG4 "%d5"
-#endif
-#ifdef __ia64__
+#elif defined(__ia64__)
 #define AREG0 "r7"
 #define AREG1 "r4"
 #define AREG2 "r5"
 #define AREG3 "r6"
+#else
+#error unsupported CPU
 #endif
 
 /* force GCC to generate only one epilog at the end of the function */
@@ -231,6 +224,16 @@
 #define PARAM1 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param1)); _r; })
 #define PARAM2 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param2)); _r; })
 #define PARAM3 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param3)); _r; })
+#elif defined(__mips__)
+/* On MIPS, parameters to a c expression are passed via the global pointer.
+ * We don't want that. */
+#define PARAMN(index) ({ register int _r; \
+                asm("lui %0,%%hi(__op_param" #index ")\n\t" \
+                        "ori %0,%0,%%lo(__op_param" #index ")" \
+                        : "=r"(_r)); _r; })
+#define PARAM1 PARAMN(1)
+#define PARAM2 PARAMN(2)
+#define PARAM3 PARAMN(3)
 #else
 #if defined(__APPLE__)
 static int __op_param1, __op_param2, __op_param3;
@@ -250,44 +253,41 @@
 #define ASM_NAME(x) #x
 #endif
 
-#ifdef __i386__
+#if defined(__i386__)
 #define EXIT_TB() asm volatile ("ret")
 #define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n)
-#endif
-#ifdef __x86_64__
+#elif defined(__x86_64__)
 #define EXIT_TB() asm volatile ("ret")
 #define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n)
-#endif
-#ifdef __powerpc__
+#elif defined(__powerpc__)
 #define EXIT_TB() asm volatile ("blr")
 #define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
-#endif
-#ifdef __s390__
+#elif defined(__s390__)
 #define EXIT_TB() asm volatile ("br %r14")
 #define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
-#endif
-#ifdef __alpha__
+#elif defined(__alpha__)
 #define EXIT_TB() asm volatile ("ret")
-#endif
-#ifdef __ia64__
+#elif defined(__ia64__)
 #define EXIT_TB() asm volatile ("br.ret.sptk.many b0;;")
 #define GOTO_LABEL_PARAM(n) asm volatile ("br.sptk.many " \
 					  ASM_NAME(__op_gen_label) #n)
-#endif
-#ifdef __sparc__
+#elif defined(__sparc__)
 #define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0; nop")
 #define GOTO_LABEL_PARAM(n) asm volatile ("ba " ASM_NAME(__op_gen_label) #n ";nop")
-#endif
-#ifdef __arm__
+#elif defined(__arm__)
 #define EXIT_TB() asm volatile ("b exec_loop")
 #define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
-#endif
-#ifdef __mc68000
+#elif defined(__mc68000)
 #define EXIT_TB() asm volatile ("rts")
-#endif
-#ifdef __mips__
-#define EXIT_TB() asm volatile ("jr $ra")
-#define GOTO_LABEL_PARAM(n) asm volatile (".set noat; la $1, " ASM_NAME(__op_gen_label) #n "; jr $1; .set at")
+#elif defined(__mips__)
+#define EXIT_TB() asm volatile ("jr $31; nop")
+#define GOTO_LABEL_PARAM(n) asm volatile (\
+    "lui $2,%hi(" ASM_NAME(__op_gen_label) #n ")\n\t" \
+    "ori $2,$2,%lo(" ASM_NAME(__op_gen_label)#n ")\n\t" \
+    "jr $2\n\t" \
+    "nop")
+#else
+#error unsupported CPU
 #endif
 
 #endif /* !defined(__DYNGEN_EXEC_H__) */
diff --rec -u -x .svn -x CVS head/dyngen.h mipshost/dyngen.h
--- head/dyngen.h	2007-05-06 11:19:44.000000000 +0200
+++ mipshost/dyngen.h	2007-05-07 20:19:20.000000000 +0200
@@ -19,7 +19,7 @@
  */
 
 int __op_param1, __op_param2, __op_param3;
-#if defined(__sparc__) || defined(__arm__)
+#if defined(__sparc__) || defined(__arm__) || defined(__mips__)
   void __op_gen_label1(){}
   void __op_gen_label2(){}
   void __op_gen_label3(){}
@@ -28,25 +28,26 @@
 #endif
 int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
 
-#ifdef __i386__
+#if defined(__i386__)
+
 static inline void flush_icache_range(unsigned long start, unsigned long stop)
 {
 }
-#endif
 
-#ifdef __x86_64__
+#elif defined(__x86_64__)
+
 static inline void flush_icache_range(unsigned long start, unsigned long stop)
 {
 }
-#endif
 
-#ifdef __s390__
+#elif defined(__s390__)
+
 static inline void flush_icache_range(unsigned long start, unsigned long stop)
 {
 }
-#endif
 
-#ifdef __ia64__
+#elif defined(__ia64__)
+
 static inline void flush_icache_range(unsigned long start, unsigned long stop)
 {
     while (start < stop) {
@@ -55,9 +56,8 @@
     }
     asm volatile (";;sync.i;;srlz.i;;");
 }
-#endif
 
-#ifdef __powerpc__
+#elif defined(__powerpc__)
 
 #define MIN_CACHE_LINE_SIZE 8 /* conservative value */
 
@@ -78,16 +78,15 @@
     asm volatile ("sync" : : : "memory");
     asm volatile ("isync" : : : "memory");
 }
-#endif
 
-#ifdef __alpha__
+#elif defined(__alpha__)
+
 static inline void flush_icache_range(unsigned long start, unsigned long stop)
 {
     asm ("imb");
 }
-#endif
 
-#ifdef __sparc__
+#elif defined(__sparc__)
 
 static void inline flush_icache_range(unsigned long start, unsigned long stop)
 {
@@ -100,9 +99,8 @@
 		__asm__ __volatile__("flush\t%0" : : "r" (p));
 }
 
-#endif
+#elif defined(__arm__)
 
-#ifdef __arm__
 static inline void flush_icache_range(unsigned long start, unsigned long stop)
 {
     register unsigned long _beg __asm ("a1") = start;
@@ -110,17 +108,16 @@
     register unsigned long _flg __asm ("a3") = 0;
     __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
 }
-#endif
 
-#ifdef __mc68000
+#elif defined(__mc68000)
+
 #include <asm/cachectl.h>
 static inline void flush_icache_range(unsigned long start, unsigned long stop)
 {
     cacheflush(start,FLUSH_SCOPE_LINE,FLUSH_CACHE_BOTH,stop-start+16);
 }
-#endif
 
-#ifdef __alpha__
+#elif defined(__alpha__)
 
 register int gp asm("$29");
 
@@ -141,9 +138,7 @@
     *dest |= (offset >> 2) & ((1 << 21) - 1);
 }
 
-#endif /* __alpha__ */
-
-#ifdef __arm__
+#elif defined(__arm__)
 
 #define ARM_LDR_TABLE_SIZE 1024
 
@@ -244,10 +239,7 @@
     return gen_code_ptr;
 }
 
-#endif /* __arm__ */
-
-#ifdef __ia64
-
+#elif defined(__ia64)
 
 /* Patch instruction with "val" where "mask" has 1 bits. */
 static inline void ia64_patch (uint64_t insn_addr, uint64_t mask, uint64_t val)
@@ -462,12 +454,16 @@
     *gen_code_pp = gen_code_ptr;
 }
 
-#endif
+#elif defined(__mips__)
 
-#ifdef __mips__
 #include <sys/cachectl.h>
 static inline void flush_icache_range(unsigned long start, unsigned long stop)
 {
     _flush_cache ((void *)start, stop - start, BCACHE);
 }
+
+#else
+
+#error unsupported CPU
+
 #endif
diff --rec -u -x .svn -x CVS head/exec-all.h mipshost/exec-all.h
--- head/exec-all.h	2007-05-06 11:19:44.000000000 +0200
+++ mipshost/exec-all.h	2007-05-07 20:39:41.000000000 +0200
@@ -357,7 +357,7 @@
 extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
 extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
 
-#ifdef __powerpc__
+#if defined(__powerpc__)
 static inline int testandset (int *p)
 {
     int ret;
@@ -373,9 +373,7 @@
                           : "cr0", "memory");
     return ret;
 }
-#endif
-
-#ifdef __i386__
+#elif defined(__i386__)
 static inline int testandset (int *p)
 {
     long int readval = 0;
@@ -386,9 +384,7 @@
                           : "cc");
     return readval;
 }
-#endif
-
-#ifdef __x86_64__
+#elif defined(__x86_64__)
 static inline int testandset (int *p)
 {
     long int readval = 0;
@@ -399,9 +395,7 @@
                           : "cc");
     return readval;
 }
-#endif
-
-#ifdef __s390__
+#elif defined(__s390__)
 static inline int testandset (int *p)
 {
     int ret;
@@ -413,9 +407,7 @@
 			  : "cc", "memory" );
     return ret;
 }
-#endif
-
-#ifdef __alpha__
+#elif defined(__alpha__)
 static inline int testandset (int *p)
 {
     int ret;
@@ -432,9 +424,7 @@
 			  : "m" (*p));
     return ret;
 }
-#endif
-
-#ifdef __sparc__
+#elif defined(__sparc__)
 static inline int testandset (int *p)
 {
 	int ret;
@@ -446,9 +436,7 @@
 
 	return (ret ? 1 : 0);
 }
-#endif
-
-#ifdef __arm__
+#elif defined(__arm__)
 static inline int testandset (int *spinlock)
 {
     register unsigned int ret;
@@ -458,9 +446,7 @@
     
     return ret;
 }
-#endif
-
-#ifdef __mc68000
+#elif defined(__mc68000)
 static inline int testandset (int *p)
 {
     char ret;
@@ -470,37 +456,32 @@
                          : "cc","memory");
     return ret;
 }
-#endif
-
-#ifdef __ia64
+#elif defined(__ia64)
 #include <ia64intrin.h>
 
 static inline int testandset (int *p)
 {
     return __sync_lock_test_and_set (p, 1);
 }
-#endif
-
-#ifdef __mips__
+#elif defined(__mips__)
 static inline int testandset (int *p)
 {
     int ret;
-
-    __asm__ __volatile__ (
-	"	.set push		\n"
-	"	.set noat		\n"
-	"	.set mips2		\n"
-	"1:	li	$1, 1		\n"
-	"	ll	%0, %1		\n"
-	"	sc	$1, %1		\n"
-	"	bnez	$1, 1b		\n"
-	"	.set pop		"
-	: "=r" (ret), "+R" (*p)
-	:
-	: "memory");
-
+    __asm__ __volatile__(
+        ".set mips2\n"
+        "ll %0,%1\n"
+        ".set noreorder\n"
+        "bnez %0,1f\n"
+        "li %0,0\n"
+        "li %0,1\n"
+        "sc %0,%1\n"
+        "1:\n"
+        : "=r" (ret), "=m" (*p)
+    );
     return ret;
 }
+#else
+#error unimplemented CPU
 #endif
 
 typedef int spinlock_t;

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] qemu Makefile.target cpu-all.h cpu-exec.c dynge...
  2007-05-07 20:23 ` [Qemu-devel] [PATCH] " Stefan Weil
@ 2007-05-07 20:27   ` Stefan Weil
  2007-05-07 22:48   ` Johannes Schindelin
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Stefan Weil @ 2007-05-07 20:27 UTC (permalink / raw)
  To: QEMU Developers

For Linux usermode emulation, this patch was missing.

Stefan

Index: cpu-exec.c
===================================================================
--- cpu-exec.c  (Revision 656)
+++ cpu-exec.c  (Arbeitskopie)
@@ -1545,9 +1545,10 @@

 #elif defined(__mips__)

-int cpu_signal_handler(int host_signum, struct siginfo *info,
+int cpu_signal_handler(int host_signum, void *pinfo,
                        void *puc)
 {
+    struct siginfo *info = (struct siginfo *)pinfo;
     struct ucontext *uc = puc;
     greg_t pc = uc->uc_mcontext.pc;
     int is_write;
   

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] qemu Makefile.target cpu-all.h cpu-exec.c dynge...
  2007-05-07 20:23 ` [Qemu-devel] [PATCH] " Stefan Weil
  2007-05-07 20:27   ` Stefan Weil
@ 2007-05-07 22:48   ` Johannes Schindelin
  2007-05-09  0:02   ` Thiemo Seufer
  2007-05-09  0:17   ` [Qemu-devel] [PATCH] qemu Makefile.target cpu-all.h cpu-exec.c dynge Thiemo Seufer
  3 siblings, 0 replies; 7+ messages in thread
From: Johannes Schindelin @ 2007-05-07 22:48 UTC (permalink / raw)
  To: Stefan Weil; +Cc: qemu-devel

Hi Stefan,

On Mon, 7 May 2007, Stefan Weil wrote:

> here is a (partially crude) patch which mixes your code with my own MIPS 
> host extension and code parts from a MIPS host made by Johannes E. 
> Schindelin 2 years ago.

Hey, that's cool! I did not have the motivation/time/machines to pick up 
on that port...

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] qemu Makefile.target cpu-all.h cpu-exec.c dynge...
  2007-05-07 20:23 ` [Qemu-devel] [PATCH] " Stefan Weil
  2007-05-07 20:27   ` Stefan Weil
  2007-05-07 22:48   ` Johannes Schindelin
@ 2007-05-09  0:02   ` Thiemo Seufer
  2007-07-31 20:49     ` [Qemu-devel] [PATCH] QEMU Mips Host Stefan Weil
  2007-05-09  0:17   ` [Qemu-devel] [PATCH] qemu Makefile.target cpu-all.h cpu-exec.c dynge Thiemo Seufer
  3 siblings, 1 reply; 7+ messages in thread
From: Thiemo Seufer @ 2007-05-09  0:02 UTC (permalink / raw)
  To: Stefan Weil; +Cc: qemu-devel

Stefan Weil wrote:
[snip]

I cherrypicked the easy bits, and will look at the rest when I have
more time.

> When I started to write MIPS host, I found it difficult to
> get all locations which needed new code. To make it easier for
> new ports, I changed sequences of #if ... #endif, #if ... #endif
> into #if ... #elif ... #elif ... #else #error #endif.

Some of those folded unrelated things together, I committed a different
patch based on yours.

> Other changes include some smaller spelling corrections.

Also committed.

> Most important was Johannes code for testandset and PARAMn.

AFAICS that testandset implementation is broken, and I think
mine is correct, maybe except for the +R vs. +m bit in the asm
constraints.

Did my implementation fail for you?

> The patch still includes your relocation code, but it is disabled
> and uses my own code. I had no time to check or try the differences.

Then I gather there's no particular reason why my _PC16 reloc code
is deleted in the patch.


Thiemo

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] qemu Makefile.target cpu-all.h cpu-exec.c dynge...
  2007-05-07 20:23 ` [Qemu-devel] [PATCH] " Stefan Weil
                     ` (2 preceding siblings ...)
  2007-05-09  0:02   ` Thiemo Seufer
@ 2007-05-09  0:17   ` Thiemo Seufer
  3 siblings, 0 replies; 7+ messages in thread
From: Thiemo Seufer @ 2007-05-09  0:17 UTC (permalink / raw)
  To: Stefan Weil; +Cc: qemu-devel

Stefan Weil wrote:
> Hello Thiemo,
> 
> here is a (partially crude) patch which mixes your code with
> my own MIPS host extension and code parts from a MIPS host
> made by Johannes E. Schindelin 2 years ago.
> 
> Using this new code I was able to start a Linux kernel
> using qemu-system-mipsel running in an emulated MALTA machine.

I fails to build for me (on a Broadcom SWARM running Debian unstable):

[...]
gcc-3.4 -Wall -O2 -g -fno-strict-aliasing  -fno-reorder-blocks  -fno-gcse    -fno-optimize-sibling-calls  -fno-crossjumping  -fno-align-labels  -fno-align-jumps  -fno-align-functions -mabi=32 -G0 -fno-PIC -mno-abicalls -fomit-frame-pointer -fno-delayed-branch -Wa,-O0   -I. -I.. -I/srv/ths/qemu/qemu-upstream/target-mips -I/srv/ths/qemu/qemu-upstream -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -I/srv/ths/qemu/qemu-upstream/fpu -DHAS_AUDIO -I/srv/ths/qemu/qemu-upstream/slirp -c -o op.o /srv/ths/qemu/qemu-upstream/target-mips/op.c
../dyngen -o op.h op.o
dyngen: empty code for op_store_T0_gpr_gpr1
make[1]: *** [op.h] Error 1
make[1]: Leaving directory `/srv/ths/qemu/qemu-upstream/mips-softmmu'
make: *** [subdir-mips-softmmu] Error 2


Thiemo

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH] QEMU Mips Host
  2007-05-09  0:02   ` Thiemo Seufer
@ 2007-07-31 20:49     ` Stefan Weil
  0 siblings, 0 replies; 7+ messages in thread
From: Stefan Weil @ 2007-07-31 20:49 UTC (permalink / raw)
  To: QEMU Developers

[-- Attachment #1: Type: text/plain, Size: 1839 bytes --]

Some parts for a working mips host are still missing
in QEMU CVS HEAD.

Here is a new patch which makes mips host work for
system emulation.

I tested it with i386-softmmu/qemu, mips-softmmu/qemu-system-mips
and mipsel-softmmu/qemu-system-mipsel running on
an emulated malta (big and little endian, 32 bit) machine.

I could not test it with 64 bit mips host.

User mode emulation does not work (it does not work with
i386 host, too).

These parts of my patch are essential to get a working emulation:

Makefile.target:
       compiler flags for mips op.o

dyngen-exec.h:
       declarations for PARAM1, PARAM2 and PARAM3
       declaration for GOTO_LABEL_PARAM

dyngen.c:
       fixes for gen_code() and relocation code

dyngen.h:
exec-all.h:
       I'm not sure whether these changes are needed.
       At least it works with the changes...

Stefan

Thiemo Seufer schrieb:
> Stefan Weil wrote:
> [snip]
>
> I cherrypicked the easy bits, and will look at the rest when I have
> more time.
>> When I started to write MIPS host, I found it difficult to
>> get all locations which needed new code. To make it easier for
>> new ports, I changed sequences of #if ... #endif, #if ... #endif
>> into #if ... #elif ... #elif ... #else #error #endif.
>
> Some of those folded unrelated things together, I committed a different
> patch based on yours.
>> Most important was Johannes code for testandset and PARAMn.
> AFAICS that testandset implementation is broken, and I think
> mine is correct, maybe except for the +R vs. +m bit in the asm
> constraints.
>
> Did my implementation fail for you?
>> The patch still includes your relocation code, but it is disabled
>> and uses my own code. I had no time to check or try the differences.
>
> Then I gather there's no particular reason why my _PC16 reloc code
> is deleted in the patch.
>
> Thiemo

[-- Attachment #2: mips-host.diff --]
[-- Type: text/x-diff, Size: 9032 bytes --]

Index: Makefile.target
===================================================================
RCS file: /sources/qemu/qemu/Makefile.target,v
retrieving revision 1.189
diff -u -b -B -r1.189 Makefile.target
--- Makefile.target	31 Jul 2007 01:45:35 -0000	1.189
+++ Makefile.target	31 Jul 2007 20:03:22 -0000
@@ -181,7 +185,7 @@
 endif
 
 ifeq ($(ARCH),mips)
-OP_CFLAGS+=-mabi=32 -G0 -fno-PIC -mno-abicalls -fomit-frame-pointer -fno-delayed-branch -Wa,-O0
+OP_CFLAGS += -G 0 -fomit-frame-pointer -fno-delayed-branch
 ifeq ($(WORDS_BIGENDIAN),yes)
 BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
 else
Index: dyngen-exec.h
===================================================================
RCS file: /sources/qemu/qemu/dyngen-exec.h,v
retrieving revision 1.36
diff -u -b -B -r1.36 dyngen-exec.h
--- dyngen-exec.h	8 May 2007 23:30:44 -0000	1.36
+++ dyngen-exec.h	31 Jul 2007 20:03:23 -0000
@@ -224,6 +224,16 @@
 #define PARAM1 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param1)); _r; })
 #define PARAM2 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param2)); _r; })
 #define PARAM3 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param3)); _r; })
+#elif defined(__mips__)
+/* On MIPS, parameters to a c expression are passed via the global pointer.
+ * We don't want that. */
+#define PARAMN(index) ({ register int _r; \
+                asm("lui %0,%%hi(__op_param" #index ")\n\t" \
+                        "ori %0,%0,%%lo(__op_param" #index ")" \
+                        : "=r"(_r)); _r; })
+#define PARAM1 PARAMN(1)
+#define PARAM2 PARAMN(2)
+#define PARAM3 PARAMN(3)
 #else
 #if defined(__APPLE__)
 static int __op_param1, __op_param2, __op_param3;
@@ -271,7 +281,10 @@
 #define EXIT_TB() asm volatile ("rts")
 #elif defined(__mips__)
 #define EXIT_TB() asm volatile ("jr $ra")
-#define GOTO_LABEL_PARAM(n) asm volatile (".set noat; la $1, " ASM_NAME(__op_gen_label) #n "; jr $1; .set at")
+#define GOTO_LABEL_PARAM(n) asm volatile (\
+    "lui $2,%hi(" ASM_NAME(__op_gen_label) #n ")\n\t" \
+    "ori $2,$2,%lo(" ASM_NAME(__op_gen_label)#n ")\n\t" \
+    "jr $2")
 #else
 #error unsupported CPU
 #endif
Index: dyngen.c
===================================================================
RCS file: /sources/qemu/qemu/dyngen.c,v
retrieving revision 1.54
diff -u -b -B -r1.54 dyngen.c
--- dyngen.c	15 Jul 2007 16:56:08 -0000	1.54
+++ dyngen.c	31 Jul 2007 20:03:26 -0000
@@ -1661,6 +1661,30 @@
 #define INSN_RETURN     0x03e00008
 #define INSN_NOP        0x00000000
 
+        uint8_t *p = (void *)(p_end - 8);
+        if (p == p_start) {
+            error("empty code for %s", name);
+        } else if (get32((uint32_t *)(p)) != INSN_RETURN) {
+            error("jr ra expected near the end of %s", name);
+        } else if (get32((uint32_t *)(p + 4)) != INSN_NOP) {
+            error("nop expected at the end of %s", name);
+        } else if ((get32((uint32_t *)(p_start)) >> 16) == 0x3c1c &&
+                  (get32((uint32_t *)(p_start + 4)) >> 16) == 0x279c &&
+                  get32((uint32_t *)(p_start + 8)) == 0x0399e021) {
+            /* Skip prologue
+               lui      gp,nn
+               addiu    gp,gp,nn
+               addu     gp,gp,t9 */
+            p_start += 12;
+            start_offset += 12;
+        }
+        copy_size = p - p_start;
+    }
+#elif (defined(HOST_MIPS) || defined(HOST_MIPS64)) && 0
+    {
+#define INSN_RETURN     0x03e00008
+#define INSN_NOP        0x00000000
+
         uint8_t *p = p_end;
 
         if (p < (p_start + 0x8)) {
@@ -1671,7 +1695,7 @@
             p -= 0x8;
             end_insn1 = get32((uint32_t *)(p + 0x0));
             end_insn2 = get32((uint32_t *)(p + 0x4));
-            if (end_insn1 != INSN_RETURN && end_insn2 != INSN_NOP)
+            if (end_insn1 != INSN_RETURN || end_insn2 != INSN_NOP)
                 error("jr ra not found at end of %s", name);
         }
         copy_size = p - p_start;
@@ -2521,11 +2545,17 @@
 #elif defined(HOST_MIPS) || defined(HOST_MIPS64)
             {
                 for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
-		    if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {
+                    host_ulong r_offset = rel->r_offset;
+		    if (r_offset >= start_offset && r_offset < start_offset + copy_size) {
                         char relname[256];
                         int type;
                         int addend;
-                        int reloc_offset;
+                        int reloc_offset = r_offset - start_offset;
+#if defined(WORDS_BIGENDIAN)
+                        int reloc_offset_lsb = reloc_offset + 2;
+#else
+                        int reloc_offset_lsb = reloc_offset;
+#endif
 
 			sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
                         /* the compiler leave some unnecessary references to the code */
@@ -2534,7 +2564,6 @@
                         get_reloc_expr(relname, sizeof(relname), sym_name);
 			type = ELF32_R_TYPE(rel->r_info);
                         addend = get32((uint32_t *)(text + rel->r_offset));
-                        reloc_offset = rel->r_offset - start_offset;
 			switch (type) {
 			case R_MIPS_26:
                             fprintf(outfile, "    /* R_MIPS_26 RELOC, offset 0x%x, name %s */\n",
@@ -2547,24 +2576,12 @@
                                     reloc_offset, addend, addend, relname, reloc_offset);
 			    break;
 			case R_MIPS_HI16:
-                            fprintf(outfile, "    /* R_MIPS_HI16 RELOC, offset 0x%x, name %s */\n",
-				    rel->r_offset, sym_name);
-                            fprintf(outfile,
-				    "    *(uint32_t *)(gen_code_ptr + 0x%x) = "
-				    "((*(uint32_t *)(gen_code_ptr + 0x%x)) "
-				    " & ~0xffff) "
-				    " | (((%s - 0x8000) >> 16) & 0xffff);\n",
-                                    reloc_offset, reloc_offset, relname);
+                            fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (uint16_t)((uint32_t)(%s) >> 16); // R_MIPS_HI16\n", 
+                                    reloc_offset_lsb, relname);
 			    break;
 			case R_MIPS_LO16:
-                            fprintf(outfile, "    /* R_MIPS_LO16 RELOC, offset 0x%x, name %s */\n",
-				    rel->r_offset, sym_name);
-                            fprintf(outfile,
-				    "    *(uint32_t *)(gen_code_ptr + 0x%x) = "
-				    "((*(uint32_t *)(gen_code_ptr + 0x%x)) "
-				    " & ~0xffff) "
-				    " | (%s & 0xffff);\n",
-                                    reloc_offset, reloc_offset, relname);
+                            fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (uint16_t)(%s); // R_MIPS_LO16\n", 
+                                    reloc_offset_lsb, relname);
 			    break;
 			case R_MIPS_PC16:
                             fprintf(outfile, "    /* R_MIPS_PC16 RELOC, offset 0x%x, name %s */\n",
@@ -2578,14 +2595,10 @@
 			    break;
 			case R_MIPS_GOT16:
 			case R_MIPS_CALL16:
-                            fprintf(outfile, "    /* R_MIPS_GOT16 RELOC, offset 0x%x, name %s */\n",
+                            /* No need to relocate. */
+                            fprintf(outfile, "    /* R_MIPS_CALL16 / R_MIPS_GOT16 RELOC, offset 0x%x, name %s */\n",
 				    rel->r_offset, sym_name);
-                            fprintf(outfile,
-				    "    *(uint32_t *)(gen_code_ptr + 0x%x) = "
-				    "((*(uint32_t *)(gen_code_ptr + 0x%x)) "
-				    " & ~0xffff) "
-				    " | (((%s - 0x8000) >> 16) & 0xffff);\n",
-                                    reloc_offset, reloc_offset, relname);
+                            fprintf(outfile, "    (void)%s;\n", relname);
 			    break;
 			default:
 			    error("unsupported MIPS relocation (%d)", type);
Index: dyngen.h
===================================================================
RCS file: /sources/qemu/qemu/dyngen.h,v
retrieving revision 1.15
diff -u -b -B -r1.15 dyngen.h
--- dyngen.h	2 Jul 2007 14:06:26 -0000	1.15
+++ dyngen.h	31 Jul 2007 20:03:26 -0000
@@ -19,7 +19,7 @@
  */
 
 int __op_param1, __op_param2, __op_param3;
-#if defined(__sparc__) || defined(__arm__)
+#if defined(__sparc__) || defined(__arm__) || defined(__mips__)
   void __op_gen_label1(){}
   void __op_gen_label2(){}
   void __op_gen_label3(){}
Index: exec-all.h
===================================================================
RCS file: /sources/qemu/qemu/exec-all.h,v
retrieving revision 1.58
diff -u -b -B -r1.58 exec-all.h
--- exec-all.h	2 Jul 2007 14:06:26 -0000	1.58
+++ exec-all.h	31 Jul 2007 20:03:27 -0000
@@ -472,6 +472,20 @@
 {
     int ret;
 
+#if 1
+    __asm__ __volatile__(
+            ".set push\n"
+            ".set mips2\n"
+            "ll %0,%1\n"
+            ".set noreorder\n"
+            "bnez %0,1f\n"
+            "li %0,0\n" /* branch delay slot */
+            "li %0,1\n"
+            "sc %0,%1\n"
+            "1:\n"
+            ".set pop\n"
+            : "=r" (ret), "=m" (*p));
+#else
     __asm__ __volatile__ (
 	"	.set push		\n"
 	"	.set noat		\n"
@@ -484,6 +498,7 @@
 	: "=r" (ret), "+R" (*p)
 	:
 	: "memory");
+#endif
 
     return ret;
 }

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2007-07-31 20:49 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-05-05 19:23 [Qemu-devel] qemu Makefile.target cpu-all.h cpu-exec.c dynge Thiemo Seufer
2007-05-07 20:23 ` [Qemu-devel] [PATCH] " Stefan Weil
2007-05-07 20:27   ` Stefan Weil
2007-05-07 22:48   ` Johannes Schindelin
2007-05-09  0:02   ` Thiemo Seufer
2007-07-31 20:49     ` [Qemu-devel] [PATCH] QEMU Mips Host Stefan Weil
2007-05-09  0:17   ` [Qemu-devel] [PATCH] qemu Makefile.target cpu-all.h cpu-exec.c dynge Thiemo Seufer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.