Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/kernel/mips-mt.c
26424 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* General MIPS MT support routines, usable in AP/SP and SMVP.
4
* Copyright (C) 2005 Mips Technologies, Inc
5
*/
6
7
#include <linux/device.h>
8
#include <linux/kernel.h>
9
#include <linux/sched.h>
10
#include <linux/export.h>
11
#include <linux/interrupt.h>
12
#include <linux/security.h>
13
14
#include <asm/cpu.h>
15
#include <asm/processor.h>
16
#include <linux/atomic.h>
17
#include <asm/hardirq.h>
18
#include <asm/mmu_context.h>
19
#include <asm/mipsmtregs.h>
20
#include <asm/r4kcache.h>
21
#include <asm/cacheflush.h>
22
#include <asm/mips_mt.h>
23
24
int vpelimit;
25
26
static int __init maxvpes(char *str)
27
{
28
get_option(&str, &vpelimit);
29
30
return 1;
31
}
32
33
__setup("maxvpes=", maxvpes);
34
35
int tclimit;
36
37
static int __init maxtcs(char *str)
38
{
39
get_option(&str, &tclimit);
40
41
return 1;
42
}
43
44
__setup("maxtcs=", maxtcs);
45
46
static int mt_opt_rpsctl = -1;
47
static int mt_opt_nblsu = -1;
48
static int mt_opt_forceconfig7;
49
static int mt_opt_config7 = -1;
50
51
static int __init rpsctl_set(char *str)
52
{
53
get_option(&str, &mt_opt_rpsctl);
54
return 1;
55
}
56
__setup("rpsctl=", rpsctl_set);
57
58
static int __init nblsu_set(char *str)
59
{
60
get_option(&str, &mt_opt_nblsu);
61
return 1;
62
}
63
__setup("nblsu=", nblsu_set);
64
65
static int __init config7_set(char *str)
66
{
67
get_option(&str, &mt_opt_config7);
68
mt_opt_forceconfig7 = 1;
69
return 1;
70
}
71
__setup("config7=", config7_set);
72
73
static unsigned int itc_base;
74
75
static int __init set_itc_base(char *str)
76
{
77
get_option(&str, &itc_base);
78
return 1;
79
}
80
81
__setup("itcbase=", set_itc_base);
82
83
void mips_mt_set_cpuoptions(void)
84
{
85
unsigned int oconfig7 = read_c0_config7();
86
unsigned int nconfig7 = oconfig7;
87
88
if (mt_opt_rpsctl >= 0) {
89
printk("34K return prediction stack override set to %d.\n",
90
mt_opt_rpsctl);
91
if (mt_opt_rpsctl)
92
nconfig7 |= (1 << 2);
93
else
94
nconfig7 &= ~(1 << 2);
95
}
96
if (mt_opt_nblsu >= 0) {
97
printk("34K ALU/LSU sync override set to %d.\n", mt_opt_nblsu);
98
if (mt_opt_nblsu)
99
nconfig7 |= (1 << 5);
100
else
101
nconfig7 &= ~(1 << 5);
102
}
103
if (mt_opt_forceconfig7) {
104
printk("CP0.Config7 forced to 0x%08x.\n", mt_opt_config7);
105
nconfig7 = mt_opt_config7;
106
}
107
if (oconfig7 != nconfig7) {
108
__asm__ __volatile("sync");
109
write_c0_config7(nconfig7);
110
ehb();
111
printk("Config7: 0x%08x\n", read_c0_config7());
112
}
113
114
if (itc_base != 0) {
115
/*
116
* Configure ITC mapping. This code is very
117
* specific to the 34K core family, which uses
118
* a special mode bit ("ITC") in the ErrCtl
119
* register to enable access to ITC control
120
* registers via cache "tag" operations.
121
*/
122
unsigned long ectlval;
123
unsigned long itcblkgrn;
124
125
ectlval = read_c0_errctl();
126
write_c0_errctl(ectlval | (0x1 << 26));
127
ehb();
128
#define INDEX_0 (0x80000000)
129
#define INDEX_8 (0x80000008)
130
/* Read "cache tag" for Dcache pseudo-index 8 */
131
cache_op(Index_Load_Tag_D, INDEX_8);
132
ehb();
133
itcblkgrn = read_c0_dtaglo();
134
itcblkgrn &= 0xfffe0000;
135
/* Set for 128 byte pitch of ITC cells */
136
itcblkgrn |= 0x00000c00;
137
/* Stage in Tag register */
138
write_c0_dtaglo(itcblkgrn);
139
ehb();
140
/* Write out to ITU with CACHE op */
141
cache_op(Index_Store_Tag_D, INDEX_8);
142
/* Now set base address, and turn ITC on with 0x1 bit */
143
write_c0_dtaglo((itc_base & 0xfffffc00) | 0x1 );
144
ehb();
145
/* Write out to ITU with CACHE op */
146
cache_op(Index_Store_Tag_D, INDEX_0);
147
write_c0_errctl(ectlval);
148
ehb();
149
printk("Mapped %ld ITC cells starting at 0x%08x\n",
150
((itcblkgrn & 0x7fe00000) >> 20), itc_base);
151
}
152
}
153
154
const struct class mt_class = {
155
.name = "mt",
156
};
157
158
static int __init mips_mt_init(void)
159
{
160
return class_register(&mt_class);
161
}
162
163
subsys_initcall(mips_mt_init);
164
165