11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1998-2004 Hewlett-Packard Co
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	David Mosberger-Tang <davidm@hpl.hp.com>
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Stephane Eranian <eranian@hpl.hp.com>
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2003 Intel Co
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Suresh Siddha <suresh.b.siddha@intel.com>
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Fenghua Yu <fenghua.yu@intel.com>
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Arun Sharma <arun.sharma@intel.com>
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 12/07/98	S. Eranian	added pt_regs & switch_stack
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 12/21/98	D. Mosberger	updated to match latest code
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  6/17/99	D. Mosberger	added second unat member to "struct switch_stack"
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1543e40f25d2c090392fc36cb900b42972e88cc2e2David Howells#ifndef _ASM_IA64_PTRACE_H
1643e40f25d2c090392fc36cb900b42972e88cc2e2David Howells#define _ASM_IA64_PTRACE_H
17d5759641f5809b19bad4e2af6ca97b830545aabaDavid Woodhouse
1882f1b07b9ad88066c0fa867dd6b32ce43ae7ad22Tony Luck#ifndef ASM_OFFSETS_C
190013a85454c281faaf064ccb576e373a2881aac8Sam Ravnborg#include <asm/asm-offsets.h>
2082f1b07b9ad88066c0fa867dd6b32ce43ae7ad22Tony Luck#endif
2143e40f25d2c090392fc36cb900b42972e88cc2e2David Howells#include <uapi/asm/ptrace.h>
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Base-2 logarithm of number of pages to allocate per task structure
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (including register backing store and memory stack):
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(CONFIG_IA64_PAGE_SIZE_4KB)
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds# define KERNEL_STACK_SIZE_ORDER		3
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#elif defined(CONFIG_IA64_PAGE_SIZE_8KB)
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds# define KERNEL_STACK_SIZE_ORDER		2
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#elif defined(CONFIG_IA64_PAGE_SIZE_16KB)
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds# define KERNEL_STACK_SIZE_ORDER		1
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds# define KERNEL_STACK_SIZE_ORDER		0
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
374dcc29e1574d88f4465ba865ed82800032f76418Tony Luck#define IA64_RBS_OFFSET			((IA64_TASK_SIZE + IA64_THREAD_INFO_SIZE + 31) & ~31)
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IA64_STK_OFFSET			((1 << KERNEL_STACK_SIZE_ORDER)*PAGE_SIZE)
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define KERNEL_STACK_SIZE		IA64_STK_OFFSET
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
42d5759641f5809b19bad4e2af6ca97b830545aabaDavid Woodhouse#ifndef __ASSEMBLY__
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
44d5759641f5809b19bad4e2af6ca97b830545aabaDavid Woodhouse#include <asm/current.h>
45d5759641f5809b19bad4e2af6ca97b830545aabaDavid Woodhouse#include <asm/page.h>
46d5759641f5809b19bad4e2af6ca97b830545aabaDavid Woodhouse
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We use the ia64_psr(regs)->ri to determine which of the three
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * instructions in bundle (16 bytes) took the sample. Generate
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the canonical representation by adding to instruction pointer.
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds# define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri)
53b3f827cb0fe0660c2eacea2c2f9bdb1f225ff768Ananth N Mavinakayanahalli
54cfb361f13c8136de78c406745abc4e4456e6d480Shaohua Listatic inline unsigned long user_stack_pointer(struct pt_regs *regs)
55cfb361f13c8136de78c406745abc4e4456e6d480Shaohua Li{
56cfb361f13c8136de78c406745abc4e4456e6d480Shaohua Li	/* FIXME: should this be bspstore + nr_dirty regs? */
57cfb361f13c8136de78c406745abc4e4456e6d480Shaohua Li	return regs->ar_bspstore;
58cfb361f13c8136de78c406745abc4e4456e6d480Shaohua Li}
59cfb361f13c8136de78c406745abc4e4456e6d480Shaohua Li
60d7e7528bcd456f5c36ad4a202ccfb43c5aa98bc4Eric Parisstatic inline int is_syscall_success(struct pt_regs *regs)
61d7e7528bcd456f5c36ad4a202ccfb43c5aa98bc4Eric Paris{
62d7e7528bcd456f5c36ad4a202ccfb43c5aa98bc4Eric Paris	return regs->r10 != -1;
63d7e7528bcd456f5c36ad4a202ccfb43c5aa98bc4Eric Paris}
64d7e7528bcd456f5c36ad4a202ccfb43c5aa98bc4Eric Paris
65d7e7528bcd456f5c36ad4a202ccfb43c5aa98bc4Eric Parisstatic inline long regs_return_value(struct pt_regs *regs)
66d7e7528bcd456f5c36ad4a202ccfb43c5aa98bc4Eric Paris{
67d7e7528bcd456f5c36ad4a202ccfb43c5aa98bc4Eric Paris	if (is_syscall_success(regs))
68d7e7528bcd456f5c36ad4a202ccfb43c5aa98bc4Eric Paris		return regs->r8;
69d7e7528bcd456f5c36ad4a202ccfb43c5aa98bc4Eric Paris	else
70d7e7528bcd456f5c36ad4a202ccfb43c5aa98bc4Eric Paris		return -regs->r8;
71d7e7528bcd456f5c36ad4a202ccfb43c5aa98bc4Eric Paris}
72b3f827cb0fe0660c2eacea2c2f9bdb1f225ff768Ananth N Mavinakayanahalli
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Conserve space in histogram by encoding slot bits in address
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bits 2 and 3 rather than bits 0 and 1.
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define profile_pc(regs)						\
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds({									\
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long __ip = instruction_pointer(regs);			\
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	(__ip & ~3UL) + ((__ip & 3UL) << 2);				\
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds})
811ca97bb541a1f5a735e697a8bba763cde3aab452Al Viro/*
821ca97bb541a1f5a735e697a8bba763cde3aab452Al Viro * Why not default?  Because user_stack_pointer() on ia64 gives register
831ca97bb541a1f5a735e697a8bba763cde3aab452Al Viro * stack backing store instead...
841ca97bb541a1f5a735e697a8bba763cde3aab452Al Viro */
851ca97bb541a1f5a735e697a8bba763cde3aab452Al Viro#define current_user_stack_pointer() (current_pt_regs()->r12)
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  /* given a pointer to a task_struct, return the user's pt_regs */
886450578f32cdca587ae5f148e2118b2fcc36bb11Al Viro# define task_pt_regs(t)		(((struct pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1)
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds# define ia64_psr(regs)			((struct ia64_psr *) &(regs)->cr_ipsr)
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds# define user_mode(regs)		(((struct ia64_psr *) &(regs)->cr_ipsr)->cpl != 0)
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds# define user_stack(task,regs)	((long) regs - (long) task == IA64_STK_OFFSET - sizeof(*regs))
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds# define fsys_mode(task,regs)					\
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  ({								\
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  struct task_struct *_task = (task);			\
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  struct pt_regs *_regs = (regs);			\
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  !user_mode(_regs) && user_stack(_task, _regs);	\
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  })
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  /*
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   * System call handlers that, upon successful completion, need to return a negative value
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   * should call force_successful_syscall_return() right before returning.  On architectures
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   * where the syscall convention provides for a separate error flag (e.g., alpha, ia64,
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   * ppc{,64}, sparc{,64}, possibly others), this macro can be used to ensure that the error
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   * flag will not get set.  On architectures which do not support a separate error flag,
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   * the macro is a no-op and the spurious error condition needs to be filtered out by some
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   * other means (e.g., in user-level, by passing an extra argument to the syscall handler,
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   * or something along those lines).
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   *
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   * On ia64, we can clear the user's pt_regs->r8 to force a successful syscall.
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   */
1116450578f32cdca587ae5f148e2118b2fcc36bb11Al Viro# define force_successful_syscall_return()	(task_pt_regs(current)->r8 = 0)
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  struct task_struct;			/* forward decl */
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  struct unw_frame_info;		/* forward decl */
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  extern void ia64_do_show_stack (struct unw_frame_info *, void *);
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  extern unsigned long ia64_get_user_rbs_end (struct task_struct *, struct pt_regs *,
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					      unsigned long *);
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  extern long ia64_peek (struct task_struct *, struct switch_stack *, unsigned long,
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 unsigned long, long *);
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  extern long ia64_poke (struct task_struct *, struct switch_stack *, unsigned long,
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 unsigned long, long);
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  extern void ia64_flush_fph (struct task_struct *);
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  extern void ia64_sync_fph (struct task_struct *);
1253b2ce0b17824c42bc2e46f7dd903b4acf5e9fff9Petr Tesarik  extern void ia64_sync_krbs(void);
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  extern long ia64_sync_user_rbs (struct task_struct *, struct switch_stack *,
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				  unsigned long, unsigned long);
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  /* get nat bits for scratch registers such that bit N==1 iff scratch register rN is a NaT */
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  extern unsigned long ia64_get_scratch_nat_bits (struct pt_regs *pt, unsigned long scratch_unat);
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  /* put nat bits for scratch registers such that scratch register rN is a NaT iff bit N==1 */
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  extern unsigned long ia64_put_scratch_nat_bits (struct pt_regs *pt, unsigned long nat);
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  extern void ia64_increment_ip (struct pt_regs *pt);
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  extern void ia64_decrement_ip (struct pt_regs *pt);
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1373b2ce0b17824c42bc2e46f7dd903b4acf5e9fff9Petr Tesarik  extern void ia64_ptrace_stop(void);
1383b2ce0b17824c42bc2e46f7dd903b4acf5e9fff9Petr Tesarik  #define arch_ptrace_stop(code, info) \
1393b2ce0b17824c42bc2e46f7dd903b4acf5e9fff9Petr Tesarik	ia64_ptrace_stop()
1403b2ce0b17824c42bc2e46f7dd903b4acf5e9fff9Petr Tesarik  #define arch_ptrace_stop_needed(code, info) \
1413b2ce0b17824c42bc2e46f7dd903b4acf5e9fff9Petr Tesarik	(!test_thread_flag(TIF_RESTORE_RSE))
1423b2ce0b17824c42bc2e46f7dd903b4acf5e9fff9Petr Tesarik
143aa91a2e90044b88228bdb0620e771f2ea7798804Petr Tesarik  extern void ptrace_attach_sync_user_rbs (struct task_struct *);
144aa91a2e90044b88228bdb0620e771f2ea7798804Petr Tesarik  #define arch_ptrace_attach(child) \
145aa91a2e90044b88228bdb0620e771f2ea7798804Petr Tesarik	ptrace_attach_sync_user_rbs(child)
146aa91a2e90044b88228bdb0620e771f2ea7798804Petr Tesarik
1478db3f5254151c3a06a764bbb18283570ba1897bfPetr Tesarik  #define arch_has_single_step()  (1)
1488db3f5254151c3a06a764bbb18283570ba1897bfPetr Tesarik  #define arch_has_block_step()   (1)
1498db3f5254151c3a06a764bbb18283570ba1897bfPetr Tesarik
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* !__ASSEMBLY__ */
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* _ASM_IA64_PTRACE_H */
152