]> Git Repo - linux.git/blob - arch/loongarch/kernel/kdebugfs.c
Linux 6.14-rc3
[linux.git] / arch / loongarch / kernel / kdebugfs.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/init.h>
3 #include <linux/export.h>
4 #include <linux/debugfs.h>
5 #include <linux/kstrtox.h>
6 #include <asm/loongarch.h>
7
8 struct dentry *arch_debugfs_dir;
9 EXPORT_SYMBOL(arch_debugfs_dir);
10
11 static int sfb_state, tso_state;
12
13 static void set_sfb_state(void *info)
14 {
15         int val = *(int *)info << CSR_STFILL_SHIFT;
16
17         csr_xchg32(val, CSR_STFILL, LOONGARCH_CSR_IMPCTL1);
18 }
19
20 static ssize_t sfb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
21 {
22         int s, state;
23         char str[32];
24
25         state = (csr_read32(LOONGARCH_CSR_IMPCTL1) & CSR_STFILL) >> CSR_STFILL_SHIFT;
26
27         s = snprintf(str, sizeof(str), "Boot State: %x\nCurrent State: %x\n", sfb_state, state);
28
29         if (*ppos >= s)
30                 return 0;
31
32         s -= *ppos;
33         s = min_t(u32, s, count);
34
35         if (copy_to_user(buf, &str[*ppos], s))
36                 return -EFAULT;
37
38         *ppos += s;
39
40         return s;
41 }
42
43 static ssize_t sfb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
44 {
45         int state;
46
47         if (kstrtoint_from_user(buf, count, 10, &state))
48                 return -EFAULT;
49
50         switch (state) {
51         case 0: case 1:
52                 on_each_cpu(set_sfb_state, &state, 1);
53                 break;
54         default:
55                 return -EINVAL;
56         }
57
58         return count;
59 }
60
61 static const struct file_operations sfb_fops = {
62         .read = sfb_read,
63         .write = sfb_write,
64         .open = simple_open,
65         .llseek = default_llseek
66 };
67
68 #define LDSTORDER_NLD_NST        0x0 /* 000 = No Load No Store */
69 #define LDSTORDER_ALD_NST        0x1 /* 001 = All Load No Store */
70 #define LDSTORDER_SLD_NST        0x3 /* 011 = Same Load No Store */
71 #define LDSTORDER_NLD_AST        0x4 /* 100 = No Load All Store */
72 #define LDSTORDER_ALD_AST        0x5 /* 101 = All Load All Store */
73 #define LDSTORDER_SLD_AST        0x7 /* 111 = Same Load All Store */
74
75 static char *tso_hints[] = {
76         "No Load No Store",
77         "All Load No Store",
78         "Invalid Config",
79         "Same Load No Store",
80         "No Load All Store",
81         "All Load All Store",
82         "Invalid Config",
83         "Same Load All Store"
84 };
85
86 static void set_tso_state(void *info)
87 {
88         int val = *(int *)info << CSR_LDSTORDER_SHIFT;
89
90         csr_xchg32(val, CSR_LDSTORDER_MASK, LOONGARCH_CSR_IMPCTL1);
91 }
92
93 static ssize_t tso_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
94 {
95         int s, state;
96         char str[240];
97
98         state = (csr_read32(LOONGARCH_CSR_IMPCTL1) & CSR_LDSTORDER_MASK) >> CSR_LDSTORDER_SHIFT;
99
100         s = snprintf(str, sizeof(str), "Boot State: %d (%s)\n"
101                                        "Current State: %d (%s)\n\n"
102                                        "Available States:\n"
103                                        "0 (%s)\t" "1 (%s)\t" "3 (%s)\n"
104                                        "4 (%s)\t" "5 (%s)\t" "7 (%s)\n",
105                                        tso_state, tso_hints[tso_state], state, tso_hints[state],
106                                        tso_hints[0], tso_hints[1], tso_hints[3], tso_hints[4], tso_hints[5], tso_hints[7]);
107
108         if (*ppos >= s)
109                 return 0;
110
111         s -= *ppos;
112         s = min_t(u32, s, count);
113
114         if (copy_to_user(buf, &str[*ppos], s))
115                 return -EFAULT;
116
117         *ppos += s;
118
119         return s;
120 }
121
122 static ssize_t tso_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
123 {
124         int state;
125
126         if (kstrtoint_from_user(buf, count, 10, &state))
127                 return -EFAULT;
128
129         switch (state) {
130         case 0: case 1: case 3:
131         case 4: case 5: case 7:
132                 on_each_cpu(set_tso_state, &state, 1);
133                 break;
134         default:
135                 return -EINVAL;
136         }
137
138         return count;
139 }
140
141 static const struct file_operations tso_fops = {
142         .read = tso_read,
143         .write = tso_write,
144         .open = simple_open,
145         .llseek = default_llseek
146 };
147
148 static int __init arch_kdebugfs_init(void)
149 {
150         unsigned int config = read_cpucfg(LOONGARCH_CPUCFG3);
151
152         arch_debugfs_dir = debugfs_create_dir("loongarch", NULL);
153
154         if (config & CPUCFG3_SFB) {
155                 debugfs_create_file("sfb_state", S_IRUGO | S_IWUSR,
156                             arch_debugfs_dir, &sfb_state, &sfb_fops);
157                 sfb_state = (csr_read32(LOONGARCH_CSR_IMPCTL1) & CSR_STFILL) >> CSR_STFILL_SHIFT;
158         }
159
160         if (config & (CPUCFG3_ALDORDER_CAP | CPUCFG3_ASTORDER_CAP)) {
161                 debugfs_create_file("tso_state", S_IRUGO | S_IWUSR,
162                             arch_debugfs_dir, &tso_state, &tso_fops);
163                 tso_state = (csr_read32(LOONGARCH_CSR_IMPCTL1) & CSR_LDSTORDER_MASK) >> CSR_LDSTORDER_SHIFT;
164         }
165
166         return 0;
167 }
168 postcore_initcall(arch_kdebugfs_init);
This page took 0.040993 seconds and 4 git commands to generate.