[Top][All Lists]
[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)
+
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [patch] m68k updates #1,
Richard Zidlicky <=