Skip to content

Commit

Permalink
metag: ptrace
Browse files Browse the repository at this point in the history
The ptrace interface for metag provides access to some core register
sets using the PTRACE_GETREGSET and PTRACE_SETREGSET operations. The
details of the internal context structures is abstracted into user API
structures to both ease use and allow flexibility to change the internal
context layouts. Copyin and copyout functions for these register sets
are exposed to allow signal handling code to use them to copy to and
from the signal context.

struct user_gp_regs (NT_PRSTATUS) provides access to the core general
purpose register context.

struct user_cb_regs (NT_METAG_CBUF) provides access to the TXCATCH*
registers which contains information abuot a memory fault, unaligned
access error or watchpoint. This can be modified to alter the way the
fault is replayed on resume ("catch replay"), or to prevent the replay
taking place.

struct user_rp_state (NT_METAG_RPIPE) provides access to the state of
the Meta read pipeline which can be used to hide memory latencies in
hand optimised data loops.

Extended DSP register state, DSP RAM, and hardware breakpoint registers
aren't yet exposed through ptrace.

Signed-off-by: James Hogan <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Denys Vlasenko <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Tony Lindgren <[email protected]>
Cc: "Paul E. McKenney" <[email protected]>
  • Loading branch information
James Hogan committed Mar 2, 2013
1 parent 29dd78c commit bc3966b
Show file tree
Hide file tree
Showing 4 changed files with 555 additions and 0 deletions.
60 changes: 60 additions & 0 deletions arch/metag/include/asm/ptrace.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#ifndef _METAG_PTRACE_H
#define _METAG_PTRACE_H

#include <linux/compiler.h>
#include <uapi/asm/ptrace.h>
#include <asm/tbx.h>

#ifndef __ASSEMBLY__

/* this struct defines the way the registers are stored on the
stack during a system call. */

struct pt_regs {
TBICTX ctx;
TBICTXEXTCB0 extcb0[5];
};

#define user_mode(regs) (((regs)->ctx.SaveMask & TBICTX_PRIV_BIT) > 0)

#define instruction_pointer(regs) ((unsigned long)(regs)->ctx.CurrPC)
#define profile_pc(regs) instruction_pointer(regs)

#define task_pt_regs(task) \
((struct pt_regs *)(task_stack_page(task) + \
sizeof(struct thread_info)))

#define current_pt_regs() \
((struct pt_regs *)((char *)current_thread_info() + \
sizeof(struct thread_info)))

int syscall_trace_enter(struct pt_regs *regs);
void syscall_trace_leave(struct pt_regs *regs);

/* copy a struct user_gp_regs out to user */
int metag_gp_regs_copyout(const struct pt_regs *regs,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf);
/* copy a struct user_gp_regs in from user */
int metag_gp_regs_copyin(struct pt_regs *regs,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf);
/* copy a struct user_cb_regs out to user */
int metag_cb_regs_copyout(const struct pt_regs *regs,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf);
/* copy a struct user_cb_regs in from user */
int metag_cb_regs_copyin(struct pt_regs *regs,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf);
/* copy a struct user_rp_state out to user */
int metag_rp_state_copyout(const struct pt_regs *regs,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf);
/* copy a struct user_rp_state in from user */
int metag_rp_state_copyin(struct pt_regs *regs,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf);

#endif /* __ASSEMBLY__ */
#endif /* _METAG_PTRACE_H */
113 changes: 113 additions & 0 deletions arch/metag/include/uapi/asm/ptrace.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#ifndef _UAPI_METAG_PTRACE_H
#define _UAPI_METAG_PTRACE_H

#ifndef __ASSEMBLY__

/*
* These are the layouts of the regsets returned by the GETREGSET ptrace call
*/

/* user_gp_regs::status */

/* CBMarker bit (indicates catch state / catch replay) */
#define USER_GP_REGS_STATUS_CATCH_BIT (1 << 22)
#define USER_GP_REGS_STATUS_CATCH_S 22
/* LSM_STEP field (load/store multiple step) */
#define USER_GP_REGS_STATUS_LSM_STEP_BITS (0x7 << 8)
#define USER_GP_REGS_STATUS_LSM_STEP_S 8
/* SCC bit (indicates split 16x16 condition flags) */
#define USER_GP_REGS_STATUS_SCC_BIT (1 << 4)
#define USER_GP_REGS_STATUS_SCC_S 4

