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