From nobody Tue Oct 28 12:15:22 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1514936907631567.4450237222738; Tue, 2 Jan 2018 15:48:27 -0800 (PST) Received: from localhost ([::1]:59640 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eWWID-0004H5-QS for importer@patchew.org; Tue, 02 Jan 2018 18:48:25 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52320) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eWWBN-00073U-OX for qemu-devel@nongnu.org; Tue, 02 Jan 2018 18:41:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eWWBM-00037F-85 for qemu-devel@nongnu.org; Tue, 02 Jan 2018 18:41:21 -0500 Received: from mout.kundenserver.de ([212.227.126.135]:61048) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eWWBL-00036Q-TH for qemu-devel@nongnu.org; Tue, 02 Jan 2018 18:41:20 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue005 [212.227.15.167]) with ESMTPSA (Nemesis) id 0M9tYC-1ed8xZ1qYa-00B365; Wed, 03 Jan 2018 00:41:17 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Wed, 3 Jan 2018 00:40:57 +0100 Message-Id: <20180102234108.32713-7-laurent@vivier.eu> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180102234108.32713-1-laurent@vivier.eu> References: <20180102234108.32713-1-laurent@vivier.eu> X-Provags-ID: V03:K0:k7zpQhC7ZtlKKec4qsHTxV2iwzgo6rzwbII2aM7asieRodzx0aU mQPQKVQk4LyNmfOPKhrqHvb2q0jRubkjDedwlMx0q7A+NSMYeb6GqZDXFzwefbe9/SXtlUK 69Ba2m3Dl+q9vKaNzR5923sRGG0zpt0iAG6/wibotUJ4701+9uCSR78T+k6+0PXp0vegDkS XVjlBxvhmZzGMHWegNTCw== X-UI-Out-Filterresults: notjunk:1;V01:K0:jS+UR0MGPgY=:N+0wy2aOYPrAvgr/Wa/3uQ DeUtzrTjYBD6GcmlgUlg5Sim7IFZw++n1Wf7Rc5d5fnqLNYDfrIpB3FfW1fxaxwxea/9fISl/ OxNAYJpc/gpfEusbXy915f7YwYHEfkJKKLPKgJE6nyumQIgUmRI0nv/AHVRGvPtRzKxQG4jeo R1HTUIfSeXnLv5A7Y6Srid8Q2QmPBbepiim2Ecs/UhMCyYCx0LW8aoM1U+IRCqLk8sT2K5Npk 11itBBikJG6uQTlVQAimwmL+UBadjx5OKOcT4+1E8yZ7u5Sjp9dRzfer81vGBUOc/zJal0jJT 6U3IMME4hRqHJ+la8A7zpjSQfJkWzzOjMJshQWGRsKZGErmO7dtqQVPtIJLJ7BltxzgZCU9aA 2FoW5MbXpR8eOc0UjD9RizP6/8jKngZ9uQvHjl2ujI9JcIh8Jt9SAMi/lEOFSynhQcngE/K6r vNeRwlypmvxpoeEZes0g3Km6OFeMblgjszRE3vrMRiNXUb396huPgEQraiHPlfqg9uUxQ/e+L dEMH+aka2rpK/abfluS/ldbcpvaEzb4V7TGXAU4+EghpOfxURFwTPfpehI0f2xLdcWX1fawHb bMpLS/K2Dco7vdRxlvY186649RzOzXaeqv/z2vkuYZgSwBQIEN6SlJRtKJJkgfLYrGIIMQSFI uBrpSPn9Ef9kus65oVzRWDd5lcF4xPUVkti3XOFMiwqeO1Vabv5dULXyC+RvT5sBssJ7H/TQK dkiDwZbXxgk7FJR4raFRznbDJk33imVewjtrkA== X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.135 Subject: [Qemu-devel] [PATCH v6 06/17] target/m68k: manage 680x0 stack frames X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Richard Henderson , Laurent Vivier Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 680x0 manages several stack frame formats: - format 0: four-word stack frame - format 1: four-word throwaway stack frame - format 2: six-word stack frame - format 3: Floating-Point post-instruction stack frame - format 4: eight-word stack frame - format 7: access-error stack frame Signed-off-by: Laurent Vivier Reviewed-by: Richard Henderson --- Notes: v6: update SR with the content of CCR in the logs introduce cpu_m68k_set_sr() to set SR instead of calling helper_set_sr(). target/m68k/cpu.h | 1 + target/m68k/helper.c | 10 ++- target/m68k/op_helper.c | 160 ++++++++++++++++++++++++++++++++++++++++++++= ++-- 3 files changed, 164 insertions(+), 7 deletions(-) diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index acc2629216..cd4b3a7c7b 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -178,6 +178,7 @@ int cpu_m68k_signal_handler(int host_signum, void *pinf= o, void *puc); uint32_t cpu_m68k_get_ccr(CPUM68KState *env); void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t); +void cpu_m68k_set_sr(CPUM68KState *env, uint32_t); void cpu_m68k_set_fpcr(CPUM68KState *env, uint32_t val); =20 =20 diff --git a/target/m68k/helper.c b/target/m68k/helper.c index 7e50ff5871..af57ffcea9 100644 --- a/target/m68k/helper.c +++ b/target/m68k/helper.c @@ -316,13 +316,17 @@ uint32_t HELPER(sats)(uint32_t val, uint32_t v) return val; } =20 -void HELPER(set_sr)(CPUM68KState *env, uint32_t val) +void cpu_m68k_set_sr(CPUM68KState *env, uint32_t sr) { - env->sr =3D val & 0xffe0; - cpu_m68k_set_ccr(env, val); + env->sr =3D sr & 0xffe0; + cpu_m68k_set_ccr(env, sr); m68k_switch_sp(env); } =20 +void HELPER(set_sr)(CPUM68KState *env, uint32_t val) +{ + cpu_m68k_set_sr(env, val); +} =20 /* MAC unit. */ /* FIXME: The MAC unit implementation is a bit of a mess. Some helpers diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c index 123981af55..5c7b27b9ca 100644 --- a/target/m68k/op_helper.c +++ b/target/m68k/op_helper.c @@ -54,7 +54,7 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessT= ype access_type, } } =20 -static void do_rte(CPUM68KState *env) +static void cf_rte(CPUM68KState *env) { uint32_t sp; uint32_t fmt; @@ -65,7 +65,46 @@ static void do_rte(CPUM68KState *env) sp |=3D (fmt >> 28) & 3; env->aregs[7] =3D sp + 8; =20 - helper_set_sr(env, fmt); + cpu_m68k_set_sr(env, fmt); +} + +static void m68k_rte(CPUM68KState *env) +{ + uint32_t sp; + uint16_t fmt; + uint16_t sr; + + sp =3D env->aregs[7]; +throwaway: + sr =3D cpu_lduw_kernel(env, sp); + sp +=3D 2; + env->pc =3D cpu_ldl_kernel(env, sp); + sp +=3D 4; + if (m68k_feature(env, M68K_FEATURE_QUAD_MULDIV)) { + /* all except 68000 */ + fmt =3D cpu_lduw_kernel(env, sp); + sp +=3D 2; + switch (fmt >> 12) { + case 0: + break; + case 1: + env->aregs[7] =3D sp; + cpu_m68k_set_sr(env, sr); + goto throwaway; + case 2: + case 3: + sp +=3D 4; + break; + case 4: + sp +=3D 8; + break; + case 7: + sp +=3D 52; + break; + } + } + env->aregs[7] =3D sp; + cpu_m68k_set_sr(env, sr); } =20 static const char *m68k_exception_name(int index) @@ -173,7 +212,7 @@ static const char *m68k_exception_name(int index) return "Unassigned"; } =20 -static void do_interrupt_all(CPUM68KState *env, int is_hw) +static void cf_interrupt_all(CPUM68KState *env, int is_hw) { CPUState *cs =3D CPU(m68k_env_get_cpu(env)); uint32_t sp; @@ -189,7 +228,7 @@ static void do_interrupt_all(CPUM68KState *env, int is_= hw) switch (cs->exception_index) { case EXCP_RTE: /* Return from an exception. */ - do_rte(env); + cf_rte(env); return; case EXCP_HALT_INSN: if (semihosting_enabled() @@ -247,6 +286,119 @@ static void do_interrupt_all(CPUM68KState *env, int i= s_hw) env->pc =3D cpu_ldl_kernel(env, env->vbr + vector); } =20 +static inline void do_stack_frame(CPUM68KState *env, uint32_t *sp, + uint16_t format, uint16_t sr, + uint32_t addr, uint32_t retaddr) +{ + CPUState *cs =3D CPU(m68k_env_get_cpu(env)); + switch (format) { + case 4: + *sp -=3D 4; + cpu_stl_kernel(env, *sp, env->pc); + *sp -=3D 4; + cpu_stl_kernel(env, *sp, addr); + break; + case 3: + case 2: + *sp -=3D 4; + cpu_stl_kernel(env, *sp, addr); + break; + } + *sp -=3D 2; + cpu_stw_kernel(env, *sp, (format << 12) + (cs->exception_index << 2)); + *sp -=3D 4; + cpu_stl_kernel(env, *sp, retaddr); + *sp -=3D 2; + cpu_stw_kernel(env, *sp, sr); +} + +static void m68k_interrupt_all(CPUM68KState *env, int is_hw) +{ + CPUState *cs =3D CPU(m68k_env_get_cpu(env)); + uint32_t sp; + uint32_t retaddr; + uint32_t vector; + uint16_t sr, oldsr; + + retaddr =3D env->pc; + + if (!is_hw) { + switch (cs->exception_index) { + case EXCP_RTE: + /* Return from an exception. */ + m68k_rte(env); + return; + case EXCP_TRAP0 ... EXCP_TRAP15: + /* Move the PC after the trap instruction. */ + retaddr +=3D 2; + break; + } + } + + vector =3D cs->exception_index << 2; + + sr =3D env->sr | cpu_m68k_get_ccr(env); + if (qemu_loglevel_mask(CPU_LOG_INT)) { + static int count; + qemu_log("INT %6d: %s(%#x) pc=3D%08x sp=3D%08x sr=3D%04x\n", + ++count, m68k_exception_name(cs->exception_index), + vector, env->pc, env->aregs[7], sr); + } + + /* + * MC68040UM/AD, chapter 9.3.10 + */ + + /* "the processor first make an internal copy" */ + oldsr =3D sr; + /* "set the mode to supervisor" */ + sr |=3D SR_S; + /* "suppress tracing" */ + sr &=3D ~SR_T; + /* "sets the processor interrupt mask" */ + if (is_hw) { + sr |=3D (env->sr & ~SR_I) | (env->pending_level << SR_I_SHIFT); + } + cpu_m68k_set_sr(env, sr); + sp =3D env->aregs[7]; + + sp &=3D ~1; + if (cs->exception_index =3D=3D EXCP_ADDRESS) { + do_stack_frame(env, &sp, 2, oldsr, 0, retaddr); + } else if (cs->exception_index =3D=3D EXCP_ILLEGAL || + cs->exception_index =3D=3D EXCP_DIV0 || + cs->exception_index =3D=3D EXCP_CHK || + cs->exception_index =3D=3D EXCP_TRAPCC || + cs->exception_index =3D=3D EXCP_TRACE) { + /* FIXME: addr is not only env->pc */ + do_stack_frame(env, &sp, 2, oldsr, env->pc, retaddr); + } else if (is_hw && oldsr & SR_M && + cs->exception_index >=3D EXCP_SPURIOUS && + cs->exception_index <=3D EXCP_INT_LEVEL_7) { + do_stack_frame(env, &sp, 0, oldsr, 0, retaddr); + oldsr =3D sr; + env->aregs[7] =3D sp; + cpu_m68k_set_sr(env, sr &=3D ~SR_M); + sp =3D env->aregs[7] & ~1; + do_stack_frame(env, &sp, 1, oldsr, 0, retaddr); + } else { + do_stack_frame(env, &sp, 0, oldsr, 0, retaddr); + } + + env->aregs[7] =3D sp; + /* Jump to vector. */ + env->pc =3D cpu_ldl_kernel(env, env->vbr + vector); +} + +static void do_interrupt_all(CPUM68KState *env, int is_hw) +{ + if (m68k_feature(env, M68K_FEATURE_M68000)) { + m68k_interrupt_all(env, is_hw); + return; + } + cf_interrupt_all(env, is_hw); +} + void m68k_cpu_do_interrupt(CPUState *cs) { M68kCPU *cpu =3D M68K_CPU(cs); --=20 2.14.3