#ifndef BPREGS_H
#define BPREGS_H

#include <sys/user.h>

/*
 * ptrace addr offsets for setting debug registers.
 */
static const struct user *u_dummy = NULL;

#define U_OFFSET(x)	((unsigned long) &u_dummy->x)
#define DBGREG_REG(n)	U_OFFSET(u_debugreg[(n)])
#define DBGREG_REG0	U_OFFSET(u_debugreg[0])
#define DBGREG_REG1	U_OFFSET(u_debugreg[1])
#define DBGREG_REG2	U_OFFSET(u_debugreg[2])
#define DBGREG_REG3	U_OFFSET(u_debugreg[3])
#define DBGREG_STAT	U_OFFSET(u_debugreg[6])
#define DBGREG_CTRL	U_OFFSET(u_debugreg[7])

/*
 * status flags
 */
#define DBGSTAT_B0HIT		(1 << 0)
#define DBGSTAT_B1HIT		(1 << 1)
#define DBGSTAT_B2HIT		(1 << 2)
#define DBGSTAT_B3HIT		(1 << 3)
#define DBGSTAT_BD		(1 << 13)
#define DBGSTAT_BS		(1 << 14)
#define DBGSTAT_BT		(1 << 15)

/*
 * control flags
 */
#define DBGCTRL_LNEN(n)		(1 << ((n) * 2))

#define DBGCTRL_L0EN		(1 << 0)
#define DBGCTRL_G0EN		(1 << 1)
#define DBGCTRL_L1EN		(1 << 2)
#define DBGCTRL_G1EN		(1 << 3)
#define DBGCTRL_L2EN		(1 << 4)
#define DBGCTRL_G2EN		(1 << 5)
#define DBGCTRL_L3EN		(1 << 6)
#define DBGCTRL_G3EN		(1 << 7)
#define DBGCTRL_LEXACT		(1 << 8)
#define DBGCTRL_GEXACT		(1 << 9)

#define DBGCTRL_RW_CODEFETCH	0
#define DBGCTRL_RW_DATAWRITE	1
#define DBGCTRL_RW_RESERVED	2
#define DBGCTRL_RW_DATARDWR	3

#define DBGCTRL_RW_SHIFT(n)	(16 + (n) * 4)

#define DBGCTRL_RW0_CODEFETCH	(DBGCTRL_RW_CODEFETCH << DBGCTRL_RW_SHIFT(0))
#define DBGCTRL_RW0_DATAWRITE	(DBGCTRL_RW_DATAWRITE << DBGCTRL_RW_SHIFT(0))
#define DBGCTRL_RW0_DATARDWR	(DBGCTRL_RW_DATARDWR  << DBGCTRL_RW_SHIFT(0))

#define DBGCTRL_RW1_CODEFETCH	(DBGCTRL_RW_CODEFETCH << DBGCTRL_RW_SHIFT(1))
#define DBGCTRL_RW1_DATAWRITE	(DBGCTRL_RW_DATAWRITE << DBGCTRL_RW_SHIFT(1))
#define DBGCTRL_RW1_DATARDWR	(DBGCTRL_RW_DATARDWR  << DBGCTRL_RW_SHIFT(1))

#define DBGCTRL_RW2_CODEFETCH	(DBGCTRL_RW_CODEFETCH << DBGCTRL_RW_SHIFT(2))
#define DBGCTRL_RW2_DATAWRITE	(DBGCTRL_RW_DATAWRITE << DBGCTRL_RW_SHIFT(2))
#define DBGCTRL_RW2_DATARDWR	(DBGCTRL_RW_DATARDWR  << DBGCTRL_RW_SHIFT(2))

#define DBGCTRL_RW3_CODEFETCH	(DBGCTRL_RW_CODEFETCH << DBGCTRL_RW_SHIFT(3))
#define DBGCTRL_RW3_DATAWRITE	(DBGCTRL_RW_DATAWRITE << DBGCTRL_RW_SHIFT(3))
#define DBGCTRL_RW3_DATARDWR	(DBGCTRL_RW_DATARDWR  << DBGCTRL_RW_SHIFT(3))

#define DBGCTRL_LEN_BYTE	0
#define DBGCTRL_LEN_WORD	1
#define DBGCTRL_LEN_RESERVED	2
#define DBGCTRL_LEN_DWORD	3

#define DBGCTRL_LEN_SHIFT(n)	(18 + (n) * 4)

#define DBGCTRL_LEN0_BYTE	(DBGCTRL_LEN_BYTE     << DBGCTRL_LEN_SHIFT(0))
#define DBGCTRL_LEN0_WORD	(DBGCTRL_LEN_WORD     << DBGCTRL_LEN_SHIFT(0))
#define DBGCTRL_LEN0_RESERVED	(DBGCTRL_LEN_RESERVED << DBGCTRL_LEN_SHIFT(0))
#define DBGCTRL_LEN0_DWORD	(DBGCTRL_LEN_DWORD    << DBGCTRL_LEN_SHIFT(0))

#define DBGCTRL_LEN1_BYTE	(DBGCTRL_LEN_BYTE     << DBGCTRL_LEN_SHIFT(1))
#define DBGCTRL_LEN1_WORD	(DBGCTRL_LEN_WORD     << DBGCTRL_LEN_SHIFT(1))
#define DBGCTRL_LEN1_RESERVED	(DBGCTRL_LEN_RESERVED << DBGCTRL_LEN_SHIFT(1))
#define DBGCTRL_LEN1_DWORD	(DBGCTRL_LEN_DWORD    << DBGCTRL_LEN_SHIFT(1))

#define DBGCTRL_LEN2_BYTE	(DBGCTRL_LEN_BYTE     << DBGCTRL_LEN_SHIFT(2))
#define DBGCTRL_LEN2_WORD	(DBGCTRL_LEN_WORD     << DBGCTRL_LEN_SHIFT(2))
#define DBGCTRL_LEN2_RESERVED	(DBGCTRL_LEN_RESERVED << DBGCTRL_LEN_SHIFT(2))
#define DBGCTRL_LEN2_DWORD	(DBGCTRL_LEN_DWORD    << DBGCTRL_LEN_SHIFT(2))

#define DBGCTRL_LEN3_BYTE	(DBGCTRL_LEN_BYTE     << DBGCTRL_LEN_SHIFT(3))
#define DBGCTRL_LEN3_WORD	(DBGCTRL_LEN_WORD     << DBGCTRL_LEN_SHIFT(3))
#define DBGCTRL_LEN3_RESERVED	(DBGCTRL_LEN_RESERVED << DBGCTRL_LEN_SHIFT(3))
#define DBGCTRL_LEN3_DWORD	(DBGCTRL_LEN_DWORD    << DBGCTRL_LEN_SHIFT(3))

#define DBGCTRL_MASK(n)		(DBGCTRL_LNEN(n) | \
				 (3 << DBGCTRL_RW_SHIFT(n)) | \
				 (3 << DBGCTRL_LEN_SHIFT(n)))

#endif /* BPREGS_H */
