2023-06-04 12:33:52

by Paul Cercueil

[permalink] [raw]
Subject: [PATCH 1/4] MIPS: uaccess: emulate Ingenic LXW/LXH/LXHU uaccess

From: Siarhei Volkau <[email protected]>

The LXW, LXH, LXHU opcodes are part of the MXU ASE found in Ingenic
XBurst based SoCs.

While technically part of the MXU ASE, they do not touch any of the SIMD
registers, and can be used even when the MXU ASE is disabled.

This patch makes it possible to emulate unaligned access for those
instructions.

Signed-off-by: Siarhei Volkau <[email protected]>
---
arch/mips/include/uapi/asm/inst.h | 33 +++++++++++++++++++++++++
arch/mips/kernel/unaligned.c | 41 +++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+)

diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h
index 43d1faa02933..c29dbc8c1d49 100644
--- a/arch/mips/include/uapi/asm/inst.h
+++ b/arch/mips/include/uapi/asm/inst.h
@@ -272,6 +272,27 @@ enum lx_func {
lbx_op = 0x16,
};

+/*
+ * func field for special2 MXU opcodes (Ingenic XBurst MXU).
+ */
+enum mxu_func {
+ /* TODO, other MXU funcs */
+ mxu_lx_op = 0x28,
+};
+
+/*
+ * op field for special2 MXU LX opcodes (Ingenic XBurst MXU).
+ */
+enum lx_ingenic_func {
+ mxu_lxb_op,
+ mxu_lxh_op,
+ /* reserved */
+ mxu_lxw_op = 3,
+ mxu_lxbu_op,
+ mxu_lxhu_op,
+ /* more reserved */
+};
+
/*
* BSHFL opcodes
*/
@@ -774,6 +795,17 @@ struct dsp_format { /* SPEC3 DSP format instructions */
;))))))
};

