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