From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.30) id 1B3hqK-000361-7I for qemu-devel@nongnu.org; Wed, 17 Mar 2004 15:40:48 -0500 Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.30) id 1B3hpl-0002ps-Gd for qemu-devel@nongnu.org; Wed, 17 Mar 2004 15:40:45 -0500 Received: from [213.191.74.84] (helo=mx2.ngi.de) by monty-python.gnu.org with esmtp (Exim 4.30) id 1B3hpk-0002oS-AR for qemu-devel@nongnu.org; Wed, 17 Mar 2004 15:40:12 -0500 Date: Wed, 17 Mar 2004 18:57:29 +0100 From: Richard Zidlicky Message-ID: <20040317175729.GA2562@linux-m68k.org> Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Subject: [Qemu-devel] [patch] m68k updates #1 Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Fabrice Bellard , Qemu ML 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 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) +