linux/arch/mips/kernel/watch.c
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 *
   6 * Copyright (C) 2008 David Daney
   7 */
   8
   9#include <linux/sched.h>
  10
  11#include <asm/processor.h>
  12#include <asm/watch.h>
  13
  14/*
  15 * Install the watch registers for the current thread.  A maximum of
  16 * four registers are installed although the machine may have more.
  17 */
  18void mips_install_watch_registers(struct task_struct *t)
  19{
  20        struct mips3264_watch_reg_state *watches = &t->thread.watch.mips3264;
  21        switch (current_cpu_data.watch_reg_use_cnt) {
  22        default:
  23                BUG();
  24        case 4:
  25                write_c0_watchlo3(watches->watchlo[3]);
  26                /* Write 1 to the I, R, and W bits to clear them, and
  27                   1 to G so all ASIDs are trapped. */
  28                write_c0_watchhi3(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW |
  29                                  watches->watchhi[3]);
  30        case 3:
  31                write_c0_watchlo2(watches->watchlo[2]);
  32                write_c0_watchhi2(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW |
  33                                  watches->watchhi[2]);
  34        case 2:
  35                write_c0_watchlo1(watches->watchlo[1]);
  36                write_c0_watchhi1(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW |
  37                                  watches->watchhi[1]);
  38        case 1:
  39                write_c0_watchlo0(watches->watchlo[0]);
  40                write_c0_watchhi0(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW |
  41                                  watches->watchhi[0]);
  42        }
  43}
  44
  45/*
  46 * Read back the watchhi registers so the user space debugger has
  47 * access to the I, R, and W bits.  A maximum of four registers are
  48 * read although the machine may have more.
  49 */
  50void mips_read_watch_registers(void)
  51{
  52        struct mips3264_watch_reg_state *watches =
  53                &current->thread.watch.mips3264;
  54        switch (current_cpu_data.watch_reg_use_cnt) {
  55        default:
  56                BUG();
  57        case 4:
  58                watches->watchhi[3] = (read_c0_watchhi3() &
  59                                       (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW));
  60        case 3:
  61                watches->watchhi[2] = (read_c0_watchhi2() &
  62                                       (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW));
  63        case 2:
  64                watches->watchhi[1] = (read_c0_watchhi1() &
  65                                       (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW));
  66        case 1:
  67                watches->watchhi[0] = (read_c0_watchhi0() &
  68                                       (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW));
  69        }
  70        if (current_cpu_data.watch_reg_use_cnt == 1 &&
  71            (watches->watchhi[0] & MIPS_WATCHHI_IRW) == 0) {
  72                /* Pathological case of release 1 architecture that
  73                 * doesn't set the condition bits.  We assume that
  74                 * since we got here, the watch condition was met and
  75                 * signal that the conditions requested in watchlo
  76                 * were met.  */
  77                watches->watchhi[0] |= (watches->watchlo[0] & MIPS_WATCHHI_IRW);
  78        }
  79 }
  80
  81/*
  82 * Disable all watch registers.  Although only four registers are
  83 * installed, all are cleared to eliminate the possibility of endless
  84 * looping in the watch handler.
  85 */
  86void mips_clear_watch_registers(void)
  87{
  88        switch (current_cpu_data.watch_reg_count) {
  89        default:
  90                BUG();
  91        case 8:
  92                write_c0_watchlo7(0);
  93        case 7:
  94                write_c0_watchlo6(0);
  95        case 6:
  96                write_c0_watchlo5(0);
  97        case 5:
  98                write_c0_watchlo4(0);
  99        case 4:
 100                write_c0_watchlo3(0);
 101        case 3:
 102                write_c0_watchlo2(0);
 103        case 2:
 104                write_c0_watchlo1(0);
 105        case 1:
 106                write_c0_watchlo0(0);
 107        }
 108}
 109
 110void mips_probe_watch_registers(struct cpuinfo_mips *c)
 111{
 112        unsigned int t;
 113
 114        if ((c->options & MIPS_CPU_WATCH) == 0)
 115                return;
 116        /*
 117         * Check which of the I,R and W bits are supported, then
 118         * disable the register.
 119         */
 120        write_c0_watchlo0(MIPS_WATCHLO_IRW);
 121        back_to_back_c0_hazard();
 122        t = read_c0_watchlo0();
 123        write_c0_watchlo0(0);
 124        c->watch_reg_masks[0] = t & MIPS_WATCHLO_IRW;
 125
 126        /* Write the mask bits and read them back to determine which
 127         * can be used. */
 128        c->watch_reg_count = 1;
 129        c->watch_reg_use_cnt = 1;
 130        t = read_c0_watchhi0();
 131        write_c0_watchhi0(t | MIPS_WATCHHI_MASK);
 132        back_to_back_c0_hazard();
 133        t = read_c0_watchhi0();
 134        c->watch_reg_masks[0] |= (t & MIPS_WATCHHI_MASK);
 135        if ((t & MIPS_WATCHHI_M) == 0)
 136                return;
 137
 138        write_c0_watchlo1(MIPS_WATCHLO_IRW);
 139        back_to_back_c0_hazard();
 140        t = read_c0_watchlo1();
 141        write_c0_watchlo1(0);
 142        c->watch_reg_masks[1] = t & MIPS_WATCHLO_IRW;
 143
 144        c->watch_reg_count = 2;
 145        c->watch_reg_use_cnt = 2;
 146        t = read_c0_watchhi1();
 147        write_c0_watchhi1(t | MIPS_WATCHHI_MASK);
 148        back_to_back_c0_hazard();
 149        t = read_c0_watchhi1();
 150        c->watch_reg_masks[1] |= (t & MIPS_WATCHHI_MASK);
 151        if ((t & MIPS_WATCHHI_M) == 0)
 152                return;
 153
 154        write_c0_watchlo2(MIPS_WATCHLO_IRW);
 155        back_to_back_c0_hazard();
 156        t = read_c0_watchlo2();
 157        write_c0_watchlo2(0);
 158        c->watch_reg_masks[2] = t & MIPS_WATCHLO_IRW;
 159
 160        c->watch_reg_count = 3;
 161        c->watch_reg_use_cnt = 3;
 162        t = read_c0_watchhi2();
 163        write_c0_watchhi2(t | MIPS_WATCHHI_MASK);
 164        back_to_back_c0_hazard();
 165        t = read_c0_watchhi2();
 166        c->watch_reg_masks[2] |= (t & MIPS_WATCHHI_MASK);
 167        if ((t & MIPS_WATCHHI_M) == 0)
 168                return;
 169
 170        write_c0_watchlo3(MIPS_WATCHLO_IRW);
 171        back_to_back_c0_hazard();
 172        t = read_c0_watchlo3();
 173        write_c0_watchlo3(0);
 174        c->watch_reg_masks[3] = t & MIPS_WATCHLO_IRW;
 175
 176        c->watch_reg_count = 4;
 177        c->watch_reg_use_cnt = 4;
 178        t = read_c0_watchhi3();
 179        write_c0_watchhi3(t | MIPS_WATCHHI_MASK);
 180        back_to_back_c0_hazard();
 181        t = read_c0_watchhi3();
 182        c->watch_reg_masks[3] |= (t & MIPS_WATCHHI_MASK);
 183        if ((t & MIPS_WATCHHI_M) == 0)
 184                return;
 185
 186        /* We use at most 4, but probe and report up to 8. */
 187        c->watch_reg_count = 5;
 188        t = read_c0_watchhi4();
 189        if ((t & MIPS_WATCHHI_M) == 0)
 190                return;
 191
 192        c->watch_reg_count = 6;
 193        t = read_c0_watchhi5();
 194        if ((t & MIPS_WATCHHI_M) == 0)
 195                return;
 196
 197        c->watch_reg_count = 7;
 198        t = read_c0_watchhi6();
 199        if ((t & MIPS_WATCHHI_M) == 0)
 200                return;
 201
 202        c->watch_reg_count = 8;
 203}
 204