qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC PATCH 28/42] target/mips/tx79: Move RDHWR usermode kludge to tr


From: Fredrik Noring
Subject: Re: [RFC PATCH 28/42] target/mips/tx79: Move RDHWR usermode kludge to trans_SQ()
Date: Tue, 16 Feb 2021 08:05:57 +0100

On Mon, Feb 15, 2021 at 01:01:52PM -0800, Richard Henderson wrote:
> On 2/14/21 9:58 AM, Philippe Mathieu-Daudé wrote:
> > +    /*
> > +     * The TX79-specific instruction Store Quadword
> > +     *
> > +     * +--------+-------+-------+------------------------+
> > +     * | 011111 |  base |   rt  |           offset       | SQ
> > +     * +--------+-------+-------+------------------------+
> > +     *      6       5       5                 16
> > +     *
> > +     * has the same opcode as the Read Hardware Register instruction
> > +     *
> > +     * +--------+-------+-------+-------+-------+--------+
> > +     * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
> > +     * +--------+-------+-------+-------+-------+--------+
> > +     *      6       5       5       5       5        6
> > +     *
> > +     * that is required, trapped and emulated by the Linux kernel. 
> > However, all
> > +     * RDHWR encodings yield address error exceptions on the TX79 since 
> > the SQ
> > +     * offset is odd.
> 
> Not that it's odd (the final address is masked, remember), but that it a store
> to an address in the zero page.

The address always resolves to 0xffffe83b (then masked) in 32-bit KSEG2,
because rt is always $3 and rd is always $29 so -6085(zero), hence the
last page (which is much better) rather than the first, as Maciej
discovered:

https://patchwork.kernel.org/comment/23824173/

Other possible RDHWR encodings are no longer used, and can therefore be
ignored and revert to SQ:

https://patchwork.kernel.org/comment/23842167/

Notice also the oddity of 32-bit R5900 addresses that doesn't matter here
but has implications for n32 and system emulation.

> I would do this as
> 
> {
>   RDHWR_user  011111 00000 ..... ..... 00000 111011   @rd_rt
>   SQ          011111 ..... ..... ................     @ldst
> }

Both rd and rt have fixed values, as mentioned.

For reference, RDHWR is currently done like this in the Linux kernel:

        if (IS_ENABLED(CONFIG_CPU_R5900)) {
                /*
                 * On the R5900, a valid RDHWR instruction
                 *
                 *     +--------+-------+----+----+-------+--------+
                 *     | 011111 | 00000 | rt | rd | 00000 | 111011 |
                 *     +--------+-------+----+----+-------+--------+
                 *          6       5      5    5     5        6
                 *
                 * having rt $3 (v1) and rd $29 (MIPS_HWR_ULR) is
                 * interpreted as the R5900 specific SQ instruction
                 *
                 *     +--------+-------+----+---------------------+
                 *     | 011111 |  base | rt |        offset       |
                 *     +--------+-------+----+---------------------+
                 *          6       5      5            16
                 *
                 * with
                 *
                 *     sq v1,-6085(zero)
                 *
                 * that asserts an address exception since -6085(zero)
                 * always resolves to 0xffffe83b in 32-bit KSEG2.
                 *
                 * Other legacy values of rd, such as MIPS_HWR_CPUNUM,
                 * are ignored.
                 */
                if (insn.r_format.func == rdhwr_op &&
                    insn.r_format.rd == MIPS_HWR_ULR &&
                    insn.r_format.rt == 3 &&
                    insn.r_format.rs == 0 &&
                    insn.r_format.re == 0) {
                        if (compute_return_epc(regs) < 0 ||
                            simulate_rdhwr(regs, insn.r_format.rd,
                                           insn.r_format.rt) < 0)
                                goto sigill;
                        return;
                }
                goto sigbus;
        } else ...

Fredrik



reply via email to

[Prev in Thread] Current Thread [Next in Thread]