1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | |
3 | #include <linux/regset.h> |
4 | |
5 | #include <asm/switch_to.h> |
6 | |
7 | #include "ptrace-decl.h" |
8 | |
9 | int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data) |
10 | { |
11 | #ifdef CONFIG_PPC_FPU_REGS |
12 | unsigned int fpidx = index - PT_FPR0; |
13 | #endif |
14 | |
15 | if (index > PT_FPSCR) |
16 | return -EIO; |
17 | |
18 | #ifdef CONFIG_PPC_FPU_REGS |
19 | flush_fp_to_thread(child); |
20 | if (fpidx < (PT_FPSCR - PT_FPR0)) { |
21 | if (IS_ENABLED(CONFIG_PPC32)) |
22 | // On 32-bit the index we are passed refers to 32-bit words |
23 | *data = ((u32 *)child->thread.fp_state.fpr)[fpidx]; |
24 | else |
25 | memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long)); |
26 | } else |
27 | *data = child->thread.fp_state.fpscr; |
28 | #else |
29 | *data = 0; |
30 | #endif |
31 | |
32 | return 0; |
33 | } |
34 | |
35 | int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data) |
36 | { |
37 | #ifdef CONFIG_PPC_FPU_REGS |
38 | unsigned int fpidx = index - PT_FPR0; |
39 | #endif |
40 | |
41 | if (index > PT_FPSCR) |
42 | return -EIO; |
43 | |
44 | #ifdef CONFIG_PPC_FPU_REGS |
45 | flush_fp_to_thread(child); |
46 | if (fpidx < (PT_FPSCR - PT_FPR0)) { |
47 | if (IS_ENABLED(CONFIG_PPC32)) |
48 | // On 32-bit the index we are passed refers to 32-bit words |
49 | ((u32 *)child->thread.fp_state.fpr)[fpidx] = data; |
50 | else |
51 | memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long)); |
52 | } else |
53 | child->thread.fp_state.fpscr = data; |
54 | #endif |
55 | |
56 | return 0; |
57 | } |
58 | |
59 | |