Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/frv/kernel/sysctl.c
10817 views
1
/* sysctl.c: implementation of /proc/sys files relating to FRV specifically
2
*
3
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells ([email protected])
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version
9
* 2 of the License, or (at your option) any later version.
10
*/
11
12
#include <linux/sysctl.h>
13
#include <linux/proc_fs.h>
14
#include <linux/init.h>
15
#include <asm/uaccess.h>
16
17
static const char frv_cache_wback[] = "wback";
18
static const char frv_cache_wthru[] = "wthru";
19
20
static void frv_change_dcache_mode(unsigned long newmode)
21
{
22
unsigned long flags, hsr0;
23
24
local_irq_save(flags);
25
26
hsr0 = __get_HSR(0);
27
hsr0 &= ~HSR0_DCE;
28
__set_HSR(0, hsr0);
29
30
asm volatile(" dcef @(gr0,gr0),#1 \n"
31
" membar \n"
32
: : : "memory"
33
);
34
35
hsr0 = (hsr0 & ~HSR0_CBM) | newmode;
36
__set_HSR(0, hsr0);
37
hsr0 |= HSR0_DCE;
38
__set_HSR(0, hsr0);
39
40
local_irq_restore(flags);
41
42
//printk("HSR0 now %08lx\n", hsr0);
43
}
44
45
/*****************************************************************************/
46
/*
47
* handle requests to dynamically switch the write caching mode delivered by /proc
48
*/
49
static int procctl_frv_cachemode(ctl_table *table, int write,
50
void __user *buffer, size_t *lenp,
51
loff_t *ppos)
52
{
53
unsigned long hsr0;
54
char buff[8];
55
int len;
56
57
len = *lenp;
58
59
if (write) {
60
/* potential state change */
61
if (len <= 1 || len > sizeof(buff) - 1)
62
return -EINVAL;
63
64
if (copy_from_user(buff, buffer, len) != 0)
65
return -EFAULT;
66
67
if (buff[len - 1] == '\n')
68
buff[len - 1] = '\0';
69
else
70
buff[len] = '\0';
71
72
if (strcmp(buff, frv_cache_wback) == 0) {
73
/* switch dcache into write-back mode */
74
frv_change_dcache_mode(HSR0_CBM_COPY_BACK);
75
return 0;
76
}
77
78
if (strcmp(buff, frv_cache_wthru) == 0) {
79
/* switch dcache into write-through mode */
80
frv_change_dcache_mode(HSR0_CBM_WRITE_THRU);
81
return 0;
82
}
83
84
return -EINVAL;
85
}
86
87
/* read the state */
88
if (*ppos > 0) {
89
*lenp = 0;
90
return 0;
91
}
92
93
hsr0 = __get_HSR(0);
94
switch (hsr0 & HSR0_CBM) {
95
case HSR0_CBM_WRITE_THRU:
96
memcpy(buff, frv_cache_wthru, sizeof(frv_cache_wthru) - 1);
97
buff[sizeof(frv_cache_wthru) - 1] = '\n';
98
len = sizeof(frv_cache_wthru);
99
break;
100
default:
101
memcpy(buff, frv_cache_wback, sizeof(frv_cache_wback) - 1);
102
buff[sizeof(frv_cache_wback) - 1] = '\n';
103
len = sizeof(frv_cache_wback);
104
break;
105
}
106
107
if (len > *lenp)
108
len = *lenp;
109
110
if (copy_to_user(buffer, buff, len) != 0)
111
return -EFAULT;
112
113
*lenp = len;
114
*ppos = len;
115
return 0;
116
117
} /* end procctl_frv_cachemode() */
118
119
/*****************************************************************************/
120
/*
121
* permit the mm_struct the nominated process is using have its MMU context ID pinned
122
*/
123
#ifdef CONFIG_MMU
124
static int procctl_frv_pin_cxnr(ctl_table *table, int write,
125
void __user *buffer, size_t *lenp,
126
loff_t *ppos)
127
{
128
pid_t pid;
129
char buff[16], *p;
130
int len;
131
132
len = *lenp;
133
134
if (write) {
135
/* potential state change */
136
if (len <= 1 || len > sizeof(buff) - 1)
137
return -EINVAL;
138
139
if (copy_from_user(buff, buffer, len) != 0)
140
return -EFAULT;
141
142
if (buff[len - 1] == '\n')
143
buff[len - 1] = '\0';
144
else
145
buff[len] = '\0';
146
147
pid = simple_strtoul(buff, &p, 10);
148
if (*p)
149
return -EINVAL;
150
151
return cxn_pin_by_pid(pid);
152
}
153
154
/* read the currently pinned CXN */
155
if (*ppos > 0) {
156
*lenp = 0;
157
return 0;
158
}
159
160
len = snprintf(buff, sizeof(buff), "%d\n", cxn_pinned);
161
if (len > *lenp)
162
len = *lenp;
163
164
if (copy_to_user(buffer, buff, len) != 0)
165
return -EFAULT;
166
167
*lenp = len;
168
*ppos = len;
169
return 0;
170
171
} /* end procctl_frv_pin_cxnr() */
172
#endif
173
174
/*
175
* FR-V specific sysctls
176
*/
177
static struct ctl_table frv_table[] =
178
{
179
{
180
.procname = "cache-mode",
181
.data = NULL,
182
.maxlen = 0,
183
.mode = 0644,
184
.proc_handler = procctl_frv_cachemode,
185
},
186
#ifdef CONFIG_MMU
187
{
188
.procname = "pin-cxnr",
189
.data = NULL,
190
.maxlen = 0,
191
.mode = 0644,
192
.proc_handler = procctl_frv_pin_cxnr
193
},
194
#endif
195
{}
196
};
197
198
/*
199
* Use a temporary sysctl number. Horrid, but will be cleaned up in 2.6
200
* when all the PM interfaces exist nicely.
201
*/
202
static struct ctl_table frv_dir_table[] =
203
{
204
{
205
.procname = "frv",
206
.mode = 0555,
207
.child = frv_table
208
},
209
{}
210
};
211
212
/*
213
* Initialize power interface
214
*/
215
static int __init frv_sysctl_init(void)
216
{
217
register_sysctl_table(frv_dir_table);
218
return 0;
219
}
220
221
__initcall(frv_sysctl_init);
222
223