+struct mxu_lx_format { /* SPEC2 MXU LX format instructions */
+ __BITFIELD_FIELD(unsigned int opcode : 6,
+ __BITFIELD_FIELD(unsigned int rs : 5,
+ __BITFIELD_FIELD(unsigned int rt : 5,
+ __BITFIELD_FIELD(unsigned int rd : 5,
+ __BITFIELD_FIELD(unsigned int strd : 2,
+ __BITFIELD_FIELD(unsigned int op : 3,
+ __BITFIELD_FIELD(unsigned int func : 6,
+ ;)))))))
+};
+
struct spec3_format { /* SPEC3 */
__BITFIELD_FIELD(unsigned int opcode:6,
__BITFIELD_FIELD(unsigned int rs:5,
@@ -1125,6 +1157,7 @@ union mips_instruction {
struct loongson3_lswc2_format loongson3_lswc2_format;
struct loongson3_lsdc2_format loongson3_lsdc2_format;
struct loongson3_lscsr_format loongson3_lscsr_format;
+ struct mxu_lx_format mxu_lx_format;
};

union mips16e_instruction {
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 7b5aba5df02e..f4cf94e92ec3 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -160,6 +160,47 @@ static void emulate_load_store_insn(struct pt_regs *regs,
* The remaining opcodes are the ones that are really of
* interest.
*/
+#ifdef CONFIG_MACH_INGENIC
+ case spec2_op:
+ if (insn.mxu_lx_format.func != mxu_lx_op)
+ goto sigbus; /* other MXU instructions we don't care */
+
+ switch (insn.mxu_lx_format.op) {
+ case mxu_lxw_op:
+ if (user && !access_ok(addr, 4))
+ goto sigbus;
+ LoadW(addr, value, res);
+ if (res)
+ goto fault;
+ compute_return_epc(regs);
+ regs->regs[insn.mxu_lx_format.rd] = value;
+ break;
+ case mxu_lxh_op:
+ if (user && !access_ok(addr, 2))
+ goto sigbus;
+ LoadHW(addr, value, res);
+ if (res)
+ goto fault;
+ compute_return_epc(regs);
+ regs->regs[insn.dsp_format.rd] = value;
+ break;
+ case mxu_lxhu_op:
+ if (user && !access_ok(addr, 2))
+ goto sigbus;
+ LoadHWU(addr, value, res);
+ if (res)
+ goto fault;
+ compute_return_epc(regs);
+ regs->regs[insn.dsp_format.rd] = value;
+ break;
+ case mxu_lxb_op:
+ case mxu_lxbu_op:
+ goto sigbus;
+ default:
+ goto sigill;
+ }
+ break;
+#endif
case spec3_op:
if (insn.dsp_format.func == lx_op) {
switch (insn.dsp_format.op) {
--
2.39.2



2023-06-04 12:35:03

by Paul Cercueil

[permalink] [raw]
Subject: [PATCH 2/4] mips: ingenic: Remove useless __maybe_unused

These flags are useless in this case as the code referencing these data
structures is always seen by the compiler (and not behind #ifdef
guards).

Signed-off-by: Paul Cercueil <[email protected]>
---
arch/mips/generic/board-ingenic.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/mips/generic/board-ingenic.c b/arch/mips/generic/board-ingenic.c
index c422bbc890ed..7a4fce06875d 100644
--- a/arch/mips/generic/board-ingenic.c
+++ b/arch/mips/generic/board-ingenic.c
@@ -117,14 +117,14 @@ static void ingenic_halt(void)
ingenic_wait_instr();
}

-static int __maybe_unused ingenic_pm_enter(suspend_state_t state)
+static int ingenic_pm_enter(suspend_state_t state)
{
ingenic_wait_instr();

return 0;
}

-static const struct platform_suspend_ops ingenic_pm_ops __maybe_unused = {
+static const struct platform_suspend_ops ingenic_pm_ops = {
.valid = suspend_valid_only_mem,
.enter = ingenic_pm_enter,
};
--
2.39.2


2023-06-09 08:33:30

by Thomas Bogendoerfer

[permalink] [raw]
Subject: Re: [PATCH 2/4] mips: ingenic: Remove useless __maybe_unused

On Sun, Jun 04, 2023 at 02:26:53PM +0200, Paul Cercueil wrote:
> These flags are useless in this case as the code referencing these data
> structures is always seen by the compiler (and not behind #ifdef
> guards).
>
> Signed-off-by: Paul Cercueil <[email protected]>
> ---
> arch/mips/generic/board-ingenic.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/mips/generic/board-ingenic.c b/arch/mips/generic/board-ingenic.c
> index c422bbc890ed..7a4fce06875d 100644
> --- a/arch/mips/generic/board-ingenic.c
> +++ b/arch/mips/generic/board-ingenic.c
> @@ -117,14 +117,14 @@ static void ingenic_halt(void)
> ingenic_wait_instr();
> }
>
> -static int __maybe_unused ingenic_pm_enter(suspend_state_t state)
> +static int ingenic_pm_enter(suspend_state_t state)
> {
> ingenic_wait_instr();
>
> return 0;
> }
>
> -static const struct platform_suspend_ops ingenic_pm_ops __maybe_unused = {
> +static const struct platform_suspend_ops ingenic_pm_ops = {
> .valid = suspend_valid_only_mem,
> .enter = ingenic_pm_enter,
> };
> --
> 2.39.2

applied to mips-next.

Thomas.

--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]

2023-06-09 08:51:46

by Thomas Bogendoerfer

[permalink] [raw]
Subject: Re: [PATCH 1/4] MIPS: uaccess: emulate Ingenic LXW/LXH/LXHU uaccess

On Sun, Jun 04, 2023 at 02:26:52PM +0200, Paul Cercueil wrote:
> From: Siarhei Volkau <[email protected]>
>
> The LXW, LXH, LXHU opcodes are part of the MXU ASE found in Ingenic
> XBurst based SoCs.
>
> While technically part of the MXU ASE, they do not touch any of the SIMD
> registers, and can be used even when the MXU ASE is disabled.
>
> This patch makes it possible to emulate unaligned access for those
> instructions.
>
> Signed-off-by: Siarhei Volkau <[email protected]>
> ---
> arch/mips/include/uapi/asm/inst.h | 33 +++++++++++++++++++++++++
> arch/mips/kernel/unaligned.c | 41 +++++++++++++++++++++++++++++++
> 2 files changed, 74 insertions(+)

applied to mips-next.

Thomas.

--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]