Skip to contentSkip to conversation

m68k updates #1

PATCH New Richard Zidlicky 1 participant 1 message Mar 17, 2004

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 m68k updates #1

Hi Fabrice,

this patch iproves signal and cache handling on m68k. Finally solved the issue with SA_SIGINFO on m68k, glibc defines ucontext differently than the kernel does it.

Richard

cpu-exec.c +45 -12
diff -urN qemu-cvs/cpu-exec.c qemu-cvs-new/cpu-exec.c
@@ -890,19 +890,52 @@
 
 #elif defined(__mc68000)
 
-int cpu_signal_handler(int host_signum, struct siginfo *info, 
-                       void *puc)
+#include "l68k.h"
+
+int cpu_signal_handler(int signr, struct siginfo *info, void *xx)
 {
-    struct ucontext *uc = puc;
-    unsigned long pc;
-    int is_write;
-    
-    pc = uc->uc_mcontext.gregs[16];
-    /* XXX: compute is_write */
-    is_write = 0;
-    return handle_cpu_signal(pc, (unsigned long)info->si_addr, 
-                             is_write,
-                             &uc->uc_sigmask, puc);
+  struct Mucontext *puc=xx;
+  int format=((puc->uc_formatvec)>>12)&0xf;
+  unsigned long ea,is_write;
+  Frame *framedata = &(puc->uc_extra);
+
+#ifdef TEST_SEGV
+  printf("exception vec %d, fmt %d\n",vecnum,format);
+#endif
+  switch (format)
+    {
+      case 4: ea=framedata->fmt4.effaddr;
+	if ( (framedata->fmt4.pc) & MMU060_MA)
+	  ea=PAGEX(PAGEI(ea+4));
+	is_write = (((framedata->fmt4.pc) & MMU060_RW) == MMU060_RW_W) ||
+	  (((framedata->fmt4.pc) & MMU060_MA) == MMU060_RW_RMW );
+	break;
+      case 7: ea=framedata->fmt7.faddr;
+	is_write = (framedata->fmt7.ssw&RW_040) != 0;
+#ifdef TEST_SEGV
+       printf("segv: ssw=%x, faddr= %x, \n\twb2s=%x, wb2a=%x, wb3s=%x, wb3a=%d\n"
+              "MA=%x, RW=%x\n ",
+	      framedata->fmt7.ssw, framedata->fmt7.faddr,
+	      framedata->fmt7.wb2s, framedata->fmt7.wb2a,
+	      framedata->fmt7.wb3s, framedata->fmt7.wb3a,
+	      framedata->fmt7.ssw&MA_040, framedata->fmt7.ssw&RW_040
+	      );
+#endif
+	 if (framedata->fmt7.ssw&MA_040) {
+	     ea=PAGEX(PAGEI(ea+4));
+	     /*printf("MA set\n");*/
+	       }
+       break;
+      case 0xa: ea=framedata->fmta.daddr; break;
+      case 0xb: ea=framedata->fmtb.daddr; break;
+    default:
+      printf("illegal exception format\n");
+      exit(1);
+    }
+
+  return handle_cpu_signal(puc->uc_mcontext.gregs[16], ea,
+			   is_write,
+			   &(puc->uc_sigmask), xx);
 }
 
 #else
dyngen.h +4 -1
diff -urN qemu-cvs/dyngen.h qemu-cvs-new/dyngen.h
@@ -98,7 +98,10 @@
 #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);
+    unsigned long _start=(start>>4)<<4;
+    unsigned long _stop=((stop+15)>>4)<<4;
+
+    cacheflush(_start,FLUSH_SCOPE_LINE,FLUSH_CACHE_BOTH,_stop-_start);
 }
 #endif
 
l68k.h +206 -0

206 lines not on this page · raw message