summaryrefslogtreecommitdiffstats
path: root/qemu/tests/tcg/xtensa/test_mmu.S
blob: a15316ffb317d5c99c6eda3ffe483b1cb81acd9a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
#include "macros.inc"

test_suite mmu

.purgem test_init

.macro clean_tlb_way way, page_size, n_entries
    movi    a2, \way
    movi    a3, \page_size
    movi    a4, \n_entries
    loop    a4, 1f
    idtlb   a2
    iitlb   a2
    add     a2, a2, a3
1:
.endm

.macro test_init
    clean_tlb_way 0, 0x00001000, 4
    clean_tlb_way 1, 0x00001000, 4
    clean_tlb_way 2, 0x00001000, 4
    clean_tlb_way 3, 0x00001000, 4
    clean_tlb_way 4, 0x00100000, 4
    movi    a2, 0x00000007
    idtlb   a2
    movi    a2, 0x00000008
    idtlb   a2
    movi    a2, 0x00000009
    idtlb   a2
.endm

test tlb_group
    movi    a2, 0x04000002 /* PPN */
    movi    a3, 0x01200004 /* VPN */
    wdtlb   a2, a3
    witlb   a2, a3
    movi    a3, 0x00200004
    rdtlb0  a1, a3
    ritlb0  a2, a3
    movi    a3, 0x01000001
    assert  eq, a1, a3
    assert  eq, a2, a3
    movi    a3, 0x00200004
    rdtlb1  a1, a3
    ritlb1  a2, a3
    movi    a3, 0x04000002
    assert  eq, a1, a3
    assert  eq, a2, a3
    movi    a3, 0x01234567
    pdtlb   a1, a3
    pitlb   a2, a3
    movi    a3, 0x01234014
    assert  eq, a1, a3
    movi    a3, 0x0123400c
    assert  eq, a2, a3
    movi    a3, 0x00200004
    idtlb   a3
    iitlb   a3
    movi    a3, 0x01234567
    pdtlb   a1, a3
    pitlb   a2, a3
    movi    a3, 0x00000010
    and     a1, a1, a3
    assert  eqi, a1, 0
    movi    a3, 0x00000008
    and     a2, a2, a3
    assert  eqi, a2, 0
test_end

test itlb_miss
    set_vector kernel, 1f

    movi    a3, 0x00100000
    jx      a3
    test_fail
1:
    rsr     a2, excvaddr
    assert  eq, a2, a3
    rsr     a2, exccause
    movi    a3, 16
    assert  eq, a2, a3
test_end

test dtlb_miss
    set_vector kernel, 1f

    movi    a3, 0x00100000
    l8ui    a2, a3, 0
    test_fail
1:
    rsr     a2, excvaddr
    assert  eq, a2, a3
    rsr     a2, exccause
    movi    a3, 24
    assert  eq, a2, a3
test_end

test itlb_multi_hit
    set_vector kernel, 1f

    movi    a2, 0x04000002 /* PPN */
    movi    a3, 0xf0000004 /* VPN */
    witlb   a2, a3
    movi    a3, 0xf0000000
    pitlb   a2, a3
    test_fail
1:
    rsr     a2, exccause
    movi    a3, 17
    assert  eq, a2, a3
test_end

test dtlb_multi_hit
    set_vector kernel, 1f

    movi    a2, 0x04000002 /* PPN */
    movi    a3, 0x01200004 /* VPN */
    wdtlb   a2, a3
    movi    a3, 0x01200007 /* VPN */
    wdtlb   a2, a3
    movi    a3, 0x01200000
    pdtlb   a2, a3
    test_fail
1:
    rsr     a2, exccause
    movi    a3, 25
    assert  eq, a2, a3
test_end

test inst_fetch_privilege
    set_vector kernel, 3f

    movi    a2, 0x4004f
    wsr     a2, ps
1:
    isync
    nop
2:
    test_fail
3:
    movi    a1, 1b
    rsr     a2, excvaddr
    rsr     a3, epc1
    assert  ge, a2, a1
    assert  ge, a3, a1
    movi    a1, 2b
    assert  lt, a2, a1
    assert  lt, a3, a1
    rsr     a2, exccause
    movi    a3, 18
    assert  eq, a2, a3
    rsr     a2, ps
    movi    a3, 0x4005f
    assert  eq, a2, a3
