^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * General MIPS MT support routines, usable in AP/SP and SMVP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2005 Mips Technologies, Inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/hardirq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <asm/mipsmtregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/r4kcache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) int vpelimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static int __init maxvpes(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) get_option(&str, &vpelimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) __setup("maxvpes=", maxvpes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) int tclimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static int __init maxtcs(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) get_option(&str, &tclimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) __setup("maxtcs=", maxtcs);
^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) * Dump new MIPS MT state for the core. Does not leave TCs halted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * Takes an argument which taken to be a pre-call MVPControl value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) void mips_mt_regdump(unsigned long mvpctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned long vpflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned long mvpconf0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int nvpe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int ntc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned long haltval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned long tcstatval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) vpflags = dvpe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) printk("=== MIPS MT State Dump ===\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) printk("-- Global State --\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) printk(" MVPControl Passed: %08lx\n", mvpctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) printk(" MVPControl Read: %08lx\n", vpflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) printk(" MVPConf0 : %08lx\n", (mvpconf0 = read_c0_mvpconf0()));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) ntc = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) printk("-- per-VPE State --\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) for (i = 0; i < nvpe; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) for (tc = 0; tc < ntc; tc++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) settc(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if ((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) printk(" VPE %d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) printk(" VPEControl : %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) read_vpe_c0_vpecontrol());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) printk(" VPEConf0 : %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) read_vpe_c0_vpeconf0());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) printk(" VPE%d.Status : %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) i, read_vpe_c0_status());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) printk(" VPE%d.EPC : %08lx %pS\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) i, read_vpe_c0_epc(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) (void *) read_vpe_c0_epc());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) printk(" VPE%d.Cause : %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) i, read_vpe_c0_cause());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) printk(" VPE%d.Config7 : %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) i, read_vpe_c0_config7());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) break; /* Next VPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) printk("-- per-TC State --\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) for (tc = 0; tc < ntc; tc++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) settc(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (read_tc_c0_tcbind() == read_c0_tcbind()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* Are we dumping ourself? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) haltval = 0; /* Then we're not halted, and mustn't be */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) tcstatval = flags; /* And pre-dump TCStatus is flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) printk(" TC %d (current TC with VPE EPC above)\n", tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) haltval = read_tc_c0_tchalt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) write_tc_c0_tchalt(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) tcstatval = read_tc_c0_tcstatus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) printk(" TC %d\n", tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) printk(" TCStatus : %08lx\n", tcstatval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) printk(" TCBind : %08lx\n", read_tc_c0_tcbind());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) printk(" TCRestart : %08lx %pS\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) read_tc_c0_tcrestart(), (void *) read_tc_c0_tcrestart());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) printk(" TCHalt : %08lx\n", haltval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) printk(" TCContext : %08lx\n", read_tc_c0_tccontext());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (!haltval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) write_tc_c0_tchalt(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) printk("===========================\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) evpe(vpflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static int mt_opt_rpsctl = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static int mt_opt_nblsu = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static int mt_opt_forceconfig7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int mt_opt_config7 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static int __init rpsctl_set(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) get_option(&str, &mt_opt_rpsctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) __setup("rpsctl=", rpsctl_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static int __init nblsu_set(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) get_option(&str, &mt_opt_nblsu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) __setup("nblsu=", nblsu_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int __init config7_set(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) get_option(&str, &mt_opt_config7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) mt_opt_forceconfig7 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) __setup("config7=", config7_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static unsigned int itc_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static int __init set_itc_base(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) get_option(&str, &itc_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) __setup("itcbase=", set_itc_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) void mips_mt_set_cpuoptions(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) unsigned int oconfig7 = read_c0_config7();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) unsigned int nconfig7 = oconfig7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (mt_opt_rpsctl >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) printk("34K return prediction stack override set to %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) mt_opt_rpsctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (mt_opt_rpsctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) nconfig7 |= (1 << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) nconfig7 &= ~(1 << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (mt_opt_nblsu >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) printk("34K ALU/LSU sync override set to %d.\n", mt_opt_nblsu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (mt_opt_nblsu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) nconfig7 |= (1 << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) nconfig7 &= ~(1 << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (mt_opt_forceconfig7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) printk("CP0.Config7 forced to 0x%08x.\n", mt_opt_config7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) nconfig7 = mt_opt_config7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (oconfig7 != nconfig7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) __asm__ __volatile("sync");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) write_c0_config7(nconfig7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ehb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) printk("Config7: 0x%08x\n", read_c0_config7());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (itc_base != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * Configure ITC mapping. This code is very
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * specific to the 34K core family, which uses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * a special mode bit ("ITC") in the ErrCtl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * register to enable access to ITC control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * registers via cache "tag" operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) unsigned long ectlval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) unsigned long itcblkgrn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* ErrCtl register is known as "ecc" to Linux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) ectlval = read_c0_ecc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) write_c0_ecc(ectlval | (0x1 << 26));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ehb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define INDEX_0 (0x80000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define INDEX_8 (0x80000008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* Read "cache tag" for Dcache pseudo-index 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) cache_op(Index_Load_Tag_D, INDEX_8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ehb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) itcblkgrn = read_c0_dtaglo();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) itcblkgrn &= 0xfffe0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* Set for 128 byte pitch of ITC cells */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) itcblkgrn |= 0x00000c00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* Stage in Tag register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) write_c0_dtaglo(itcblkgrn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ehb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* Write out to ITU with CACHE op */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) cache_op(Index_Store_Tag_D, INDEX_8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* Now set base address, and turn ITC on with 0x1 bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) write_c0_dtaglo((itc_base & 0xfffffc00) | 0x1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) ehb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* Write out to ITU with CACHE op */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) cache_op(Index_Store_Tag_D, INDEX_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) write_c0_ecc(ectlval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ehb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) printk("Mapped %ld ITC cells starting at 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) ((itcblkgrn & 0x7fe00000) >> 20), itc_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct class *mt_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int __init mt_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct class *mtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) mtc = class_create(THIS_MODULE, "mt");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (IS_ERR(mtc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return PTR_ERR(mtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) mt_class = mtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) subsys_initcall(mt_init);