diff options
Diffstat (limited to 'arch/mips/include')
-rw-r--r-- | arch/mips/include/asm/cpu-info.h | 6 | ||||
-rw-r--r-- | arch/mips/include/asm/processor.h | 20 | ||||
-rw-r--r-- | arch/mips/include/asm/thread_info.h | 2 | ||||
-rw-r--r-- | arch/mips/include/asm/watch.h | 32 |
4 files changed, 60 insertions, 0 deletions
diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h index 2de73dbb2e9..744cd8fb107 100644 --- a/arch/mips/include/asm/cpu-info.h +++ b/arch/mips/include/asm/cpu-info.h @@ -12,6 +12,8 @@ #ifndef __ASM_CPU_INFO_H #define __ASM_CPU_INFO_H +#include <linux/types.h> + #include <asm/cache.h> /* @@ -69,6 +71,10 @@ struct cpuinfo_mips { int tc_id; /* Thread Context number */ #endif void *data; /* Additional data */ + unsigned int watch_reg_count; /* Number that exist */ + unsigned int watch_reg_use_cnt; /* Usable by ptrace */ +#define NUM_WATCH_REGS 4 + u16 watch_reg_masks[NUM_WATCH_REGS]; } __attribute__((aligned(SMP_CACHE_BYTES))); extern struct cpuinfo_mips cpu_data[]; diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index a1e4453469f..18ee58e3944 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -105,6 +105,19 @@ struct mips_dsp_state { {0,} \ } +struct mips3264_watch_reg_state { + /* The width of watchlo is 32 in a 32 bit kernel and 64 in a + 64 bit kernel. We use unsigned long as it has the same + property. */ + unsigned long watchlo[NUM_WATCH_REGS]; + /* Only the mask and IRW bits from watchhi. */ + u16 watchhi[NUM_WATCH_REGS]; +}; + +union mips_watch_reg_state { + struct mips3264_watch_reg_state mips3264; +}; + typedef struct { unsigned long seg; } mm_segment_t; @@ -137,6 +150,9 @@ struct thread_struct { /* Saved state of the DSP ASE, if available. */ struct mips_dsp_state dsp; + /* Saved watch register state, if available. */ + union mips_watch_reg_state watch; + /* Other stuff associated with the thread. */ unsigned long cp0_badvaddr; /* Last user fault */ unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */ @@ -193,6 +209,10 @@ struct thread_struct { .dspcontrol = 0, \ }, \ /* \ + * saved watch register stuff \ + */ \ + .watch = {{{0,},},}, \ + /* \ * Other stuff associated with the process \ */ \ .cp0_badvaddr = 0, \ diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index bb3060699df..3f76de73c94 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -124,6 +124,7 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define TIF_32BIT_REGS 22 /* also implies 16/32 fprs */ #define TIF_32BIT_ADDR 23 /* 32-bit address space (o32/n32) */ #define TIF_FPUBOUND 24 /* thread bound to FPU-full CPU set */ +#define TIF_LOAD_WATCH 25 /* If set, load watch registers */ #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) @@ -140,6 +141,7 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define _TIF_32BIT_REGS (1<<TIF_32BIT_REGS) #define _TIF_32BIT_ADDR (1<<TIF_32BIT_ADDR) #define _TIF_FPUBOUND (1<<TIF_FPUBOUND) +#define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) /* work to do on interrupt/exception return */ #define _TIF_WORK_MASK (0x0000ffef & ~_TIF_SECCOMP) diff --git a/arch/mips/include/asm/watch.h b/arch/mips/include/asm/watch.h new file mode 100644 index 00000000000..20126ec7935 --- /dev/null +++ b/arch/mips/include/asm/watch.h @@ -0,0 +1,32 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 David Daney + */ +#ifndef _ASM_WATCH_H +#define _ASM_WATCH_H + +#include <linux/bitops.h> + +#include <asm/mipsregs.h> + +void mips_install_watch_registers(void); +void mips_read_watch_registers(void); +void mips_clear_watch_registers(void); +void mips_probe_watch_registers(struct cpuinfo_mips *c); + +#ifdef CONFIG_HARDWARE_WATCHPOINTS +#define __restore_watch() do { \ + if (unlikely(test_bit(TIF_LOAD_WATCH, \ + ¤t_thread_info()->flags))) { \ + mips_install_watch_registers(); \ + } \ +} while (0) + +#else +#define __restore_watch() do {} while (0) +#endif + +#endif /* _ASM_WATCH_H */ |