test_end

test load_store_privilege
    set_vector kernel, 2f

    movi    a3, 10f
    pitlb   a3, a3
    ritlb1  a2, a3
    movi    a1, 0x10
    or      a2, a2, a1
    movi    a1, 0x000ff000
    and     a3, a3, a1
    movi    a1, 4
    or      a3, a3, a1
    witlb   a2, a3
    movi    a3, 10f
    movi    a1, 0x000fffff
    and     a1, a3, a1

    movi    a2, 0x04000003 /* PPN */
    movi    a3, 0x01200004 /* VPN */
    wdtlb   a2, a3
    movi    a3, 0x01200001
    movi    a2, 0x4004f
    jx      a1
10:
    wsr     a2, ps
    isync
1:
    l8ui    a2, a3, 0
    test_fail
2:
    rsr     a2, excvaddr
    assert  eq, a2, a3
    rsr     a2, epc1
    movi    a3, 1b
    movi    a1, 0x000fffff
    and     a3, a3, a1
    assert  eq, a2, a3
    rsr     a2, exccause
    movi    a3, 26
    assert  eq, a2, a3
    rsr     a2, ps
    movi    a3, 0x4005f
    assert  eq, a2, a3
test_end

test cring_load_store_privilege
    set_vector kernel, 0
    set_vector double, 2f

    movi    a2, 0x04000003 /* PPN */
    movi    a3, 0x01200004 /* VPN */
    wdtlb   a2, a3
    movi    a3, 0x01200004
    movi    a2, 0x4005f    /* ring 1 + excm => cring == 0 */
    wsr     a2, ps
    isync
    l8ui    a2, a3, 0      /* cring used */
1:
    l32e    a2, a3, -4     /* ring used */
    test_fail
2:
    rsr     a2, excvaddr
    addi    a2, a2, 4
    assert  eq, a2, a3
    rsr     a2, depc
    movi    a3, 1b
    assert  eq, a2, a3
    rsr     a2, exccause
    movi    a3, 26
    assert  eq, a2, a3
    rsr     a2, ps
    movi    a3, 0x4005f
    assert  eq, a2, a3
test_end

test inst_fetch_prohibited
    set_vector kernel, 2f

    movi    a3, 10f
    pitlb   a3, a3
    ritlb1  a2, a3
    movi    a1, 0xfffff000
    and     a2, a2, a1
    movi    a1, 0x4
    or      a2, a2, a1
    movi    a1, 0x000ff000
    and     a3, a3, a1
    movi    a1, 4
    or      a3, a3, a1
    witlb   a2, a3
    movi    a3, 10f
    movi    a1, 0x000fffff
    and     a1, a3, a1
    jx      a1
    .align  4
10:
    nop
    test_fail
2:
    rsr     a2, excvaddr
    assert  eq, a2, a1
    rsr     a2, epc1
    assert  eq, a2, a1
    rsr     a2, exccause
    movi    a3, 20
    assert  eq, a2, a3
test_end

test load_prohibited
    set_vector kernel, 2f

    movi    a2, 0x0400000c /* PPN */
    movi    a3, 0x01200004 /* VPN */
    wdtlb   a2, a3
    movi    a3, 0x01200002
1:
    l8ui    a2, a3, 0
    test_fail
2:
    rsr     a2, excvaddr
    assert  eq, a2, a3
    rsr     a2, epc1
    movi    a3, 1b
    assert  eq, a2, a3
    rsr     a2, exccause
    movi    a3, 28
    assert  eq, a2, a3
test_end

test store_prohibited
    set_vector kernel, 2f

    movi    a2, 0x04000001 /* PPN */
    movi    a3, 0x01200004 /* VPN */
    wdtlb   a2, a3
    movi    a3, 0x01200003
    l8ui    a2, a3, 0
1:
    s8i     a2, a3, 0
    test_fail
2:
    rsr     a2, excvaddr
    assert  eq, a2, a3
    rsr     a2, epc1
    movi    a3, 1b
    assert  eq, a2, a3
    rsr     a2, exccause
    movi    a3, 29
    assert  eq, a2, a3
