...
...
15
value may has been initialized to 0. we need just check the tlb_e
15
value may has been initialized to 0. we need just check the tlb_e
16
skip the function and check tlb_ps write a guest log.
16
skip the function and check tlb_ps write a guest log.
17
3. csrwr instructions.
17
3. csrwr instructions.
18
to make sure CSR_PWCL.PTBASE and CSR_STLBPS.PS bits are avalable,
18
to make sure CSR_PWCL.PTBASE and CSR_STLBPS.PS bits are avalable,
19
cheke theses bits and set a default value from CSR_PRCFG2.
19
cheke theses bits and set a default value from CSR_PRCFG2.
20
21
22
v7:
23
clean code and rebase.
24
25
v6:
26
1 clean code. fix code style.
27
2 rebase and R-b.
20
28
21
V5:
29
V5:
22
1 Add add chek_ps() function to check tlb_ps with CSR_PRCFG2;
30
1 Add add chek_ps() function to check tlb_ps with CSR_PRCFG2;
23
2 Some tlb instuctions, just check tlb_ps, do't rewrite the tlb_ps
31
2 Some tlb instuctions, just check tlb_ps, do't rewrite the tlb_ps
24
bits just write a guest log;
32
bits just write a guest log;
...
...
diff view generated by jsdifflib
1
some tlb instructions get the tlb_ps from tlb->misc but the
1
some tlb instructions get the tlb_ps from tlb->misc but the
2
value may has been initialized to 0,just check the tlb_ps skip
2
value may has been initialized to 0,just check the tlb_ps skip
3
the function and write a log.
3
the function and write a log.
4
4
5
Signed-off-by: Song Gao <gaosong@loongson.cn>
5
Signed-off-by: Song Gao <gaosong@loongson.cn>
6
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
6
---
7
---
7
target/loongarch/tcg/tlb_helper.c | 8 ++++++++
8
target/loongarch/tcg/tlb_helper.c | 12 ++++++++++++
8
1 file changed, 8 insertions(+)
9
1 file changed, 12 insertions(+)
9
10
10
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
11
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
11
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
12
--- a/target/loongarch/tcg/tlb_helper.c
13
--- a/target/loongarch/tcg/tlb_helper.c
13
+++ b/target/loongarch/tcg/tlb_helper.c
14
+++ b/target/loongarch/tcg/tlb_helper.c
15
@@ -XXX,XX +XXX,XX @@ static void invalidate_tlb_entry(CPULoongArchState *env, int index)
16
uint8_t tlb_v0 = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, V);
17
uint8_t tlb_v1 = FIELD_EX64(tlb->tlb_entry1, TLBENTRY, V);
18
uint64_t tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
19
+ uint8_t tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
20
21
+ if (!tlb_e) {
22
+ return;
23
+ }
24
if (index >= LOONGARCH_STLB) {
25
tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
26
} else {
14
@@ -XXX,XX +XXX,XX @@ void helper_invtlb_page_asid(CPULoongArchState *env, target_ulong info,
27
@@ -XXX,XX +XXX,XX @@ void helper_invtlb_page_asid(CPULoongArchState *env, target_ulong info,
15
uint16_t tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
28
uint16_t tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
16
uint64_t vpn, tlb_vppn;
29
uint64_t vpn, tlb_vppn;
17
uint8_t tlb_ps, compare_shift;
30
uint8_t tlb_ps, compare_shift;
18
+ uint8_t tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
31
+ uint8_t tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
19
32
20
+ if (!tlb_e){
33
+ if (!tlb_e) {
21
+ continue;
34
+ continue;
22
+ }
35
+ }
23
if (i >= LOONGARCH_STLB) {
36
if (i >= LOONGARCH_STLB) {
24
tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
37
tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
25
} else {
38
} else {
26
@@ -XXX,XX +XXX,XX @@ void helper_invtlb_page_asid_or_g(CPULoongArchState *env,
39
@@ -XXX,XX +XXX,XX @@ void helper_invtlb_page_asid_or_g(CPULoongArchState *env,
27
uint16_t tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
40
uint16_t tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
28
uint64_t vpn, tlb_vppn;
41
uint64_t vpn, tlb_vppn;
29
uint8_t tlb_ps, compare_shift;
42
uint8_t tlb_ps, compare_shift;
30
+ uint8_t tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
43
+ uint8_t tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
31
44
32
+ if (!tlb_e){
45
+ if (!tlb_e) {
33
+ continue;
46
+ continue;
34
+ }
47
+ }
35
if (i >= LOONGARCH_STLB) {
48
if (i >= LOONGARCH_STLB) {
36
tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
49
tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
37
} else {
50
} else {
38
--
51
--
39
2.34.1
52
2.34.1
diff view generated by jsdifflib
...
...
14
to make sure CSR_PWCL.PTBASE and CSR_STLBPS.PS bits are avalable,
14
to make sure CSR_PWCL.PTBASE and CSR_STLBPS.PS bits are avalable,
15
cheke theses bits and set a default value from CSR_PRCFG2.
15
cheke theses bits and set a default value from CSR_PRCFG2.
16
16
17
Signed-off-by: Song Gao <gaosong@loongson.cn>
17
Signed-off-by: Song Gao <gaosong@loongson.cn>
18
---
18
---
19
target/loongarch/cpu.c | 10 ++--
19
target/loongarch/cpu.c | 11 +++++---
20
target/loongarch/cpu_helper.c | 8 +++-
21
target/loongarch/helper.h | 1 +
20
target/loongarch/helper.h | 1 +
22
target/loongarch/internals.h | 2 +
21
target/loongarch/internals.h | 2 ++
23
target/loongarch/tcg/csr_helper.c | 30 +++++++++++-
22
target/loongarch/tcg/csr_helper.c | 27 +++++++++++++++++--
24
.../tcg/insn_trans/trans_privileged.c.inc | 1 +
23
.../tcg/insn_trans/trans_privileged.c.inc | 1 +
25
target/loongarch/tcg/tlb_helper.c | 46 ++++++++++++++++++-
24
target/loongarch/tcg/tlb_helper.c | 23 ++++++++++++++--
26
7 files changed, 90 insertions(+), 8 deletions(-)
25
6 files changed, 58 insertions(+), 7 deletions(-)
27
26
28
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
27
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
29
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
30
--- a/target/loongarch/cpu.c
29
--- a/target/loongarch/cpu.c
31
+++ b/target/loongarch/cpu.c
30
+++ b/target/loongarch/cpu.c
31
@@ -XXX,XX +XXX,XX @@ static void loongarch_max_initfn(Object *obj)
32
33
static void loongarch_cpu_reset_hold(Object *obj, ResetType type)
34
{
35
+ uint8_t tlb_ps;
36
CPUState *cs = CPU(obj);
37
LoongArchCPUClass *lacc = LOONGARCH_CPU_GET_CLASS(obj);
38
CPULoongArchState *env = cpu_env(cs);
32
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type)
39
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type)
33
*/
40
*/
34
env->CSR_PGDH = 0;
41
env->CSR_PGDH = 0;
35
env->CSR_PGDL = 0;
42
env->CSR_PGDL = 0;
36
- env->CSR_PWCL = 0;
43
- env->CSR_PWCL = 0;
...
...
40
env->CSR_TLBRENTRY = 0;
47
env->CSR_TLBRENTRY = 0;
41
env->CSR_MERRENTRY = 0;
48
env->CSR_MERRENTRY = 0;
42
-
49
-
43
+ /* set CSR_PWCL.PTBASE and CSR_STLBPS.PS bits from CSR_PRCFG2 */
50
+ /* set CSR_PWCL.PTBASE and CSR_STLBPS.PS bits from CSR_PRCFG2 */
44
+ if (env->CSR_PRCFG2 == 0) {
51
+ if (env->CSR_PRCFG2 == 0) {
45
+ env->CSR_PRCFG2 =0x3fffff000;
52
+ env->CSR_PRCFG2 = 0x3fffff000;
46
+ }
53
+ }
47
+ int tlb_ps = clz32(env->CSR_PRCFG2);
54
+ tlb_ps = ctz32(env->CSR_PRCFG2);
48
+ env->CSR_STLBPS = FIELD_DP64(env->CSR_STLBPS, CSR_STLBPS, PS, tlb_ps);
55
+ env->CSR_STLBPS = FIELD_DP64(env->CSR_STLBPS, CSR_STLBPS, PS, tlb_ps);
49
+ env->CSR_PWCL = FIELD_DP64(env->CSR_PWCL, CSR_PWCL, PTBASE, tlb_ps);
56
+ env->CSR_PWCL = FIELD_DP64(env->CSR_PWCL, CSR_PWCL, PTBASE, tlb_ps);
50
for (n = 0; n < 4; n++) {
57
for (n = 0; n < 4; n++) {
51
env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV0, 0);
58
env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV0, 0);
52
env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV1, 0);
59
env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV1, 0);
53
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/loongarch/cpu_helper.c
56
+++ b/target/loongarch/cpu_helper.c
57
@@ -XXX,XX +XXX,XX @@ bool loongarch_tlb_search(CPULoongArchState *env, target_ulong vaddr,
58
*index = i * 256 + stlb_idx;
59
return true;
60
}
61
- }
62
+ } else {
63
+     continue;
64
+    }
65
}
66
67
/* Search MTLB */
68
@@ -XXX,XX +XXX,XX @@ bool loongarch_tlb_search(CPULoongArchState *env, target_ulong vaddr,
69
*index = i;
70
return true;
71
}
72
- }
73
+ } else {
74
+     continue;
75
+    }
76
}
77
return false;
78
}
79
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
60
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
80
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
81
--- a/target/loongarch/helper.h
62
--- a/target/loongarch/helper.h
82
+++ b/target/loongarch/helper.h
63
+++ b/target/loongarch/helper.h
83
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(rdtime_d, i64, env)
64
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(rdtime_d, i64, env)
...
...
107
+++ b/target/loongarch/tcg/csr_helper.c
88
+++ b/target/loongarch/tcg/csr_helper.c
108
@@ -XXX,XX +XXX,XX @@
89
@@ -XXX,XX +XXX,XX @@
109
#include "hw/irq.h"
90
#include "hw/irq.h"
110
#include "cpu-csr.h"
91
#include "cpu-csr.h"
111
92
112
+
113
+
114
+target_ulong helper_csrwr_stlbps(CPULoongArchState *env, target_ulong val)
93
+target_ulong helper_csrwr_stlbps(CPULoongArchState *env, target_ulong val)
115
+{
94
+{
116
+ int64_t old_v = env->CSR_STLBPS;
95
+ int64_t old_v = env->CSR_STLBPS;
117
+ uint8_t default_ps = ctz32(env->CSR_PRCFG2);
118
+
96
+
119
+ /*
97
+ /*
120
+ * The real hardware only supports the min tlb_ps is 12
98
+ * The real hardware only supports the min tlb_ps is 12
121
+ * tlb_ps=0 may cause undefined-behavior.
99
+ * tlb_ps=0 may cause undefined-behavior.
122
+ */
100
+ */
123
+ uint8_t tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
101
+ uint8_t tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
124
+ if (!check_ps(env, tlb_ps)) {
102
+ if (!check_ps(env, tlb_ps)) {
125
+ qemu_log_mask(LOG_GUEST_ERROR,
103
+ qemu_log_mask(LOG_GUEST_ERROR,
126
+ "Attempted set ps %d\n",tlb_ps);
104
+ "Attempted set ps %d\n", tlb_ps);
127
+ val = FIELD_DP64(val, CSR_STLBPS, PS, default_ps);
105
+ return old_v;
128
+ }
106
+ }
129
+ env->CSR_STLBPS = val;
130
+ return old_v;
107
+ return old_v;
131
+}
108
+}
132
+
109
+
133
target_ulong helper_csrrd_pgd(CPULoongArchState *env)
110
target_ulong helper_csrrd_pgd(CPULoongArchState *env)
134
{
111
{
...
...
138
target_ulong helper_csrwr_pwcl(CPULoongArchState *env, target_ulong val)
115
target_ulong helper_csrwr_pwcl(CPULoongArchState *env, target_ulong val)
139
{
116
{
140
- int shift;
117
- int shift;
141
+ int shift, ptbase;
118
+ int shift, ptbase;
142
int64_t old_v = env->CSR_PWCL;
119
int64_t old_v = env->CSR_PWCL;
143
+ uint8_t default_ps = ctz32(env->CSR_PRCFG2);
144
120
145
/*
121
/*
146
* The real hardware only supports 64bit PTE width now, 128bit or others
122
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrwr_pwcl(CPULoongArchState *env, target_ulong val)
147
* treated as illegal.
123
* treated as illegal.
148
*/
124
*/
149
shift = FIELD_EX64(val, CSR_PWCL, PTEWIDTH);
125
shift = FIELD_EX64(val, CSR_PWCL, PTEWIDTH);
150
+ ptbase = FIELD_EX64(val, CSR_PWCL, PTBASE);
126
+ ptbase = FIELD_EX64(val, CSR_PWCL, PTBASE);
151
if (shift) {
127
if (shift) {
152
qemu_log_mask(LOG_GUEST_ERROR,
128
qemu_log_mask(LOG_GUEST_ERROR,
153
"Attempted set pte width with %d bit\n", 64 << shift);
129
"Attempted set pte width with %d bit\n", 64 << shift);
154
val = FIELD_DP64(val, CSR_PWCL, PTEWIDTH, 0);
130
val = FIELD_DP64(val, CSR_PWCL, PTEWIDTH, 0);
155
}
131
}
132
+ env->CSR_PWCL =val;
156
+ if (!check_ps(env, ptbase)) {
133
+ if (!check_ps(env, ptbase)) {
157
+ qemu_log_mask(LOG_GUEST_ERROR,
134
+ qemu_log_mask(LOG_GUEST_ERROR,
158
+ "Attrmpted set ptbase 2^%d\n", ptbase);
135
+ "Attrmpted set ptbase 2^%d\n", ptbase);
159
+ val = FIELD_DP64(val, CSR_PWCL, PTBASE, default_ps);
136
+ return old_v;
160
+ }
137
+ }
161
138
162
env->CSR_PWCL = val;
139
- env->CSR_PWCL = val;
163
return old_v;
140
return old_v;
141
}
164
diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
142
diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
165
index XXXXXXX..XXXXXXX 100644
143
index XXXXXXX..XXXXXXX 100644
166
--- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
144
--- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
167
+++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
145
+++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
168
@@ -XXX,XX +XXX,XX @@ static bool set_csr_trans_func(unsigned int csr_num, GenCSRRead readfn,
146
@@ -XXX,XX +XXX,XX @@ static bool set_csr_trans_func(unsigned int csr_num, GenCSRRead readfn,
...
...
181
#include "exec/log.h"
159
#include "exec/log.h"
182
#include "cpu-csr.h"
160
#include "cpu-csr.h"
183
161
184
+bool check_ps(CPULoongArchState *env, int tlb_ps)
162
+bool check_ps(CPULoongArchState *env, int tlb_ps)
185
+{
163
+{
186
+ if(tlb_ps > 64){
164
+ if (tlb_ps > 64) {
187
+ return false;
165
+ return false;
188
+ }
166
+ }
189
+ return BIT_ULL(tlb_ps) && (env->CSR_PRCFG2);
167
+ return BIT_ULL(tlb_ps) & (env->CSR_PRCFG2);
190
+}
168
+}
191
+
169
+
192
void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
170
void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
193
uint64_t *dir_width, target_ulong level)
171
uint64_t *dir_width, target_ulong level)
194
{
172
{
195
@@ -XXX,XX +XXX,XX @@ static void invalidate_tlb_entry(CPULoongArchState *env, int index)
196
uint8_t tlb_v0 = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, V);
197
uint8_t tlb_v1 = FIELD_EX64(tlb->tlb_entry1, TLBENTRY, V);
198
uint64_t tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
199
+ uint8_t tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
200
+
201
+ if (!tlb_e){
202
+ return;
203
+ }
204
205
if (index >= LOONGARCH_STLB) {
206
tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
207
} else {
208
tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
209
}
210
+ if (!check_ps(env,tlb_ps)) {
211
+ qemu_log_mask(LOG_GUEST_ERROR, "tlb_ps %d is illegal\n", tlb_ps);
212
+ return;
213
+ }
214
pagesize = MAKE_64BIT_MASK(tlb_ps, 1);
215
mask = MAKE_64BIT_MASK(0, tlb_ps + 1);
216
217
@@ -XXX,XX +XXX,XX @@ static void fill_tlb_entry(CPULoongArchState *env, int index)
173
@@ -XXX,XX +XXX,XX @@ static void fill_tlb_entry(CPULoongArchState *env, int index)
218
lo1 = env->CSR_TLBELO1;
174
lo1 = env->CSR_TLBELO1;
219
}
175
}
220
176
221
- if (csr_ps == 0) {
177
- if (csr_ps == 0) {
...
...
225
+ qemu_log_mask(LOG_GUEST_ERROR, "csr_ps %d is illegal\n", csr_ps);
181
+ qemu_log_mask(LOG_GUEST_ERROR, "csr_ps %d is illegal\n", csr_ps);
226
+ return;
182
+ return;
227
}
183
}
228
184
229
/* Only MTLB has the ps fields */
185
/* Only MTLB has the ps fields */
230
@@ -XXX,XX +XXX,XX @@ void helper_tlbrd(CPULoongArchState *env)
231
}
232
tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
233
234
+ if (!check_ps(env, tlb_ps)) {
235
+ qemu_log_mask(LOG_GUEST_ERROR, "tlb_ps %d is illegal\n", tlb_ps);
236
+ return;
237
+ }
238
if (!tlb_e) {
239
/* Invalid TLB entry */
240
env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 1);
241
@@ -XXX,XX +XXX,XX @@ void helper_tlbfill(CPULoongArchState *env)
186
@@ -XXX,XX +XXX,XX @@ void helper_tlbfill(CPULoongArchState *env)
242
pagesize = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS);
187
pagesize = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS);
243
}
188
}
244
189
245
+ if (!check_ps(env, pagesize)) {
190
+ if (!check_ps(env, pagesize)) {
...
...
253
+ return;
198
+ return;
254
+ }
199
+ }
255
200
256
if (pagesize == stlb_ps) {
201
if (pagesize == stlb_ps) {
257
/* Only write into STLB bits [47:13] */
202
/* Only write into STLB bits [47:13] */
258
@@ -XXX,XX +XXX,XX @@ void helper_invtlb_page_asid(CPULoongArchState *env, target_ulong info,
259
} else {
260
tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
261
}
262
+ if (!check_ps(env, tlb_ps)) {
263
+ qemu_log_mask(LOG_GUEST_ERROR, "tlb_ps %d is illegal\n", tlb_ps);
264
+ return;
265
+ }
266
tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
267
vpn = (addr & TARGET_VIRT_MASK) >> (tlb_ps + 1);
268
compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
269
@@ -XXX,XX +XXX,XX @@ void helper_invtlb_page_asid_or_g(CPULoongArchState *env,
270
} else {
271
tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
272
}
273
+ if (!check_ps(env, tlb_ps)) {
274
+ qemu_log_mask(LOG_GUEST_ERROR, "tlb_ps %d is illegal\n", tlb_ps);
275
+ return;
276
+ }
277
+
278
+
279
tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
280
vpn = (addr & TARGET_VIRT_MASK) >> (tlb_ps + 1);
281
compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
282
--
203
--
283
2.34.1
204
2.34.1
diff view generated by jsdifflib