Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Licensed under the GPL |
| 3 | */ |
| 4 | |
| 5 | #ifndef __SYS_PTRACE_PPC_H |
| 6 | #define __SYS_PTRACE_PPC_H |
| 7 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 8 | #include "linux/types.h" |
| 9 | |
| 10 | /* the following taken from <asm-ppc/ptrace.h> */ |
| 11 | |
| 12 | #ifdef CONFIG_PPC64 |
| 13 | #define PPC_REG unsigned long /*long*/ |
| 14 | #else |
| 15 | #define PPC_REG unsigned long |
| 16 | #endif |
| 17 | struct sys_pt_regs_s { |
| 18 | PPC_REG gpr[32]; |
| 19 | PPC_REG nip; |
| 20 | PPC_REG msr; |
| 21 | PPC_REG orig_gpr3; /* Used for restarting system calls */ |
| 22 | PPC_REG ctr; |
| 23 | PPC_REG link; |
| 24 | PPC_REG xer; |
| 25 | PPC_REG ccr; |
| 26 | PPC_REG mq; /* 601 only (not used at present) */ |
| 27 | /* Used on APUS to hold IPL value. */ |
| 28 | PPC_REG trap; /* Reason for being here */ |
| 29 | PPC_REG dar; /* Fault registers */ |
| 30 | PPC_REG dsisr; |
| 31 | PPC_REG result; /* Result of a system call */ |
| 32 | }; |
| 33 | |
| 34 | #define NUM_REGS (sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG)) |
| 35 | |
| 36 | struct sys_pt_regs { |
| 37 | PPC_REG regs[sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG)]; |
| 38 | }; |
| 39 | |
| 40 | #define UM_MAX_REG (PT_FPR0) |
| 41 | #define UM_MAX_REG_OFFSET (UM_MAX_REG * sizeof(PPC_REG)) |
| 42 | |
| 43 | #define EMPTY_REGS { { [ 0 ... NUM_REGS - 1] = 0 } } |
| 44 | |
| 45 | #define UM_REG(r, n) ((r)->regs[n]) |
| 46 | |
| 47 | #define UM_SYSCALL_RET(r) UM_REG(r, PT_R3) |
| 48 | #define UM_SP(r) UM_REG(r, PT_R1) |
| 49 | #define UM_IP(r) UM_REG(r, PT_NIP) |
| 50 | #define UM_ELF_ZERO(r) UM_REG(r, PT_FPSCR) |
| 51 | #define UM_SYSCALL_NR(r) UM_REG(r, PT_R0) |
| 52 | #define UM_SYSCALL_ARG1(r) UM_REG(r, PT_ORIG_R3) |
| 53 | #define UM_SYSCALL_ARG2(r) UM_REG(r, PT_R4) |
| 54 | #define UM_SYSCALL_ARG3(r) UM_REG(r, PT_R5) |
| 55 | #define UM_SYSCALL_ARG4(r) UM_REG(r, PT_R6) |
| 56 | #define UM_SYSCALL_ARG5(r) UM_REG(r, PT_R7) |
| 57 | #define UM_SYSCALL_ARG6(r) UM_REG(r, PT_R8) |
| 58 | |
| 59 | #define UM_SYSCALL_NR_OFFSET (PT_R0 * sizeof(PPC_REG)) |
| 60 | #define UM_SYSCALL_RET_OFFSET (PT_R3 * sizeof(PPC_REG)) |
| 61 | #define UM_SYSCALL_ARG1_OFFSET (PT_R3 * sizeof(PPC_REG)) |
| 62 | #define UM_SYSCALL_ARG2_OFFSET (PT_R4 * sizeof(PPC_REG)) |
| 63 | #define UM_SYSCALL_ARG3_OFFSET (PT_R5 * sizeof(PPC_REG)) |
| 64 | #define UM_SYSCALL_ARG4_OFFSET (PT_R6 * sizeof(PPC_REG)) |
| 65 | #define UM_SYSCALL_ARG5_OFFSET (PT_R7 * sizeof(PPC_REG)) |
| 66 | #define UM_SYSCALL_ARG6_OFFSET (PT_R8 * sizeof(PPC_REG)) |
| 67 | #define UM_SP_OFFSET (PT_R1 * sizeof(PPC_REG)) |
| 68 | #define UM_IP_OFFSET (PT_NIP * sizeof(PPC_REG)) |
| 69 | #define UM_ELF_ZERO_OFFSET (PT_R3 * sizeof(PPC_REG)) |
| 70 | |
| 71 | #define UM_SET_SYSCALL_RETURN(_regs, result) \ |
| 72 | do { \ |
| 73 | if (result < 0) { \ |
| 74 | (_regs)->regs[PT_CCR] |= 0x10000000; \ |
| 75 | UM_SYSCALL_RET((_regs)) = -result; \ |
| 76 | } else { \ |
| 77 | UM_SYSCALL_RET((_regs)) = result; \ |
| 78 | } \ |
| 79 | } while(0) |
| 80 | |
| 81 | extern void shove_aux_table(unsigned long sp); |
| 82 | #define UM_FIX_EXEC_STACK(sp) shove_aux_table(sp); |
| 83 | |
| 84 | /* These aren't actually defined. The undefs are just to make sure |
| 85 | * everyone's clear on the concept. |
| 86 | */ |
| 87 | #undef UML_HAVE_GETREGS |
| 88 | #undef UML_HAVE_GETFPREGS |
| 89 | #undef UML_HAVE_SETREGS |
| 90 | #undef UML_HAVE_SETFPREGS |
| 91 | |
| 92 | #endif |
| 93 | |