test_end

/* Set up page table entry vaddr->paddr, ring=pte_ring, attr=pte_attr
 * and DTLB way 7 to cover this PTE, ring=pt_ring, attr=pt_attr
 */
.macro pt_setup pt_ring, pt_attr, pte_ring, vaddr, paddr, pte_attr
    movi    a2, 0x80000000
    wsr     a2, ptevaddr

    movi    a3, 0x80000007 | (((\vaddr) >> 10) & 0xfffff000) /* way 7 */
    movi    a4, 0x04000003 | ((\pt_ring) << 4) /* PADDR 64M */
    wdtlb   a4, a3
    isync

    movi    a3, ((\paddr) & 0xfffff000) | ((\pte_ring) << 4) | (\pte_attr)
    movi    a1, ((\vaddr) >> 12) << 2
    add     a2, a1, a2
    s32i    a3, a2, 0

    movi    a3, 0x80000007 | (((\vaddr) >> 10) & 0xfffff000) /* way 7 */
    movi    a4, 0x04000000 | ((\pt_ring) << 4) | (\pt_attr) /* PADDR 64M */
    wdtlb   a4, a3
    isync

    movi    a3, (\vaddr)
.endm

/* out: PS.RING=ring, PS.EXCM=excm, a3=vaddr */
.macro go_ring ring, excm, vaddr
    movi    a3, 10f
    pitlb   a3, a3
    ritlb1  a2, a3
    movi    a1, 0x10
    or      a2, a2, a1
    movi    a1, 0x000ff000
    and     a3, a3, a1
    movi    a1, 4
    or      a3, a3, a1
    witlb   a2, a3
    movi    a3, 10f
    movi    a1, 0x000fffff
    and     a1, a3, a1

    movi    a2, 0
    wsr     a2, excvaddr

    movi    a3, \vaddr
    movi    a2, 0x4000f | ((\ring) << 6) | ((\excm) << 4)
    jx      a1
10:
    wsr     a2, ps
    isync
.endm

/* in: a3 -- virtual address to test */
.macro assert_auto_tlb
    movi    a2, 0x4000f
    wsr     a2, ps
    isync
    pdtlb   a2, a3
    movi    a1, 0xfffff01f
    and     a2, a2, a1
    movi    a1, 0xfffff000
    and     a1, a1, a3
    xor     a1, a1, a2
    assert  gei, a1, 0x10
    movi    a2, 0x14
    assert  lt, a1, a2
.endm

/* in: a3 -- virtual address to test */
.macro assert_no_auto_tlb
    movi    a2, 0x4000f
    wsr     a2, ps
    isync
    pdtlb   a2, a3
    movi    a1, 0x10
    and     a1, a1, a2
    assert  eqi, a1, 0
.endm

.macro assert_sr sr, v
    rsr     a2, \sr
    movi    a1, (\v)
    assert  eq, a1, a2
.endm

.macro assert_epc1_1m vaddr
    movi    a2, (\vaddr)
    movi    a1, 0xfffff
    and     a1, a1, a2
    rsr     a2, epc1
    assert  eq, a1, a2
.endm

test dtlb_autoload
    set_vector kernel, 0

    pt_setup    0, 3, 1, 0x1000, 0x1000, 3
    assert_no_auto_tlb

    l8ui    a1, a3, 0

    rsr     a2, excvaddr
    assert  eq, a2, a3

    assert_auto_tlb
test_end

test autoload_load_store_privilege
    set_vector kernel, 0
    set_vector double, 2f

    pt_setup    0, 3, 0, 0x2000, 0x2000, 3
    movi    a3, 0x2004
    assert_no_auto_tlb

    movi    a2, 0x4005f    /* ring 1 + excm => cring == 0 */
    wsr     a2, ps
    isync
1:
    l32e    a2, a3, -4     /* ring used */
    test_fail
2:
    rsr     a2, excvaddr
    addi    a1, a3, -4
    assert  eq, a1, a2

    assert_auto_tlb
    assert_sr depc, 1b
    assert_sr exccause, 26
test_end

test autoload_pte_load_prohibited
    set_vector kernel, 2f

    pt_setup    0, 3, 0, 0x3000, 0, 0xc
    assert_no_auto_tlb
