qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [patch] m68k updates #1


From: Richard Zidlicky
Subject: [Qemu-devel] [patch] m68k updates #1
Date: Wed, 17 Mar 2004 18:57:29 +0100
User-agent: Mutt/1.4i

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


diff -urN qemu-cvs/cpu-exec.c qemu-cvs-new/cpu-exec.c
--- qemu-cvs/cpu-exec.c Fri Mar  5 14:53:07 2004
+++ qemu-cvs-new/cpu-exec.c     Wed Mar 17 18:41:40 2004
@@ -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


diff -urN qemu-cvs/dyngen.h qemu-cvs-new/dyngen.h
--- qemu-cvs/dyngen.h   Fri Mar  5 14:53:07 2004
+++ qemu-cvs-new/dyngen.h       Wed Mar 17 18:35:57 2004
@@ -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
 


diff -urN qemu-cvs/l68k.h qemu-cvs-new/l68k.h
--- qemu-cvs/l68k.h     Thu Jan  1 01:00:00 1970
+++ qemu-cvs-new/l68k.h Wed Mar 17 18:47:12 2004
@@ -0,0 +1,206 @@
+/*
+ * m68k expcetion frame formats, mostly copied together from various
+ * Linux kernel include files.
+ */
+
+typedef union {
+    struct {
+      unsigned long  iaddr;    /* instruction address */
+    } fmt2;
+    struct {
+      unsigned long  effaddr;  /* effective address */
+    } fmt3;
+    struct {
+      unsigned long  effaddr;  /* effective address */
+      unsigned long  pc;       /* fslw or pc of faulted instr */
+    } fmt4;
+    struct {
+      unsigned long  effaddr;  /* effective address */
+      unsigned short ssw;      /* special status word */
+      unsigned short wb3s;     /* write back 3 status */
+      unsigned short wb2s;     /* write back 2 status */
+      unsigned short wb1s;     /* write back 1 status */
+      unsigned long  faddr;    /* fault address */
+      unsigned long  wb3a;     /* write back 3 address */
+      unsigned long  wb3d;     /* write back 3 data */
+      unsigned long  wb2a;     /* write back 2 address */
+      unsigned long  wb2d;     /* write back 2 data */
+      unsigned long  wb1a;     /* write back 1 address */
+      unsigned long  wb1dpd0;  /* write back 1 data/push data 0*/
+      unsigned long  pd1;      /* push data 1*/
+      unsigned long  pd2;      /* push data 2*/
+      unsigned long  pd3;      /* push data 3*/
+    } fmt7;
+    struct {
+      unsigned long  iaddr;    /* instruction address */
+      unsigned short int1[4];  /* internal registers */
+    } fmt9;
+    struct {
+      unsigned short int1;
+      unsigned short ssw;      /* special status word */
+      unsigned short isc;      /* instruction stage c */
+      unsigned short isb;      /* instruction stage b */
+      unsigned long  daddr;    /* data cycle fault address */
+      unsigned short int2[2];
+      unsigned long  dobuf;    /* data cycle output buffer */
+      unsigned short int3[2];
+    } fmta;
+    struct {
+      unsigned short int1;
+      unsigned short ssw;      /* special status word */
+      unsigned short isc;      /* instruction stage c */
+      unsigned short isb;      /* instruction stage b */
+      unsigned long  daddr;    /* data cycle fault address */
+      unsigned short int2[2];
+      unsigned long  dobuf;    /* data cycle output buffer */
+      unsigned short int3[4];
+      unsigned long  baddr;    /* stage B address */
+      unsigned short int4[2];
+      unsigned long  dibuf;    /* data cycle input buffer */
+      unsigned short int5[3];
+      unsigned    ver : 4;     /* stack frame version # */
+      unsigned    int6:12;
+      unsigned short int7[18];
+    } fmtb;
+} Frame;
+
+
+
+#ifndef _ASM_M68k_SIGCONTEXT_H
+#define _ASM_M68k_SIGCONTEXT_H
+
+struct sigcontext {
+       unsigned long  sc_mask;         /* old sigmask */
+       unsigned long  sc_usp;          /* old user stack pointer */
+       unsigned long  sc_d0;
+       unsigned long  sc_d1;
+       unsigned long  sc_a0;
+       unsigned long  sc_a1;
+       unsigned short sc_sr;
+       unsigned long  sc_pc;
+       unsigned short sc_formatvec;
+       unsigned long  sc_fpregs[2*3];  /* room for two fp registers */
+       unsigned long  sc_fpcntl[3];
+       unsigned char  sc_fpstate[216];
+};
+#endif
+
+
+
+#ifndef MUCONTEXT_H
+#define MUCONTEXT_H
+
+typedef int greg_t;
+#define NGREG 18
+typedef greg_t gregset_t[NGREG];
+
+typedef struct Mfpregset {
+       int f_pcr;
+       int f_psr;
+       int f_fpiaddr;
+       int f_fpregs[8][3];
+} Mfpregset_t;
+
+struct mcontext {
+       int version;
+       gregset_t gregs;
+       fpregset_t fpregs;
+};
+
+#define MCONTEXT_VERSION 2
+
+struct Mucontext {
+       unsigned long     uc_flags;
+       struct ucontext  *uc_link;
+       stack_t           uc_stack;
+       struct mcontext   uc_mcontext;
+       unsigned long     uc_filler[80];
+       sigset_t          uc_sigmask;   /* mask last for extensibility */
+};
+
+#define FPCONTEXT_SIZE 216
+#define uc_formatvec   uc_filler[FPCONTEXT_SIZE/4]
+#define uc_extra       uc_filler[FPCONTEXT_SIZE/4+1]
+
+
+#endif
+
+/* bits for 68040 special status word */
+#define CP_040 (0x8000)
+#define CU_040 (0x4000)
+#define CT_040 (0x2000)
+#define CM_040 (0x1000)
+#define MA_040 (0x0800)
+#define ATC_040 (0x0400)
+#define LK_040 (0x0200)
+#define RW_040 (0x0100)
+#define SIZ_040 (0x0060)
+#define TT_040 (0x0018)
+#define TM_040 (0x0007)
+
+/* bits for 68040 write back status word */
+#define WBV_040   (0x80)
+#define WBSIZ_040 (0x60)
+#define WBBYT_040 (0x20)
+#define WBWRD_040 (0x40)
+#define WBLNG_040 (0x00)
+#define WBTT_040  (0x18)
+#define WBTM_040  (0x07)
+
+/* bus access size codes */
+#define BA_SIZE_BYTE    (0x20)
+#define BA_SIZE_WORD    (0x40)
+#define BA_SIZE_LONG    (0x00)
+#define BA_SIZE_LINE    (0x60)
+
+/* bus access transfer type codes */
+#define BA_TT_MOVE16    (0x08)
+
+/* bits for 68040 MMU status register (mmusr) */
+#define MMU_B_040   (0x0800)
+#define MMU_G_040   (0x0400)
+#define MMU_S_040   (0x0080)
+#define MMU_CM_040  (0x0060)
+#define MMU_M_040   (0x0010)
+#define MMU_WP_040  (0x0004)
+#define MMU_T_040   (0x0002)
+#define MMU_R_040   (0x0001)
+
+/* bits in the 68060 fault status long word (FSLW) */
+#define        MMU060_MA       (0x08000000)    /* misaligned */
+#define        MMU060_LK       (0x02000000)    /* locked transfer */
+#define        MMU060_RW       (0x01800000)    /* read/write */
+# define MMU060_RW_W   (0x00800000)    /* write */
+# define MMU060_RW_R   (0x01000000)    /* read */
+# define MMU060_RW_RMW (0x01800000)    /* read/modify/write */
+# define MMU060_W              (0x00800000)    /* general write, includes rmw 
*/
+#define        MMU060_SIZ      (0x00600000)    /* transfer size */
+#define        MMU060_TT       (0x00180000)    /* transfer type (TT) bits */
+#define        MMU060_TM       (0x00070000)    /* transfer modifier (TM) bits 
*/
+#define        MMU060_IO       (0x00008000)    /* instruction or operand */
+#define        MMU060_PBE      (0x00004000)    /* push buffer bus error */
+#define        MMU060_SBE      (0x00002000)    /* store buffer bus error */
+#define        MMU060_PTA      (0x00001000)    /* pointer A fault */
+#define        MMU060_PTB      (0x00000800)    /* pointer B fault */
+#define        MMU060_IL       (0x00000400)    /* double indirect descr fault 
*/
+#define        MMU060_PF       (0x00000200)    /* page fault (invalid descr) */
+#define        MMU060_SP       (0x00000100)    /* supervisor protection */
+#define        MMU060_WP       (0x00000080)    /* write protection */
+#define        MMU060_TWE      (0x00000040)    /* bus error on table search */
+#define        MMU060_RE       (0x00000020)    /* bus error on read */
+#define        MMU060_WE       (0x00000010)    /* bus error on write */
+#define        MMU060_TTR      (0x00000008)    /* error caused by TTR 
translation */
+#define        MMU060_BPE      (0x00000004)    /* branch prediction error */
+#define        MMU060_SEE      (0x00000001)    /* software emulated error */
+
+/* cases of missing or invalid descriptors */
+#define MMU060_DESC_ERR        (MMU060_TWE | MMU060_PTA | MMU060_PTB | \
+                                                MMU060_IL  | MMU060_PF)
+/* bits that indicate real errors */
+#define MMU060_ERR_BITS        (MMU060_PBE | MMU060_SBE | MMU060_DESC_ERR | \
+                                                MMU060_SP  | MMU060_WP  | 
MMU060_RE | \
+                                                MMU060_WE)
+
+#define PAGEX(addr) (4096*(addr))
+#define PAGEI(addr) ((addr)/4096)
+




reply via email to

[Prev in Thread] Current Thread [Next in Thread]