/* normal condition flags */
/* CF_Z bit (Zero flag) */
#define USER_GP_REGS_STATUS_CF_Z_BIT (1 << 3)
#define USER_GP_REGS_STATUS_CF_Z_S 3
/* CF_N bit (Negative flag) */
#define USER_GP_REGS_STATUS_CF_N_BIT (1 << 2)
#define USER_GP_REGS_STATUS_CF_N_S 2
/* CF_V bit (oVerflow flag) */
#define USER_GP_REGS_STATUS_CF_V_BIT (1 << 1)
#define USER_GP_REGS_STATUS_CF_V_S 1
/* CF_C bit (Carry flag) */
#define USER_GP_REGS_STATUS_CF_C_BIT (1 << 0)
#define USER_GP_REGS_STATUS_CF_C_S 0

/* split 16x16 condition flags */
/* SCF_LZ bit (Low Zero flag) */
#define USER_GP_REGS_STATUS_SCF_LZ_BIT (1 << 3)
#define USER_GP_REGS_STATUS_SCF_LZ_S 3
/* SCF_HZ bit (High Zero flag) */
#define USER_GP_REGS_STATUS_SCF_HZ_BIT (1 << 2)
#define USER_GP_REGS_STATUS_SCF_HZ_S 2
/* SCF_HC bit (High Carry flag) */
#define USER_GP_REGS_STATUS_SCF_HC_BIT (1 << 1)
#define USER_GP_REGS_STATUS_SCF_HC_S 1
/* SCF_LC bit (Low Carry flag) */
#define USER_GP_REGS_STATUS_SCF_LC_BIT (1 << 0)
#define USER_GP_REGS_STATUS_SCF_LC_S 0

/**
* struct user_gp_regs - User general purpose registers
* @dx: GP data unit regs (dx[reg][unit] = D{unit:0-1}.{reg:0-7})
* @ax: GP address unit regs (ax[reg][unit] = A{unit:0-1}.{reg:0-3})
* @pc: PC register
* @status: TXSTATUS register (condition flags, LSM_STEP etc)
* @rpt: TXRPT registers (branch repeat counter)
* @bpobits: TXBPOBITS register ("branch prediction other" bits)
* @mode: TXMODE register
* @_pad1: Reserved padding to make sizeof obviously 64bit aligned
*
* This is the user-visible general purpose register state structure.
*
* It can be accessed through PTRACE_GETREGSET with NT_PRSTATUS.
*
* It is also used in the signal context.
*/
struct user_gp_regs {
unsigned long dx[8][2];
unsigned long ax[4][2];
unsigned long pc;
unsigned long status;
unsigned long rpt;
unsigned long bpobits;
unsigned long mode;
unsigned long _pad1;
};

/**
* struct user_cb_regs - User catch buffer registers
* @flags: TXCATCH0 register (fault flags)
* @addr: TXCATCH1 register (fault address)
* @data: TXCATCH2 and TXCATCH3 registers (low and high data word)
*
* This is the user-visible catch buffer register state structure containing
* information about a failed memory access, and allowing the access to be
* modified and replayed.
*
* It can be accessed through PTRACE_GETREGSET with NT_METAG_CBUF.
*/
struct user_cb_regs {
unsigned long flags;
unsigned long addr;
unsigned long long data;
};

/**
* struct user_rp_state - User read pipeline state
* @entries: Read pipeline entries
* @mask: Mask of valid pipeline entries (RPMask from TXDIVTIME register)
*
* This is the user-visible read pipeline state structure containing the entries
* currently in the read pipeline and the mask of valid entries.
*
* It can be accessed through PTRACE_GETREGSET with NT_METAG_RPIPE.
*/
struct user_rp_state {
unsigned long long entries[6];
unsigned long mask;
};

#endif /* __ASSEMBLY__ */

#endif /* _UAPI_METAG_PTRACE_H */
Loading

0 comments on commit bc3966b

Please sign in to comment.