1:
    l32i    a2, a3, 0
    test_fail
2:
    rsr     a2, excvaddr
    assert  eq, a2, a3

    assert_auto_tlb
    assert_sr epc1, 1b
    assert_sr exccause, 28
test_end

test autoload_pt_load_prohibited
    set_vector kernel, 2f

    pt_setup    0, 0xc, 0, 0x4000, 0x4000, 3
    assert_no_auto_tlb
1:
    l32i    a2, a3, 0
    test_fail
2:
    rsr     a2, excvaddr
    assert  eq, a2, a3

    assert_no_auto_tlb
    assert_sr epc1, 1b
    assert_sr exccause, 24
test_end

test autoload_pt_privilege
    set_vector  kernel, 2f
    pt_setup    0, 3, 1, 0x5000, 0, 3
    go_ring     1, 0, 0x5001

    l8ui    a2, a3, 0
1:
    syscall
2:
    rsr     a2, excvaddr
    assert  eq, a2, a3

    assert_auto_tlb
    assert_epc1_1m 1b
    assert_sr exccause, 1
test_end

test autoload_pte_privilege
    set_vector  kernel, 2f
    pt_setup    0, 3, 0, 0x6000, 0, 3
    go_ring     1, 0, 0x6001
1:
    l8ui    a2, a3, 0
    syscall
2:
    rsr     a2, excvaddr
    assert  eq, a2, a3

    assert_auto_tlb
    assert_epc1_1m 1b
    assert_sr exccause, 26
test_end

test autoload_3_level_pt
    set_vector  kernel, 2f
    pt_setup    1, 3, 1, 0x00400000, 0, 3
    pt_setup    1, 3, 1, 0x80001000, 0x2000000, 3
    go_ring     1, 0, 0x00400001
1:
    l8ui    a2, a3, 0
    syscall
2:
    rsr     a2, excvaddr
    assert  eq, a2, a3

    assert_no_auto_tlb
    assert_epc1_1m 1b
    assert_sr exccause, 24
test_end

test cross_page_insn
    set_vector kernel, 2f

    movi    a2, 0x04000003 /* PPN */
    movi    a3, 0x00007000 /* VPN */
    witlb   a2, a3
    wdtlb   a2, a3
    movi    a3, 0x00008000 /* VPN */
    witlb   a2, a3
    wdtlb   a2, a3

    movi    a2, 0x00007fff
    movi    a3, 20f
    movi    a4, 21f
    sub     a4, a4, a3
    loop    a4, 1f
    l8ui    a5, a3, 0
    s8i     a5, a2, 0
    addi    a2, a2, 1
    addi    a3, a3, 1
1:
    movi    a2, 0x00007fff
    movi    a3, 0x00008000
    /* DTLB: OK, ITLB: OK */
    jx      a2

    .begin  no-transform
20:
    l32i    a2, a3, 0
    syscall
21:
    .end    no-transform

2:
    rsr     a2, exccause
    movi    a3, 1
    assert  eq, a2, a3
    rsr     a2, epc1
    movi    a3, 0x8002
    assert  eq, a2, a3
    rsr     a2, excsave1
    movi    a3, 0x00007fff
    assert  ne, a2, a3

    reset_ps
    set_vector kernel, 3f

    movi    a2, 0x0400000c /* PPN */
    movi    a3, 0x00008000 /* VPN */
    wdtlb   a2, a3
    movi    a2, 0x00007fff
    movi    a3, 0x00008000
    /* DTLB: FAIL, ITLB: OK */
    jx      a2
3:
    rsr     a2, exccause
    movi    a3, 28
    assert  eq, a2, a3
    rsr     a2, epc1
    movi    a3, 0x7fff
    assert  eq, a2, a3
    rsr     a2, excsave1
    movi    a3, 0x00007fff
    assert  eq, a2, a3

    reset_ps
    set_vector kernel, 4f

    movi    a2, 0x0400000c /* PPN */
    movi    a3, 0x00008000 /* VPN */
    witlb   a2, a3
    movi    a2, 0x04000003 /* PPN */
    wdtlb   a2, a3
    movi    a2, 0x00007fff
    movi    a3, 0x00008000
    /* DTLB: OK, ITLB: FAIL */
    jx      a2
