qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Weil <weil@mail.berlios.de>
To: QEMU Developers <qemu-devel@nongnu.org>
Subject: [Qemu-devel] [PATCH] QEMU Mips Host
Date: Tue, 31 Jul 2007 22:49:23 +0200	[thread overview]
Message-ID: <46AFA053.6000004@mail.berlios.de> (raw)
In-Reply-To: <20070509000204.GC13638@networkno.de>

[-- 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;
 }

  reply	other threads:[~2007-07-31 20:49 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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     ` Stefan Weil [this message]
2007-05-09  0:17   ` Thiemo Seufer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=46AFA053.6000004@mail.berlios.de \
    --to=weil@mail.berlios.de \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).