From nobody Fri May 10 05:44:14 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1560098741; cv=none; d=zoho.com; s=zohoarc; b=TMyZmWJfR+XHsbMiN0vYJFVZB+J+oYDtpA7talhICffnN3usJnio8arhKb7d8n1Xca557+OAP1pskDFCQaoxfHtAoOEySHVpk5hW5vjsh6xtflOOnJgpHKkWY79IO2pTINtelOi7w8U+1aZC97S7ZKLUJw1hi5raU0CHIUn1ju4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1560098741; h=Content-Type:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To:ARC-Authentication-Results; bh=DtPfPTWOQlo10DwlIQDI2mU54ew7piJpCaqIxGPpLWs=; b=k2UkRAcSkFC1yZfctYjjMzJSrdnMvBpt0URdaFg0TezZNrGxaf9VNp+tABPlerXyWHqH7/SehCJNCz2gfSWswf5L18PB8LfoDBCidOqV7dBrxYDxtLyGMumeXJytcD9jsPEZGYz0rWqg8tpY3BduHkT++K8ZImLjOe1bnr2eMKo= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1560098741923692.6658322774989; Sun, 9 Jun 2019 09:45:41 -0700 (PDT) Received: from localhost ([::1]:37038 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1ha0wu-0006nR-FC for importer@patchew.org; Sun, 09 Jun 2019 12:45:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:55094) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1ha0vG-0006ET-Hk for qemu-devel@nongnu.org; Sun, 09 Jun 2019 12:44:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ha0vD-0003na-IO for qemu-devel@nongnu.org; Sun, 09 Jun 2019 12:43:58 -0400 Received: from mail-pf1-x442.google.com ([2607:f8b0:4864:20::442]:43750) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ha0vD-0003mc-6c for qemu-devel@nongnu.org; Sun, 09 Jun 2019 12:43:55 -0400 Received: by mail-pf1-x442.google.com with SMTP id i189so3873549pfg.10 for ; Sun, 09 Jun 2019 09:43:55 -0700 (PDT) Received: from localhost.localdomain (i60-43-49-30.s30.a048.ap.plala.or.jp. [60.43.49.30]) by smtp.gmail.com with ESMTPSA id n35sm8553523pgl.44.2019.06.09.09.43.51 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Sun, 09 Jun 2019 09:43:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:subject:message-id:mime-version:content-disposition :user-agent; bh=DtPfPTWOQlo10DwlIQDI2mU54ew7piJpCaqIxGPpLWs=; b=W/wa8sM2EET8QPOcnEriu9Ehkcdc+F6QzgjUJbNfTIh+KDkfVjDFQr89N7WqJcwy12 suYCUq57Dfs+DtJoNtF7bQn3ar5eWvxlm+Pvmg2ISk6vP2LkxQJPK35vAnbXtmYBpo2n LYRb+DbV+q/NuFKDpKhnhadVs16KVRnePaG0+z4tbUqM9D4rIIcuVjXXd2dO0Eb1B35L j8/aEKslgMTL/eGr/TBwZt/4sk0xCrbd1BH7wtbS3h5i5kZYPb2Ogy1dpWKERmgB+6yD EGRzMm7kFnIyCIZ3BEwqeGzJQ/L+HhC7YcpKB0hVrNnryn7KIIRWtwxljmVzuAHOeRQC Wx3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition:user-agent; bh=DtPfPTWOQlo10DwlIQDI2mU54ew7piJpCaqIxGPpLWs=; b=Puq0S4PUTtfYSLd5z5HsOX3pqBOwOcsx2tfY+5VeSD+xPGDmsJDXVUojR9oJMera4i pE8p5BIIgx/+rHOktErkVJvhUrwXDOGyJ3qsIRUn7HwB0TNzvK97rRGS+ecBpO6+6EMa YinNuRJQNIKvTZxcYrznO0FnPshU12R2bDqAYIl1zEB4e5wJoBMlWn5uOqmNdhI0Vpyb JaiKNtX73RThuJeLzB0/6yln+2kHeSI2XQFUP0JQwRN7CgWRBewuQPZp4xt8VqEmAWo7 4YX0BYWn5Eai3fJBkZq1NJdrjrQCm7s9boELq7hOTl/DVqikWqWFBd1RuMbr9Pk67S5f vTOw== X-Gm-Message-State: APjAAAUrMrUtE+l/sXhZB6+WMDStodLvwXy5xraUQat1WiWPiMcT02nE CvlRTjiMNCzGoKE+2MMQy1mijvx1 X-Google-Smtp-Source: APXvYqz7P/Xz7Yg5VL5rqFVuSOn6RB+CIW0MiL7Uo2X3YTcwwtzgBSEu+IgSJ2+EssFhHKndUKwbiA== X-Received: by 2002:a62:b503:: with SMTP id y3mr68086392pfe.4.1560098633582; Sun, 09 Jun 2019 09:43:53 -0700 (PDT) Date: Mon, 10 Jun 2019 01:43:49 +0900 From: Lucien Murray-Pitts To: qemu-devel@nongnu.org, Laurent Vivier , Lucien Murray-Pitts Message-ID: <20190609164349.GA60211@localhost.localdomain> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.11.4 (2019-03-13) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::442 Subject: [Qemu-devel] [PATCH v2] Incorrect Stack Pointer shadow register support on some m68k CPUs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Brief overview; - Added "CPU class" m68k_feature to each CPU init so MOVEC can detect wrong CR (Control Register) access - Added cascaded "inheritance" of m68k_features by calling m680xx_cpu_initf= n() of previous CPU so that 68060 inherits 68040, and so on - Added comments above m680xx_cpu_initfn to identify additional supported features for that CPU class - Added more detailed comments, including CPU classes supported, to enum m68k_features - Added more detailed comments to each case of m68k_move_to/from helpers to list the supported CPUs for that CR - Added CPU class detection for each CR type, exits switch if unsupported - Added ILLEGAL INSTRUCITON exception condition when the helper fails to decode the CR - Moved abort only to handle unimplemented control registers, all other unknown CR will cause ILLEGAL instruciton - Fixed m68k_switch_sp so it switches only if MSP feature is implemented - Changed the MOVEC instruction in translate to be 68010 not 68000 - Added missing BUSCR/PCR CR defines, and decodes for helpers for the 68060 Long overview; The 68000 does not support the MOVEC instruction, it was added with the 680= 10. Futher on the 68010, and CPU32 the ISP doesnt exist. These CPUs only have SSP/USP. On supporting CPUs the SR register also implements a single bit, the "M" (master-mode) bit that determines which of the ISP/MSP is active at the tim= e. When not supported by the CPU the MOVEC instruction when accessing these shadow registers should issue an ILLEGAL INSTRUCTION exception. Futher this patch adds classes for each CPU family 680[012346] so that illegal access to specific control registers can be checked. Additional comments added to the features set to claify exactly what differentiates each class. (m68k_features) The helpers m68k_movec_to, and m68k_movec_from have been updated to support the exception ILLEGAL INSTRUCTION for all control registers that are illegal per CPU class, and for any unkown control register. Added defines for BUS, and Processor Configuration Register (PCR) for MC680= 60, and case statements in the helper for the missing Cache Address Register (C= AAR), and the new BUS, and PCR which results in a cpu abort (unimplemented). All other cases will result in an ILLEGAL INSTRUCTION exception as per the manual. Because the MSP support results in an illegal instruction exception if the wrong Control Register is accessed then it was necessary to know the CPU class in the MOVEC instruction. To do this a sizable overhaul of the CPU initialize funcitons was needed to add a feature showing the CPU class. So in the CPU classes the m680XX_cpu_initfn functions have been rearranged to cascade starting from the base 68000, so that the 68010 then inherits from this, and so on until the 68060. Because each cpu class inherits the previous CPU class, then for example the 68020 also has the feature 68010, and 68000 and so on upto the 68060. Added some more detailed comments to each cpu initialization function to make it clear the instructions added/changed for that CPU to make future debugging easier, and the reason for the feature flags more clear. These comments could go deeper into explaining supported/ehnaced modes, but this wasnt done in this patch. There are comments in the existing code referring to the EC/L/and-so-on classes, however no code has been implemented to handle these specific varitations of each CPU class, and so no m68k_feature was mde to distinguish them that way. Signed-off-by: Lucien Murray-Pitts --- Notes: v1->v2 - Submitted previous patch to fix existing non-compliant comment styl= e=20 - Added a comment about sp in CPUM68KState structure - updated movec in the same patch to issue exception - Reworked code in m68k_movec_from()/m68k_movec_to() because=20 as they trigger a cpu_abort() with unknown code,=20 - Above rework then required some additions for CPU class and so on. - Maybe this is becoming more of an RFC? / should be split for the re= work? Based-on: 20190606234125.GA4830@localhost.localdomain ([PATCH v2] m68k comments break patch submission due to being incorrectly f= ormatted) target/m68k/cpu.c | 112 ++++++++++++++---- target/m68k/cpu.h | 56 ++++++--- target/m68k/helper.c | 247 +++++++++++++++++++++++++++++++--------- target/m68k/translate.c | 4 +- 4 files changed, 326 insertions(+), 93 deletions(-) diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c index c144278661..09f3514715 100644 --- a/target/m68k/cpu.c +++ b/target/m68k/cpu.c @@ -42,6 +42,11 @@ static void m68k_set_feature(CPUM68KState *env, int feat= ure) env->features |=3D (1u << feature); } =20 +static void m68k_unset_feature(CPUM68KState *env, int feature) +{ + env->features &=3D (-1u - (1u << feature)); +} + /* CPUClass::reset() */ static void m68k_cpu_reset(CPUState *s) { @@ -104,6 +109,10 @@ static void m5206_cpu_initfn(Object *obj) m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); } =20 + +/* + * Base feature set, including isns. for m68k family + */ static void m68000_cpu_initfn(Object *obj) { M68kCPU *cpu =3D M68K_CPU(obj); @@ -115,14 +124,36 @@ static void m68000_cpu_initfn(Object *obj) m68k_set_feature(env, M68K_FEATURE_MOVEP); } =20 + +/* + * Adds BKPT, MOVE-from-SR *now priv instr, and MOVEC, MOVES, RTD + */ +static void m68010_cpu_initfn(Object *obj) +{ + M68kCPU *cpu =3D M68K_CPU(obj); + CPUM68KState *env =3D &cpu->env; + + m68000_cpu_initfn(obj); + m68k_set_feature(env, M68K_FEATURE_M68010); + m68k_set_feature(env, M68K_FEATURE_RTD); + m68k_set_feature(env, M68K_FEATURE_BKPT); + m68k_set_feature(env, M68K_FEATURE_MSP); +} + + +/* + * Adds BFCHG, BFCLR, BFEXTS, BFEXTU, BFFFO, BFINS, BFSET, BFTST, CAS, CAS= 2, + * CHK2, CMP2, DIVSL, DIVUL, EXTB, PACK, TRAPcc, UNPK. + * + * 68020/30 Only:CALLM, cpBcc, cpDBcc, cpGEN, cpRESTORE, cpSAVE, cpScc, cp= TRAPcc + */ static void m68020_cpu_initfn(Object *obj) { M68kCPU *cpu =3D M68K_CPU(obj); CPUM68KState *env =3D &cpu->env; =20 - m68k_set_feature(env, M68K_FEATURE_M68000); - m68k_set_feature(env, M68K_FEATURE_USP); - m68k_set_feature(env, M68K_FEATURE_WORD_INDEX); + m68010_cpu_initfn(obj); + m68k_set_feature(env, M68K_FEATURE_M68020); m68k_set_feature(env, M68K_FEATURE_QUAD_MULDIV); m68k_set_feature(env, M68K_FEATURE_BRAL); m68k_set_feature(env, M68K_FEATURE_BCCL); @@ -132,43 +163,79 @@ static void m68020_cpu_initfn(Object *obj) m68k_set_feature(env, M68K_FEATURE_LONG_MULDIV); m68k_set_feature(env, M68K_FEATURE_FPU); m68k_set_feature(env, M68K_FEATURE_CAS); - m68k_set_feature(env, M68K_FEATURE_BKPT); - m68k_set_feature(env, M68K_FEATURE_RTD); m68k_set_feature(env, M68K_FEATURE_CHK2); - m68k_set_feature(env, M68K_FEATURE_MOVEP); } -#define m68030_cpu_initfn m68020_cpu_initfn =20 -static void m68040_cpu_initfn(Object *obj) + +/* + * Adds: PFLUSH (*5) + * 68030 Only: PFLUSHA (*5), PLOAD (*5), PMOVE + * 68030/40 Only: PTEST + * + * NOTES: + * 5. Not valid on MC68EC030 + */ +static void m68030_cpu_initfn(Object *obj) { M68kCPU *cpu =3D M68K_CPU(obj); CPUM68KState *env =3D &cpu->env; =20 m68020_cpu_initfn(obj); + m68k_set_feature(env, M68K_FEATURE_M68030); +} + + +/* + * Adds: CINV, CPUSH + * Adds all with Note *2: FABS, FSABS, FDABS, FADD, FSADD, FDADD, FBcc, FC= MP, + * FDBcc, FDIV, FSDIV, FDDIV, FMOVE, FSMOVE, FDMOVE, + * FMOVEM, FMUL, FSMUL, FDMUL, FNEG, FSNEG, FDNEG, = FNOP, + * FRESTORE, FSAVE, FScc, FSQRT, FSSQRT, FDSQRT, FS= UB, + * FSSUB, FDSUB, FTRAPcc, FTST + * + * Adds with Notes *2, and *3: FACOS, FASIN, FATAN, FATANH, FCOS, FCOSH, F= ETOX, + * FETOXM, FGETEXP, FGETMAN, FINT, FINTRZ, FLO= G10, + * FLOG2, FLOGN, FLOGNP1, FMOD, FMOVECR, FREM, + * FSCALE, FSGLDIV, FSGLMUL, FSIN, FSINCOS, FS= INH, + * FTAN, FTANH, FTENTOX, FTWOTOX + * NOTES: + * 2. Not applicable to the MC68EC040, MC68LC040, MC68EC060, and MC68LC060. + * 3. These are software-supported instructions on the MC68040 and MC68060. + */ +static void m68040_cpu_initfn(Object *obj) +{ + M68kCPU *cpu =3D M68K_CPU(obj); + CPUM68KState *env =3D &cpu->env; + + m68030_cpu_initfn(obj); m68k_set_feature(env, M68K_FEATURE_M68040); } =20 + +/* + * Adds: PLPA + * Adds all with Note *2: CAS, CAS2, MULS, MULU, CHK2, CMP2, DIVS, DIVU + * All Fxxxx instructions are as per m68040 with exception to; FMOVEM NOTE3 + * + * Does NOT implement MOVEP + * + * NOTES: + * 2. Not applicable to the MC68EC040, MC68LC040, MC68EC060, and MC68LC060. + * 3. These are software-supported instructions on the MC68040 and MC68060. + */ static void m68060_cpu_initfn(Object *obj) { M68kCPU *cpu =3D M68K_CPU(obj); CPUM68KState *env =3D &cpu->env; =20 - m68k_set_feature(env, M68K_FEATURE_M68000); - m68k_set_feature(env, M68K_FEATURE_USP); - m68k_set_feature(env, M68K_FEATURE_WORD_INDEX); - m68k_set_feature(env, M68K_FEATURE_BRAL); - m68k_set_feature(env, M68K_FEATURE_BCCL); - m68k_set_feature(env, M68K_FEATURE_BITFIELD); - m68k_set_feature(env, M68K_FEATURE_EXT_FULL); - m68k_set_feature(env, M68K_FEATURE_SCALED_INDEX); - m68k_set_feature(env, M68K_FEATURE_LONG_MULDIV); - m68k_set_feature(env, M68K_FEATURE_FPU); - m68k_set_feature(env, M68K_FEATURE_CAS); - m68k_set_feature(env, M68K_FEATURE_BKPT); - m68k_set_feature(env, M68K_FEATURE_RTD); - m68k_set_feature(env, M68K_FEATURE_CHK2); + m68040_cpu_initfn(obj); + m68k_unset_feature(env, M68K_FEATURE_MOVEP); + + /* Implemented as a software feature */ + m68k_unset_feature(env, M68K_FEATURE_QUAD_MULDIV); } =20 + static void m5208_cpu_initfn(Object *obj) { M68kCPU *cpu =3D M68K_CPU(obj); @@ -303,6 +370,7 @@ static const TypeInfo m68k_cpus_type_infos[] =3D { .class_init =3D m68k_cpu_class_init, }, DEFINE_M68K_CPU_TYPE("m68000", m68000_cpu_initfn), + DEFINE_M68K_CPU_TYPE("m68010", m68010_cpu_initfn), DEFINE_M68K_CPU_TYPE("m68020", m68020_cpu_initfn), DEFINE_M68K_CPU_TYPE("m68030", m68030_cpu_initfn), DEFINE_M68K_CPU_TYPE("m68040", m68040_cpu_initfn), diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index 3c4d7de017..7a8e4872e2 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -93,7 +93,13 @@ typedef struct CPUM68KState { uint32_t pc; uint32_t sr; =20 - /* SSP and USP. The current_sp is stored in aregs[7], the other here.= */ + /* + * The 68020/30/40 support two supervisor stacks, ISP and MSP. + * The 68000/10, Coldfire, and CPU32 only have USP/SSP. + * + * The current_sp is stored in aregs[7], the other here. + * The USP, SSP, and if used the additional ISP for 68020/30/40. + */ int current_sp; uint32_t sp[3]; =20 @@ -411,6 +417,10 @@ typedef enum { #define M68K_CR_DACR0 0x006 #define M68K_CR_DACR1 0x007 =20 +/* MC68060 */ +#define M68K_CR_BUSCR 0x008 +#define M68K_CR_PCR 0x808 + #define M68K_FPIAR_SHIFT 0 #define M68K_FPIAR (1 << M68K_FPIAR_SHIFT) #define M68K_FPSR_SHIFT 1 @@ -468,36 +478,50 @@ void m68k_switch_sp(CPUM68KState *env); void do_m68k_semihosting(CPUM68KState *env, int nr); =20 /* + * The 68000 family is defined in six main CPU classes, the 680[012346]0. + * Generally each successive CPU adds enhanced data/stack/instructions. + * However, some features are only common to one, or a few classes. + * The features covers those subsets of instructons. + * + * CPU32/32+ are basically 680010 compatible with some 68020 class instruc= tons, + * and some additional CPU32 instructions. Mostly Supervisor state differe= nces. + * + * The ColdFire core ISA is a RISC-style reduction of the 68000 series cpu. * There are 4 ColdFire core ISA revisions: A, A+, B and C. * Each feature covers the subset of instructions common to the * ISA revisions mentioned. */ =20 enum m68k_features { - M68K_FEATURE_M68000, - M68K_FEATURE_CF_ISA_A, + M68K_FEATURE_M68000, /* Base m68k instruction set */ + M68K_FEATURE_M68010, /* Additional insn. specific to MC68010 */ + M68K_FEATURE_M68020, /* Additional insn. specific to MC68020 */ + M68K_FEATURE_M68030, /* Additional insn. specific to MC68030 */ + M68K_FEATURE_M68040, /* Additional insn. specific to MC68040 */ + M68K_FEATURE_M68060, /* Additional insn. specific to MC68060 */ + M68K_FEATURE_CF_ISA_A, /* Base Coldfire set Rev A. */ M68K_FEATURE_CF_ISA_B, /* (ISA B or C). */ M68K_FEATURE_CF_ISA_APLUSC, /* BIT/BITREV, FF1, STRLDSR (ISA A+ or C).= */ - M68K_FEATURE_BRAL, /* Long unconditional branch. (ISA A+ or B). */ + M68K_FEATURE_BRAL, /* BRA with Long branch. (680[2346]0, ISA A+ or B)= . */ M68K_FEATURE_CF_FPU, M68K_FEATURE_CF_MAC, M68K_FEATURE_CF_EMAC, M68K_FEATURE_CF_EMAC_B, /* Revision B EMAC (dual accumulate). */ - M68K_FEATURE_USP, /* User Stack Pointer. (ISA A+, B or C). */ + M68K_FEATURE_USP, /* User Stack Pointer. (680[012346]0, ISA A+, B or C= ).*/ + M68K_FEATURE_MSP, /* Master Stack Pointer. (680[234]0) */ M68K_FEATURE_EXT_FULL, /* 68020+ full extension word. */ M68K_FEATURE_WORD_INDEX, /* word sized address index registers. */ M68K_FEATURE_SCALED_INDEX, /* scaled address index registers. */ - M68K_FEATURE_LONG_MULDIV, /* 32 bit multiply/divide. */ - M68K_FEATURE_QUAD_MULDIV, /* 64 bit multiply/divide. */ - M68K_FEATURE_BCCL, /* Long conditional branches. */ - M68K_FEATURE_BITFIELD, /* Bit field insns. */ - M68K_FEATURE_FPU, - M68K_FEATURE_CAS, - M68K_FEATURE_BKPT, - M68K_FEATURE_RTD, - M68K_FEATURE_CHK2, - M68K_FEATURE_M68040, /* instructions specific to MC68040 */ - M68K_FEATURE_MOVEP, + M68K_FEATURE_LONG_MULDIV, /* 32 bit mul/div. (680[2346]0, and CPU32) */ + M68K_FEATURE_QUAD_MULDIV, /* 64 bit mul/div. (680[2346]0, and CPU32) */ + M68K_FEATURE_BCCL, /* Bcc with Long branches. (680[2346]0, and CPU32) = */ + M68K_FEATURE_BITFIELD, /* BFxxx Bit field insns. (680[2346]0) */ + M68K_FEATURE_FPU, /* fpu insn. (680[46]0) */ + M68K_FEATURE_CAS, /* CAS/CAS2[WL] insns. (680[2346]0) */ + M68K_FEATURE_BKPT,/* BKPT insn. (680[12346]0, and CPU32) */ + M68K_FEATURE_RTD, /* RTD insn. (680[12346]0, and CPU32) */ + M68K_FEATURE_CHK2,/* CHL2 insn. (680[2346]0, and CPU32) */ + M68K_FEATURE_MOVEP,/* MOVEP insn. (680[01234]0, and CPU32) */ }; =20 static inline int m68k_feature(CPUM68KState *env, int feature) diff --git a/target/m68k/helper.c b/target/m68k/helper.c index b0bb579403..0661723aac 100644 --- a/target/m68k/helper.c +++ b/target/m68k/helper.c @@ -192,64 +192,138 @@ void HELPER(cf_movec_to)(CPUM68KState *env, uint32_t= reg, uint32_t val) } } =20 + + +static void raise_exception_ra(CPUM68KState *env, int tt, uintptr_t raddr) +{ + CPUState *cs =3D CPU(m68k_env_get_cpu(env)); + + cs->exception_index =3D tt; + cpu_loop_exit_restore(cs, raddr); +} + void HELPER(m68k_movec_to)(CPUM68KState *env, uint32_t reg, uint32_t val) { M68kCPU *cpu =3D m68k_env_get_cpu(env); =20 switch (reg) { - /* MC680[1234]0 */ + /* MC680[12346]0 */ case M68K_CR_SFC: env->sfc =3D val & 7; return; + /* MC680[12346]0 */ case M68K_CR_DFC: env->dfc =3D val & 7; return; + /* MC680[12346]0 */ case M68K_CR_VBR: env->vbr =3D val; return; - /* MC680[234]0 */ + /* MC680[2346]0 */ case M68K_CR_CACR: - env->cacr =3D val; - m68k_switch_sp(env); - return; - /* MC680[34]0 */ + if (m68k_feature(env, M68K_FEATURE_M68020) + || m68k_feature(env, M68K_FEATURE_M68030) + || m68k_feature(env, M68K_FEATURE_M68040) + || m68k_feature(env, M68K_FEATURE_M68060)) { + env->cacr =3D val; + m68k_switch_sp(env); + return; + } + break; + /* MC680[46]0 */ case M68K_CR_TC: - env->mmu.tcr =3D val; - return; + if (m68k_feature(env, M68K_FEATURE_M68040) + || m68k_feature(env, M68K_FEATURE_M68060)) { + env->mmu.tcr =3D val; + return; + } + break; + /* MC680[4]0 */ case M68K_CR_MMUSR: - env->mmu.mmusr =3D val; - return; + if (m68k_feature(env, M68K_FEATURE_M68040)) { + env->mmu.mmusr =3D val; + return; + } + break; + /* MC680[46]0 */ case M68K_CR_SRP: - env->mmu.srp =3D val; - return; + if (m68k_feature(env, M68K_FEATURE_M68040) + || m68k_feature(env, M68K_FEATURE_M68060)) { + env->mmu.srp =3D val; + return; + } + break; + /* MC680[46]0 */ case M68K_CR_URP: - env->mmu.urp =3D val; - return; + if (m68k_feature(env, M68K_FEATURE_M68040) + || m68k_feature(env, M68K_FEATURE_M68060)) { + env->mmu.urp =3D val; + return; + } + break; + /* MC680[12346]0 */ case M68K_CR_USP: env->sp[M68K_USP] =3D val; return; + /* MC680[234]0 */ case M68K_CR_MSP: - env->sp[M68K_SSP] =3D val; - return; + if (m68k_feature(env, M68K_FEATURE_M68020) + || m68k_feature(env, M68K_FEATURE_M68030) + || m68k_feature(env, M68K_FEATURE_M68040)) { + env->sp[M68K_SSP] =3D val; + return; + } + break; + /* MC680[234]0 */ case M68K_CR_ISP: - env->sp[M68K_ISP] =3D val; - return; + if (m68k_feature(env, M68K_FEATURE_M68020) + || m68k_feature(env, M68K_FEATURE_M68030) + || m68k_feature(env, M68K_FEATURE_M68040)) { + env->sp[M68K_ISP] =3D val; + return; + } + break; /* MC68040/MC68LC040 */ - case M68K_CR_ITT0: - env->mmu.ttr[M68K_ITTR0] =3D val; - return; - case M68K_CR_ITT1: - env->mmu.ttr[M68K_ITTR1] =3D val; - return; - case M68K_CR_DTT0: - env->mmu.ttr[M68K_DTTR0] =3D val; - return; - case M68K_CR_DTT1: - env->mmu.ttr[M68K_DTTR1] =3D val; + case M68K_CR_ITT0: /* MC68EC040 only: M68K_CR_IACR0 */ + if (m68k_feature(env, M68K_FEATURE_M68040)) { + env->mmu.ttr[M68K_ITTR0] =3D val; + return; + } + break; + /* MC68040/MC68LC040 */ + case M68K_CR_ITT1: /* MC68EC040 only: M68K_CR_IACR1 */ + if (m68k_feature(env, M68K_FEATURE_M68040)) { + env->mmu.ttr[M68K_ITTR1] =3D val; + return; + } + break; + /* MC68040/MC68LC040 */ + case M68K_CR_DTT0: /* MC68EC040 only: M68K_CR_DACR0 */ + if (m68k_feature(env, M68K_FEATURE_M68040)) { + env->mmu.ttr[M68K_DTTR0] =3D val; + return; + } + break; + /* MC68040/MC68LC040 */ + case M68K_CR_DTT1: /* MC68EC040 only: M68K_CR_DACR1 */ + if (m68k_feature(env, M68K_FEATURE_M68040)) { + env->mmu.ttr[M68K_DTTR1] =3D val; + return; + } + break; + /* Unimplemented Registers */ + case M68K_CR_CAAR: + case M68K_CR_PCR: + case M68K_CR_BUSCR: + cpu_abort(CPU(cpu), + "Unimplemented control register write 0x%x =3D 0x%x\n", + reg, val); return; } - cpu_abort(CPU(cpu), "Unimplemented control register write 0x%x =3D 0x%= x\n", - reg, val); + + /* Invalid control registers will generate an exception. */ + raise_exception_ra(env, EXCP_ILLEGAL, 0); + return; } =20 uint32_t HELPER(m68k_movec_from)(CPUM68KState *env, uint32_t reg) @@ -257,43 +331,107 @@ uint32_t HELPER(m68k_movec_from)(CPUM68KState *env, = uint32_t reg) M68kCPU *cpu =3D m68k_env_get_cpu(env); =20 switch (reg) { - /* MC680[1234]0 */ + /* MC680[12346]0 */ case M68K_CR_SFC: return env->sfc; + /* MC680[12346]0 */ case M68K_CR_DFC: return env->dfc; + /* MC680[12346]0 */ case M68K_CR_VBR: return env->vbr; - /* MC680[234]0 */ + /* MC680[2346]0 */ case M68K_CR_CACR: - return env->cacr; - /* MC680[34]0 */ + if (m68k_feature(env, M68K_FEATURE_M68020) + || m68k_feature(env, M68K_FEATURE_M68030) + || m68k_feature(env, M68K_FEATURE_M68040) + || m68k_feature(env, M68K_FEATURE_M68060)) { + return env->cacr; + } + break; + /* MC680[46]0 */ case M68K_CR_TC: - return env->mmu.tcr; + if (m68k_feature(env, M68K_FEATURE_M68040) + || m68k_feature(env, M68K_FEATURE_M68060)) { + return env->mmu.tcr; + } + break; + /* MC680[4]0 */ case M68K_CR_MMUSR: - return env->mmu.mmusr; + if (m68k_feature(env, M68K_FEATURE_M68040)) { + return env->mmu.mmusr; + } + break; + /* MC680[46]0 */ case M68K_CR_SRP: - return env->mmu.srp; + if (m68k_feature(env, M68K_FEATURE_M68040) + || m68k_feature(env, M68K_FEATURE_M68060)) { + return env->mmu.srp; + } + break; + /* MC68040/MC68LC040 */ + case M68K_CR_URP: + if (m68k_feature(env, M68K_FEATURE_M68040) + || m68k_feature(env, M68K_FEATURE_M68060)) { + return env->mmu.urp; + } + break; + /* MC680[46]0 */ case M68K_CR_USP: return env->sp[M68K_USP]; + /* MC680[234]0 */ case M68K_CR_MSP: - return env->sp[M68K_SSP]; + if (m68k_feature(env, M68K_FEATURE_M68020) + || m68k_feature(env, M68K_FEATURE_M68030) + || m68k_feature(env, M68K_FEATURE_M68040)) { + return env->sp[M68K_SSP]; + } + break; + /* MC680[234]0 */ case M68K_CR_ISP: - return env->sp[M68K_ISP]; + if (m68k_feature(env, M68K_FEATURE_M68020) + || m68k_feature(env, M68K_FEATURE_M68030) + || m68k_feature(env, M68K_FEATURE_M68040)) { + return env->sp[M68K_ISP]; + } + break; /* MC68040/MC68LC040 */ - case M68K_CR_URP: - return env->mmu.urp; - case M68K_CR_ITT0: - return env->mmu.ttr[M68K_ITTR0]; - case M68K_CR_ITT1: - return env->mmu.ttr[M68K_ITTR1]; - case M68K_CR_DTT0: - return env->mmu.ttr[M68K_DTTR0]; - case M68K_CR_DTT1: - return env->mmu.ttr[M68K_DTTR1]; - } - cpu_abort(CPU(cpu), "Unimplemented control register read 0x%x\n", - reg); + case M68K_CR_ITT0: /* MC68EC040 only: M68K_CR_IACR0 */ + if (m68k_feature(env, M68K_FEATURE_M68040)) { + return env->mmu.ttr[M68K_ITTR0]; + } + break; + /* MC68040/MC68LC040 */ + case M68K_CR_ITT1: /* MC68EC040 only: M68K_CR_IACR1 */ + if (m68k_feature(env, M68K_FEATURE_M68040)) { + return env->mmu.ttr[M68K_ITTR1]; + } + break; + /* MC68040/MC68LC040 */ + case M68K_CR_DTT0: /* MC68EC040 only: M68K_CR_DACR0 */ + if (m68k_feature(env, M68K_FEATURE_M68040)) { + return env->mmu.ttr[M68K_DTTR0]; + } + break; + /* MC68040/MC68LC040 */ + case M68K_CR_DTT1: /* MC68EC040 only: M68K_CR_DACR1 */ + if (m68k_feature(env, M68K_FEATURE_M68040)) { + return env->mmu.ttr[M68K_DTTR1]; + } + break; + /* Unimplemented Registers */ + case M68K_CR_CAAR: + case M68K_CR_PCR: + case M68K_CR_BUSCR: + cpu_abort(CPU(cpu), "Unimplemented control register read 0x%x\n", + reg); + return 0; + } + + /* Invalid control registers will generate an exception. */ + raise_exception_ra(env, EXCP_ILLEGAL, 0); + + return 0; } =20 void HELPER(set_macsr)(CPUM68KState *env, uint32_t val) @@ -337,7 +475,8 @@ void m68k_switch_sp(CPUM68KState *env) env->sp[env->current_sp] =3D env->aregs[7]; if (m68k_feature(env, M68K_FEATURE_M68000)) { if (env->sr & SR_S) { - if (env->sr & SR_M) { + /* SR:Master-Mode bit unimplemented then ISP is not available = */ + if (!m68k_feature(env, M68K_FEATURE_MSP) || env->sr & SR_M) { new_sp =3D M68K_SSP; } else { new_sp =3D M68K_ISP; diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 9b0ca4c14c..7a5da254dd 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -4753,6 +4753,8 @@ DISAS_INSN(m68k_movec) } else { reg =3D DREG(ext, 12); } + + /* Decode ctrl reg field, issues exception if the cpu doesnt support i= t */ if (insn & 1) { gen_helper_m68k_movec_to(cpu_env, tcg_const_i32(ext & 0xfff), reg); } else { @@ -5990,7 +5992,7 @@ void register_m68k_insns (CPUM68KState *env) BASE(stop, 4e72, ffff); BASE(rte, 4e73, ffff); INSN(cf_movec, 4e7b, ffff, CF_ISA_A); - INSN(m68k_movec, 4e7a, fffe, M68000); + INSN(m68k_movec, 4e7a, fffe, M68010); #endif BASE(nop, 4e71, ffff); INSN(rtd, 4e74, ffff, RTD); --=20 2.21.0