4:
    rsr     a2, exccause
    movi    a3, 20
    assert  eq, a2, a3
    rsr     a2, epc1
    movi    a3, 0x7fff
    assert  eq, a2, a3
    rsr     a2, excsave1
    movi    a3, 0x00007fff
    assert  eq, a2, a3

    reset_ps
    set_vector kernel, 5f

    movi    a2, 0x0400000c /* PPN */
    movi    a3, 0x00008000 /* VPN */
    wdtlb   a2, a3
    movi    a2, 0x00007fff
    movi    a3, 0x00008000
    /* DTLB: FAIL, ITLB: FAIL */
    jx      a2
5:
    rsr     a2, exccause
    movi    a3, 20
    assert  eq, a2, a3
    rsr     a2, epc1
    movi    a3, 0x7fff
    assert  eq, a2, a3
    rsr     a2, excsave1
    movi    a3, 0x00007fff
    assert  eq, a2, a3
test_end

test cross_page_tb
    set_vector kernel, 2f

    movi    a2, 0x04000003 /* PPN */
    movi    a3, 0x00007000 /* VPN */
    witlb   a2, a3
    wdtlb   a2, a3
    movi    a3, 0x00008000 /* VPN */
    witlb   a2, a3
    wdtlb   a2, a3

    movi    a2, 0x00007ffc
    movi    a3, 20f
    movi    a4, 21f
    sub     a4, a4, a3
    loop    a4, 1f
    l8ui    a5, a3, 0
    s8i     a5, a2, 0
    addi    a2, a2, 1
    addi    a3, a3, 1
1:
    movi    a2, 0x00007ffc
    movi    a3, 0x00008000
    /* DTLB: OK, ITLB: OK */
    jx      a2

    .begin  no-transform
20:
    l32i    a2, a3, 0
    syscall
21:
    .end    no-transform

2:
    rsr     a2, exccause
    movi    a3, 1
    assert  eq, a2, a3
    rsr     a2, epc1
    movi    a3, 0x7fff
    assert  eq, a2, a3
    rsr     a2, excsave1
    movi    a3, 0x00007ffc
    assert  ne, a2, a3

    reset_ps
    set_vector kernel, 3f

    movi    a2, 0x0400000c /* PPN */
    movi    a3, 0x00008000 /* VPN */
    wdtlb   a2, a3
    movi    a2, 0x00007ffc
    movi    a3, 0x00008000
    /* DTLB: FAIL, ITLB: OK */
    jx      a2
3:
    rsr     a2, exccause
    movi    a3, 28
    assert  eq, a2, a3
    rsr     a2, epc1
    movi    a3, 0x7ffc
    assert  eq, a2, a3
    rsr     a2, excsave1
    movi    a3, 0x00007ffc
    assert  eq, a2, a3

    reset_ps
    set_vector kernel, 4f

    movi    a2, 0x0400000c /* PPN */
    movi    a3, 0x00008000 /* VPN */
    witlb   a2, a3
    movi    a2, 0x04000003 /* PPN */
    wdtlb   a2, a3
    movi    a2, 0x00007ffc
    movi    a3, 0x00008000
    /* DTLB: OK, ITLB: FAIL */
    jx      a2
4:
    rsr     a2, exccause
    movi    a3, 20
    assert  eq, a2, a3
    rsr     a2, epc1
    movi    a3, 0x7fff
    assert  eq, a2, a3
    rsr     a2, excsave1
    movi    a3, 0x00007ffc
    assert  ne, a2, a3

    reset_ps
    set_vector kernel, 5f

    movi    a2, 0x0400000c /* PPN */
    movi    a3, 0x00008000 /* VPN */
    wdtlb   a2, a3
    movi    a2, 0x00007ffc
    movi    a3, 0x00008000
    /* DTLB: FAIL, ITLB: FAIL */
    jx      a2
5:
    rsr     a2, exccause
    movi    a3, 28
    assert  eq, a2, a3
    rsr     a2, epc1
    movi    a3, 0x7ffc
    assert  eq, a2, a3
    rsr     a2, excsave1
    movi    a3, 0x00007ffc
    assert  eq, a2, a3
test_end

test_suite_end