diff mbox series

[v2,08/30] bsd-user/arm/target_arch_cpu.h: Implement trivial EXCP exceptions

Message ID 20211102225248.52999-9-imp@bsdimp.com (mailing list archive)
State New, archived
Headers show
Series bsd-user: arm (32-bit) support | expand

Commit Message

Warner Losh Nov. 2, 2021, 10:52 p.m. UTC
Implement EXCP_UDEF, EXCP_DEBUG, EXCP_INTERRUPT, EXCP_ATOMIC and
EXCP_YIELD. The first two generate a signal to the emulated
binary. EXCP_ATOMIC handles atomic operations. The remainder are fancy
nops.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Mikaƫl Urankar <mikael.urankar@gmail.com>
Signed-off-by: Kyle Evans <kevans@FreeBSD.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
---
 bsd-user/arm/target_arch_cpu.h | 58 ++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

Comments

Richard Henderson Nov. 3, 2021, 3:17 a.m. UTC | #1
On 11/2/21 6:52 PM, Warner Losh wrote:
> +        case EXCP_UDEF:
> +            {
> +                /* See arm/arm/undefined.c undefinedinstruction(); */
> +                info.si_addr = env->regs[15];
> +
> +                /*
> +                 * Make sure the PC is correctly aligned. (It should
> +                 * be.)
> +                 */
> +                if ((info.si_addr & 3) != 0) {
> +                    info.si_signo = TARGET_SIGILL;
> +                    info.si_errno = 0;
> +                    info.si_code = TARGET_ILL_ILLADR;
> +                    queue_signal(env, info.si_signo, &info);

You won't need this; unaligned pc will raise a different exception.

> +                } else {
> +                    int rc = 0;
> +#ifdef NOT_YET
> +                    uint32_t opcode;
> +
> +                    /*
> +                     * Get the opcode.
> +                     *
> +                     * FIXME - what to do if get_user() fails?
> +                     */
> +                    get_user_u32(opcode, env->regs[15]);
> +
> +                    /* Check the opcode with CP handlers we may have. */
> +                    rc = EmulateAll(opcode, &ts->fpa, env);
> +#endif /* NOT_YET */

Drop this til you need it.  Even then, we prefer to emulate all insns in the front-end. 
We can talk about what changes need to happen such that the actual CP registers are simply 
available at EL0.  I suspect they've already been done for linux-user anyway...


r~
Warner Losh Nov. 3, 2021, 4:27 p.m. UTC | #2
On Tue, Nov 2, 2021 at 9:17 PM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 11/2/21 6:52 PM, Warner Losh wrote:
> > +        case EXCP_UDEF:
> > +            {
> > +                /* See arm/arm/undefined.c undefinedinstruction(); */
> > +                info.si_addr = env->regs[15];
> > +
> > +                /*
> > +                 * Make sure the PC is correctly aligned. (It should
> > +                 * be.)
> > +                 */
> > +                if ((info.si_addr & 3) != 0) {
> > +                    info.si_signo = TARGET_SIGILL;
> > +                    info.si_errno = 0;
> > +                    info.si_code = TARGET_ILL_ILLADR;
> > +                    queue_signal(env, info.si_signo, &info);
>
> You won't need this; unaligned pc will raise a different exception.
>

Dropped.


> > +                } else {
> > +                    int rc = 0;
> > +#ifdef NOT_YET
> > +                    uint32_t opcode;
> > +
> > +                    /*
> > +                     * Get the opcode.
> > +                     *
> > +                     * FIXME - what to do if get_user() fails?
> > +                     */
> > +                    get_user_u32(opcode, env->regs[15]);
> > +
> > +                    /* Check the opcode with CP handlers we may have. */
> > +                    rc = EmulateAll(opcode, &ts->fpa, env);
> > +#endif /* NOT_YET */
>
> Drop this til you need it.  Even then, we prefer to emulate all insns in
> the front-end.
> We can talk about what changes need to happen such that the actual CP
> registers are simply
> available at EL0.  I suspect they've already been done for linux-user
> anyway...
>

Dropped, reformatted and added a TODO comment.

Both will be in the next spin.

Thanks!

Warner
diff mbox series

Patch

diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
index 2484bdc2f7..609b78b4e2 100644
--- a/bsd-user/arm/target_arch_cpu.h
+++ b/bsd-user/arm/target_arch_cpu.h
@@ -48,6 +48,64 @@  static inline void target_cpu_loop(CPUARMState *env)
         cpu_exec_end(cs);
         process_queued_cpu_work(cs);
         switch (trapnr) {
+        case EXCP_UDEF:
+            {
+                /* See arm/arm/undefined.c undefinedinstruction(); */
+                info.si_addr = env->regs[15];
+
+                /*
+                 * Make sure the PC is correctly aligned. (It should
+                 * be.)
+                 */
+                if ((info.si_addr & 3) != 0) {
+                    info.si_signo = TARGET_SIGILL;
+                    info.si_errno = 0;
+                    info.si_code = TARGET_ILL_ILLADR;
+                    queue_signal(env, info.si_signo, &info);
+                } else {
+                    int rc = 0;
+#ifdef NOT_YET
+                    uint32_t opcode;
+
+                    /*
+                     * Get the opcode.
+                     *
+                     * FIXME - what to do if get_user() fails?
+                     */
+                    get_user_u32(opcode, env->regs[15]);
+
+                    /* Check the opcode with CP handlers we may have. */
+                    rc = EmulateAll(opcode, &ts->fpa, env);
+#endif /* NOT_YET */
+                    if (rc == 0) {
+                        /* illegal instruction */
+                        info.si_signo = TARGET_SIGILL;
+                        info.si_errno = 0;
+                        info.si_code = TARGET_ILL_ILLOPC;
+                        queue_signal(env, info.si_signo, &info);
+                    }
+                }
+            }
+            break;
+        case EXCP_INTERRUPT:
+            /* just indicate that signals should be handled asap */
+            break;
+        case EXCP_DEBUG:
+            {
+
+                info.si_signo = TARGET_SIGTRAP;
+                info.si_errno = 0;
+                info.si_code = TARGET_TRAP_BRKPT;
+                info.si_addr = env->exception.vaddress;
+                queue_signal(env, info.si_signo, &info);
+            }
+            break;
+        case EXCP_ATOMIC:
+            cpu_exec_step_atomic(cs);
+            break;
+        case EXCP_YIELD:
+            /* nothing to do here for user-mode, just resume guest code */
+            break;
         default:
             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
                     trapnr);