From b22da3d8526a935aa31e086e63f60ff3246cb61c Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 07:24:11 +0000
Subject: [PATCH] add stmac read mac form eeprom
---
kernel/arch/mips/kernel/ptrace.c | 589 ++++++++++++++++++++++++++++++++--------------------------
1 files changed, 323 insertions(+), 266 deletions(-)
diff --git a/kernel/arch/mips/kernel/ptrace.c b/kernel/arch/mips/kernel/ptrace.c
index e5ba56c..db7c5be 100644
--- a/kernel/arch/mips/kernel/ptrace.c
+++ b/kernel/arch/mips/kernel/ptrace.c
@@ -39,7 +39,6 @@
#include <asm/fpu.h>
#include <asm/mipsregs.h>
#include <asm/mipsmtregs.h>
-#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/processor.h>
#include <asm/syscall.h>
@@ -49,25 +48,6 @@
#define CREATE_TRACE_POINTS
#include <trace/events/syscalls.h>
-
-static void init_fp_ctx(struct task_struct *target)
-{
- /* If FP has been used then the target already has context */
- if (tsk_used_math(target))
- return;
-
- /* Begin with data registers set to all 1s... */
- memset(&target->thread.fpu.fpr, ~0, sizeof(target->thread.fpu.fpr));
-
- /* FCSR has been preset by `mips_set_personality_nan'. */
-
- /*
- * Record that the target has "used" math, such that the context
- * just initialised, and any modifications made by the caller,
- * aren't discarded.
- */
- set_stopped_child_used_math(target);
-}
/*
* Called by kernel/ptrace.c when detaching..
@@ -81,21 +61,6 @@
}
/*
- * Poke at FCSR according to its mask. Set the Cause bits even
- * if a corresponding Enable bit is set. This will be noticed at
- * the time the thread is switched to and SIGFPE thrown accordingly.
- */
-static void ptrace_setfcr31(struct task_struct *child, u32 value)
-{
- u32 fcr31;
- u32 mask;
-
- fcr31 = child->thread.fpu.fcr31;
- mask = boot_cpu_data.fpu_msk31;
- child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
-}
-
-/*
* Read a general register set. We always use the 64-bit format, even
* for 32-bit kernels and for 32-bit processes on a 64-bit kernel.
* Registers are sign extended to fill the available space.
@@ -105,7 +70,7 @@
struct pt_regs *regs;
int i;
- if (!access_ok(VERIFY_WRITE, data, 38 * 8))
+ if (!access_ok(data, 38 * 8))
return -EIO;
regs = task_pt_regs(child);
@@ -132,7 +97,7 @@
struct pt_regs *regs;
int i;
- if (!access_ok(VERIFY_READ, data, 38 * 8))
+ if (!access_ok(data, 38 * 8))
return -EIO;
regs = task_pt_regs(child);
@@ -151,55 +116,6 @@
return 0;
}
-int ptrace_getfpregs(struct task_struct *child, __u32 __user *data)
-{
- int i;
-
- if (!access_ok(VERIFY_WRITE, data, 33 * 8))
- return -EIO;
-
- if (tsk_used_math(child)) {
- union fpureg *fregs = get_fpu_regs(child);
- for (i = 0; i < 32; i++)
- __put_user(get_fpr64(&fregs[i], 0),
- i + (__u64 __user *)data);
- } else {
- for (i = 0; i < 32; i++)
- __put_user((__u64) -1, i + (__u64 __user *) data);
- }
-
- __put_user(child->thread.fpu.fcr31, data + 64);
- __put_user(boot_cpu_data.fpu_id, data + 65);
-
- return 0;
-}
-
-int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
-{
- union fpureg *fregs;
- u64 fpr_val;
- u32 value;
- int i;
-
- if (!access_ok(VERIFY_READ, data, 33 * 8))
- return -EIO;
-
- init_fp_ctx(child);
- fregs = get_fpu_regs(child);
-
- for (i = 0; i < 32; i++) {
- __get_user(fpr_val, i + (__u64 __user *)data);
- set_fpr64(&fregs[i], 0, fpr_val);
- }
-
- __get_user(value, data + 64);
- ptrace_setfcr31(child, value);
-
- /* FIR may not be written. */
-
- return 0;
-}
-
int ptrace_get_watch_regs(struct task_struct *child,
struct pt_watch_regs __user *addr)
{
@@ -208,7 +124,7 @@
if (!cpu_has_watch || boot_cpu_data.watch_reg_use_cnt == 0)
return -EIO;
- if (!access_ok(VERIFY_WRITE, addr, sizeof(struct pt_watch_regs)))
+ if (!access_ok(addr, sizeof(struct pt_watch_regs)))
return -EIO;
#ifdef CONFIG_32BIT
@@ -250,7 +166,7 @@
if (!cpu_has_watch || boot_cpu_data.watch_reg_use_cnt == 0)
return -EIO;
- if (!access_ok(VERIFY_READ, addr, sizeof(struct pt_watch_regs)))
+ if (!access_ok(addr, sizeof(struct pt_watch_regs)))
return -EIO;
/* Check the values. */
for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) {
@@ -294,15 +210,13 @@
static int gpr32_get(struct task_struct *target,
const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- void *kbuf, void __user *ubuf)
+ struct membuf to)
{
struct pt_regs *regs = task_pt_regs(target);
u32 uregs[ELF_NGREG] = {};
mips_dump_regs32(uregs, regs);
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0,
- sizeof(uregs));
+ return membuf_write(&to, uregs, sizeof(uregs));
}
static int gpr32_set(struct task_struct *target,
@@ -361,15 +275,13 @@
static int gpr64_get(struct task_struct *target,
const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- void *kbuf, void __user *ubuf)
+ struct membuf to)
{
struct pt_regs *regs = task_pt_regs(target);
u64 uregs[ELF_NGREG] = {};
mips_dump_regs64(uregs, regs);
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0,
- sizeof(uregs));
+ return membuf_write(&to, uregs, sizeof(uregs));
}
static int gpr64_set(struct task_struct *target,
@@ -420,18 +332,83 @@
#endif /* CONFIG_64BIT */
+
+#ifdef CONFIG_MIPS_FP_SUPPORT
+
+/*
+ * Poke at FCSR according to its mask. Set the Cause bits even
+ * if a corresponding Enable bit is set. This will be noticed at
+ * the time the thread is switched to and SIGFPE thrown accordingly.
+ */
+static void ptrace_setfcr31(struct task_struct *child, u32 value)
+{
+ u32 fcr31;
+ u32 mask;
+
+ fcr31 = child->thread.fpu.fcr31;
+ mask = boot_cpu_data.fpu_msk31;
+ child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
+}
+
+int ptrace_getfpregs(struct task_struct *child, __u32 __user *data)
+{
+ int i;
+
+ if (!access_ok(data, 33 * 8))
+ return -EIO;
+
+ if (tsk_used_math(child)) {
+ union fpureg *fregs = get_fpu_regs(child);
+ for (i = 0; i < 32; i++)
+ __put_user(get_fpr64(&fregs[i], 0),
+ i + (__u64 __user *)data);
+ } else {
+ for (i = 0; i < 32; i++)
+ __put_user((__u64) -1, i + (__u64 __user *) data);
+ }
+
+ __put_user(child->thread.fpu.fcr31, data + 64);
+ __put_user(boot_cpu_data.fpu_id, data + 65);
+
+ return 0;
+}
+
+int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
+{
+ union fpureg *fregs;
+ u64 fpr_val;
+ u32 value;
+ int i;
+
+ if (!access_ok(data, 33 * 8))
+ return -EIO;
+
+ init_fp_ctx(child);
+ fregs = get_fpu_regs(child);
+
+ for (i = 0; i < 32; i++) {
+ __get_user(fpr_val, i + (__u64 __user *)data);
+ set_fpr64(&fregs[i], 0, fpr_val);
+ }
+
+ __get_user(value, data + 64);
+ ptrace_setfcr31(child, value);
+
+ /* FIR may not be written. */
+
+ return 0;
+}
+
/*
* Copy the floating-point context to the supplied NT_PRFPREG buffer,
* !CONFIG_CPU_HAS_MSA variant. FP context's general register slots
* correspond 1:1 to buffer slots. Only general registers are copied.
*/
-static int fpr_get_fpa(struct task_struct *target,
- unsigned int *pos, unsigned int *count,
- void **kbuf, void __user **ubuf)
+static void fpr_get_fpa(struct task_struct *target,
+ struct membuf *to)
{
- return user_regset_copyout(pos, count, kbuf, ubuf,
- &target->thread.fpu,
- 0, NUM_FPU_REGS * sizeof(elf_fpreg_t));
+ membuf_write(to, &target->thread.fpu,
+ NUM_FPU_REGS * sizeof(elf_fpreg_t));
}
/*
@@ -440,25 +417,13 @@
* general register slots are copied to buffer slots. Only general
* registers are copied.
*/
-static int fpr_get_msa(struct task_struct *target,
- unsigned int *pos, unsigned int *count,
- void **kbuf, void __user **ubuf)
+static void fpr_get_msa(struct task_struct *target, struct membuf *to)
{
unsigned int i;
- u64 fpr_val;
- int err;
- BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
- for (i = 0; i < NUM_FPU_REGS; i++) {
- fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0);
- err = user_regset_copyout(pos, count, kbuf, ubuf,
- &fpr_val, i * sizeof(elf_fpreg_t),
- (i + 1) * sizeof(elf_fpreg_t));
- if (err)
- return err;
- }
-
- return 0;
+ BUILD_BUG_ON(sizeof(u64) != sizeof(elf_fpreg_t));
+ for (i = 0; i < NUM_FPU_REGS; i++)
+ membuf_store(to, get_fpr64(&target->thread.fpu.fpr[i], 0));
}
/*
@@ -468,31 +433,16 @@
*/
static int fpr_get(struct task_struct *target,
const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- void *kbuf, void __user *ubuf)
+ struct membuf to)
{
- const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t);
- const int fir_pos = fcr31_pos + sizeof(u32);
- int err;
-
if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
- err = fpr_get_fpa(target, &pos, &count, &kbuf, &ubuf);
+ fpr_get_fpa(target, &to);
else
- err = fpr_get_msa(target, &pos, &count, &kbuf, &ubuf);
- if (err)
- return err;
+ fpr_get_msa(target, &to);
- err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &target->thread.fpu.fcr31,
- fcr31_pos, fcr31_pos + sizeof(u32));
- if (err)
- return err;
-
- err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &boot_cpu_data.fpu_id,
- fir_pos, fir_pos + sizeof(u32));
-
- return err;
+ membuf_write(&to, &target->thread.fpu.fcr31, sizeof(u32));
+ membuf_write(&to, &boot_cpu_data.fpu_id, sizeof(u32));
+ return 0;
}
/*
@@ -590,6 +540,151 @@
return err;
}
+/* Copy the FP mode setting to the supplied NT_MIPS_FP_MODE buffer. */
+static int fp_mode_get(struct task_struct *target,
+ const struct user_regset *regset,
+ struct membuf to)
+{
+ return membuf_store(&to, (int)mips_get_process_fp_mode(target));
+}
+
+/*
+ * Copy the supplied NT_MIPS_FP_MODE buffer to the FP mode setting.
+ *
+ * We optimize for the case where `count % sizeof(int) == 0', which
+ * is supposed to have been guaranteed by the kernel before calling
+ * us, e.g. in `ptrace_regset'. We enforce that requirement, so
+ * that we can safely avoid preinitializing temporaries for partial
+ * mode writes.
+ */
+static int fp_mode_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int fp_mode;
+ int err;
+
+ BUG_ON(count % sizeof(int));
+
+ if (pos + count > sizeof(fp_mode))
+ return -EIO;
+
+ err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fp_mode, 0,
+ sizeof(fp_mode));
+ if (err)
+ return err;
+
+ if (count > 0)
+ err = mips_set_process_fp_mode(target, fp_mode);
+
+ return err;
+}
+
+#endif /* CONFIG_MIPS_FP_SUPPORT */
+
+#ifdef CONFIG_CPU_HAS_MSA
+
+struct msa_control_regs {
+ unsigned int fir;
+ unsigned int fcsr;
+ unsigned int msair;
+ unsigned int msacsr;
+};
+
+static void copy_pad_fprs(struct task_struct *target,
+ const struct user_regset *regset,
+ struct membuf *to,
+ unsigned int live_sz)
+{
+ int i, j;
+ unsigned long long fill = ~0ull;
+ unsigned int cp_sz, pad_sz;
+
+ cp_sz = min(regset->size, live_sz);
+ pad_sz = regset->size - cp_sz;
+ WARN_ON(pad_sz % sizeof(fill));
+
+ for (i = 0; i < NUM_FPU_REGS; i++) {
+ membuf_write(to, &target->thread.fpu.fpr[i], cp_sz);
+ for (j = 0; j < (pad_sz / sizeof(fill)); j++)
+ membuf_store(to, fill);
+ }
+}
+
+static int msa_get(struct task_struct *target,
+ const struct user_regset *regset,
+ struct membuf to)
+{
+ const unsigned int wr_size = NUM_FPU_REGS * regset->size;
+ const struct msa_control_regs ctrl_regs = {
+ .fir = boot_cpu_data.fpu_id,
+ .fcsr = target->thread.fpu.fcr31,
+ .msair = boot_cpu_data.msa_id,
+ .msacsr = target->thread.fpu.msacsr,
+ };
+
+ if (!tsk_used_math(target)) {
+ /* The task hasn't used FP or MSA, fill with 0xff */
+ copy_pad_fprs(target, regset, &to, 0);
+ } else if (!test_tsk_thread_flag(target, TIF_MSA_CTX_LIVE)) {
+ /* Copy scalar FP context, fill the rest with 0xff */
+ copy_pad_fprs(target, regset, &to, 8);
+ } else if (sizeof(target->thread.fpu.fpr[0]) == regset->size) {
+ /* Trivially copy the vector registers */
+ membuf_write(&to, &target->thread.fpu.fpr, wr_size);
+ } else {
+ /* Copy as much context as possible, fill the rest with 0xff */
+ copy_pad_fprs(target, regset, &to,
+ sizeof(target->thread.fpu.fpr[0]));
+ }
+
+ return membuf_write(&to, &ctrl_regs, sizeof(ctrl_regs));
+}
+
+static int msa_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ const unsigned int wr_size = NUM_FPU_REGS * regset->size;
+ struct msa_control_regs ctrl_regs;
+ unsigned int cp_sz;
+ int i, err, start;
+
+ init_fp_ctx(target);
+
+ if (sizeof(target->thread.fpu.fpr[0]) == regset->size) {
+ /* Trivially copy the vector registers */
+ err = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.fpu.fpr,
+ 0, wr_size);
+ } else {
+ /* Copy as much context as possible */
+ cp_sz = min_t(unsigned int, regset->size,
+ sizeof(target->thread.fpu.fpr[0]));
+
+ i = start = err = 0;
+ for (; i < NUM_FPU_REGS; i++, start += regset->size) {
+ err |= user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.fpu.fpr[i],
+ start, start + cp_sz);
+ }
+ }
+
+ if (!err)
+ err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl_regs,
+ wr_size, wr_size + sizeof(ctrl_regs));
+ if (!err) {
+ target->thread.fpu.fcr31 = ctrl_regs.fcsr & ~FPU_CSR_ALL_X;
+ target->thread.fpu.msacsr = ctrl_regs.msacsr & ~MSA_CSR_CAUSEF;
+ }
+
+ return err;
+}
+
+#endif /* CONFIG_CPU_HAS_MSA */
+
#if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32)
/*
@@ -597,34 +692,20 @@
*/
static int dsp32_get(struct task_struct *target,
const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- void *kbuf, void __user *ubuf)
+ struct membuf to)
{
- unsigned int start, num_regs, i;
u32 dspregs[NUM_DSP_REGS + 1];
+ unsigned int i;
- BUG_ON(count % sizeof(u32));
+ BUG_ON(to.left % sizeof(u32));
if (!cpu_has_dsp)
return -EIO;
- start = pos / sizeof(u32);
- num_regs = count / sizeof(u32);
-
- if (start + num_regs > NUM_DSP_REGS + 1)
- return -EIO;
-
- for (i = start; i < num_regs; i++)
- switch (i) {
- case 0 ... NUM_DSP_REGS - 1:
- dspregs[i] = target->thread.dsp.dspr[i];
- break;
- case NUM_DSP_REGS:
- dspregs[i] = target->thread.dsp.dspcontrol;
- break;
- }
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, dspregs, 0,
- sizeof(dspregs));
+ for (i = 0; i < NUM_DSP_REGS; i++)
+ dspregs[i] = target->thread.dsp.dspr[i];
+ dspregs[NUM_DSP_REGS] = target->thread.dsp.dspcontrol;
+ return membuf_write(&to, dspregs, sizeof(dspregs));
}
/*
@@ -677,34 +758,20 @@
*/
static int dsp64_get(struct task_struct *target,
const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- void *kbuf, void __user *ubuf)
+ struct membuf to)
{
- unsigned int start, num_regs, i;
u64 dspregs[NUM_DSP_REGS + 1];
+ unsigned int i;
- BUG_ON(count % sizeof(u64));
+ BUG_ON(to.left % sizeof(u64));
if (!cpu_has_dsp)
return -EIO;
- start = pos / sizeof(u64);
- num_regs = count / sizeof(u64);
-
- if (start + num_regs > NUM_DSP_REGS + 1)
- return -EIO;
-
- for (i = start; i < num_regs; i++)
- switch (i) {
- case 0 ... NUM_DSP_REGS - 1:
- dspregs[i] = target->thread.dsp.dspr[i];
- break;
- case NUM_DSP_REGS:
- dspregs[i] = target->thread.dsp.dspcontrol;
- break;
- }
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, dspregs, 0,
- sizeof(dspregs));
+ for (i = 0; i < NUM_DSP_REGS; i++)
+ dspregs[i] = target->thread.dsp.dspr[i];
+ dspregs[NUM_DSP_REGS] = target->thread.dsp.dspcontrol;
+ return membuf_write(&to, dspregs, sizeof(dspregs));
}
/*
@@ -759,57 +826,16 @@
return cpu_has_dsp ? NUM_DSP_REGS + 1 : -ENODEV;
}
-/* Copy the FP mode setting to the supplied NT_MIPS_FP_MODE buffer. */
-static int fp_mode_get(struct task_struct *target,
- const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- void *kbuf, void __user *ubuf)
-{
- int fp_mode;
-
- fp_mode = mips_get_process_fp_mode(target);
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &fp_mode, 0,
- sizeof(fp_mode));
-}
-
-/*
- * Copy the supplied NT_MIPS_FP_MODE buffer to the FP mode setting.
- *
- * We optimize for the case where `count % sizeof(int) == 0', which
- * is supposed to have been guaranteed by the kernel before calling
- * us, e.g. in `ptrace_regset'. We enforce that requirement, so
- * that we can safely avoid preinitializing temporaries for partial
- * mode writes.
- */
-static int fp_mode_set(struct task_struct *target,
- const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- const void *kbuf, const void __user *ubuf)
-{
- int fp_mode;
- int err;
-
- BUG_ON(count % sizeof(int));
-
- if (pos + count > sizeof(fp_mode))
- return -EIO;
-
- err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fp_mode, 0,
- sizeof(fp_mode));
- if (err)
- return err;
-
- if (count > 0)
- err = mips_set_process_fp_mode(target, fp_mode);
-
- return err;
-}
-
enum mips_regset {
REGSET_GPR,
- REGSET_FPR,
REGSET_DSP,
+#ifdef CONFIG_MIPS_FP_SUPPORT
+ REGSET_FPR,
REGSET_FP_MODE,
+#endif
+#ifdef CONFIG_CPU_HAS_MSA
+ REGSET_MSA,
+#endif
};
struct pt_regs_offset {
@@ -904,34 +930,46 @@
.n = ELF_NGREG,
.size = sizeof(unsigned int),
.align = sizeof(unsigned int),
- .get = gpr32_get,
+ .regset_get = gpr32_get,
.set = gpr32_set,
- },
- [REGSET_FPR] = {
- .core_note_type = NT_PRFPREG,
- .n = ELF_NFPREG,
- .size = sizeof(elf_fpreg_t),
- .align = sizeof(elf_fpreg_t),
- .get = fpr_get,
- .set = fpr_set,
},
[REGSET_DSP] = {
.core_note_type = NT_MIPS_DSP,
.n = NUM_DSP_REGS + 1,
.size = sizeof(u32),
.align = sizeof(u32),
- .get = dsp32_get,
+ .regset_get = dsp32_get,
.set = dsp32_set,
.active = dsp_active,
+ },
+#ifdef CONFIG_MIPS_FP_SUPPORT
+ [REGSET_FPR] = {
+ .core_note_type = NT_PRFPREG,
+ .n = ELF_NFPREG,
+ .size = sizeof(elf_fpreg_t),
+ .align = sizeof(elf_fpreg_t),
+ .regset_get = fpr_get,
+ .set = fpr_set,
},
[REGSET_FP_MODE] = {
.core_note_type = NT_MIPS_FP_MODE,
.n = 1,
.size = sizeof(int),
.align = sizeof(int),
- .get = fp_mode_get,
+ .regset_get = fp_mode_get,
.set = fp_mode_set,
},
+#endif
+#ifdef CONFIG_CPU_HAS_MSA
+ [REGSET_MSA] = {
+ .core_note_type = NT_MIPS_MSA,
+ .n = NUM_FPU_REGS + 1,
+ .size = 16,
+ .align = 16,
+ .regset_get = msa_get,
+ .set = msa_set,
+ },
+#endif
};
static const struct user_regset_view user_mips_view = {
@@ -952,34 +990,46 @@
.n = ELF_NGREG,
.size = sizeof(unsigned long),
.align = sizeof(unsigned long),
- .get = gpr64_get,
+ .regset_get = gpr64_get,
.set = gpr64_set,
- },
- [REGSET_FPR] = {
- .core_note_type = NT_PRFPREG,
- .n = ELF_NFPREG,
- .size = sizeof(elf_fpreg_t),
- .align = sizeof(elf_fpreg_t),
- .get = fpr_get,
- .set = fpr_set,
},
[REGSET_DSP] = {
.core_note_type = NT_MIPS_DSP,
.n = NUM_DSP_REGS + 1,
.size = sizeof(u64),
.align = sizeof(u64),
- .get = dsp64_get,
+ .regset_get = dsp64_get,
.set = dsp64_set,
.active = dsp_active,
},
+#ifdef CONFIG_MIPS_FP_SUPPORT
[REGSET_FP_MODE] = {
.core_note_type = NT_MIPS_FP_MODE,
.n = 1,
.size = sizeof(int),
.align = sizeof(int),
- .get = fp_mode_get,
+ .regset_get = fp_mode_get,
.set = fp_mode_set,
},
+ [REGSET_FPR] = {
+ .core_note_type = NT_PRFPREG,
+ .n = ELF_NFPREG,
+ .size = sizeof(elf_fpreg_t),
+ .align = sizeof(elf_fpreg_t),
+ .regset_get = fpr_get,
+ .set = fpr_set,
+ },
+#endif
+#ifdef CONFIG_CPU_HAS_MSA
+ [REGSET_MSA] = {
+ .core_note_type = NT_MIPS_MSA,
+ .n = NUM_FPU_REGS + 1,
+ .size = 16,
+ .align = 16,
+ .regset_get = msa_get,
+ .set = msa_set,
+ },
+#endif
};
static const struct user_regset_view user_mips64_view = {
@@ -1040,7 +1090,6 @@
/* Read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
struct pt_regs *regs;
- union fpureg *fregs;
unsigned long tmp = 0;
regs = task_pt_regs(child);
@@ -1050,7 +1099,10 @@
case 0 ... 31:
tmp = regs->regs[addr];
break;
- case FPR_BASE ... FPR_BASE + 31:
+#ifdef CONFIG_MIPS_FP_SUPPORT
+ case FPR_BASE ... FPR_BASE + 31: {
+ union fpureg *fregs;
+
if (!tsk_used_math(child)) {
/* FP not yet used */
tmp = -1;
@@ -1072,6 +1124,15 @@
#endif
tmp = get_fpr64(&fregs[addr - FPR_BASE], 0);
break;
+ }
+ case FPC_CSR:
+ tmp = child->thread.fpu.fcr31;
+ break;
+ case FPC_EIR:
+ /* implementation / version register */
+ tmp = boot_cpu_data.fpu_id;
+ break;
+#endif
case PC:
tmp = regs->cp0_epc;
break;
@@ -1092,13 +1153,6 @@
tmp = regs->acx;
break;
#endif
- case FPC_CSR:
- tmp = child->thread.fpu.fcr31;
- break;
- case FPC_EIR:
- /* implementation / version register */
- tmp = boot_cpu_data.fpu_id;
- break;
case DSP_BASE ... DSP_BASE + 5: {
dspreg_t *dregs;
@@ -1149,6 +1203,7 @@
mips_syscall_is_indirect(child, regs))
mips_syscall_update_nr(child, regs);
break;
+#ifdef CONFIG_MIPS_FP_SUPPORT
case FPR_BASE ... FPR_BASE + 31: {
union fpureg *fregs = get_fpu_regs(child);
@@ -1168,6 +1223,11 @@
set_fpr64(&fregs[addr - FPR_BASE], 0, data);
break;
}
+ case FPC_CSR:
+ init_fp_ctx(child);
+ ptrace_setfcr31(child, data);
+ break;
+#endif
case PC:
regs->cp0_epc = data;
break;
@@ -1182,10 +1242,6 @@
regs->acx = data;
break;
#endif
- case FPC_CSR:
- init_fp_ctx(child);
- ptrace_setfcr31(child, data);
- break;
case DSP_BASE ... DSP_BASE + 5: {
dspreg_t *dregs;
@@ -1221,6 +1277,7 @@
ret = ptrace_setregs(child, datavp);
break;
+#ifdef CONFIG_MIPS_FP_SUPPORT
case PTRACE_GETFPREGS:
ret = ptrace_getfpregs(child, datavp);
break;
@@ -1228,7 +1285,7 @@
case PTRACE_SETFPREGS:
ret = ptrace_setfpregs(child, datavp);
break;
-
+#endif
case PTRACE_GET_THREAD_AREA:
ret = put_user(task_thread_info(child)->tp_value, datalp);
break;
@@ -1272,8 +1329,8 @@
unsigned long args[6];
sd.nr = syscall;
- sd.arch = syscall_get_arch();
- syscall_get_arguments(current, regs, 0, 6, args);
+ sd.arch = syscall_get_arch(current);
+ syscall_get_arguments(current, regs, args);
for (i = 0; i < 6; i++)
sd.args[i] = args[i];
sd.instruction_pointer = KSTK_EIP(current);
--
Gitblit v1.6.2