-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathvirt.h
1400 lines (1261 loc) · 53.5 KB
/
virt.h
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
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#ifdef __arm64__
#ifndef __VIRT_H_
#define __VIRT_H_
#include "bitops.h"
typedef struct HvfArm64State HvfArm64State;
/*
* Round number down to multiple. Requires that d be a power of 2 (see
* QEMU_ALIGN_UP for a safer but slower version on arbitrary
* numbers); works even if d is a smaller type than n.
*/
#ifndef ROUND_DOWN
#define ROUND_DOWN(n, d) ((n) & -(0 ? (n) : (d)))
#endif
/*
* Round number up to multiple. Requires that d be a power of 2 (see
* QEMU_ALIGN_UP for a safer but slower version on arbitrary
* numbers); works even if d is a smaller type than n.
*/
#define ROUND_UP(n, d) ROUND_DOWN((n) + (d)-1, (d))
#define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d))
typedef int64_t target_long;
typedef uint64_t target_ulong;
/* For M profile, some registers are banked secure vs non-secure;
* these are represented as a 2-element array where the first element
* is the non-secure copy and the second is the secure copy.
* When the CPU does not have implement the security extension then
* only the first element is used.
* This means that the copy for the current security state can be
* accessed via env->registerfield[env->v7m.secure] (whether the security
* extension is implemented or not).
*/
enum {
M_REG_NS = 0,
M_REG_S = 1,
M_REG_NUM_BANKS = 2,
};
/* ARM-specific interrupt pending bits. */
#define CPU_INTERRUPT_FIQ CPU_INTERRUPT_TGT_EXT_1
#define CPU_INTERRUPT_VIRQ CPU_INTERRUPT_TGT_EXT_2
#define CPU_INTERRUPT_VFIQ CPU_INTERRUPT_TGT_EXT_3
#define CPU_INTERRUPT_VSERR CPU_INTERRUPT_TGT_INT_0
/* CPU state for each instance of a generic timer (in cp15 c14) */
typedef struct ARMGenericTimer {
uint64_t cval; /* Timer CompareValue register */
uint64_t ctl; /* Timer Control register */
} ARMGenericTimer;
#define GTIMER_PHYS 0
#define GTIMER_VIRT 1
#define GTIMER_HYP 2
#define GTIMER_SEC 3
#define GTIMER_HYPVIRT 4
#define NUM_GTIMERS 5
#define ARM_MAX_VQ 16
typedef struct ARMVectorReg {
uint64_t d[2 * ARM_MAX_VQ] __attribute__((aligned(16)));
;
} ARMVectorReg;
/* In AArch32 mode, predicate registers do not exist at all. */
typedef struct ARMPredicateReg {
uint64_t p[DIV_ROUND_UP(2 * ARM_MAX_VQ, 8)] __attribute__((aligned(16)));
} ARMPredicateReg;
/* In AArch32 mode, PAC keys do not exist at all. */
typedef struct ARMPACKey {
uint64_t lo, hi;
} ARMPACKey;
/* See the commentary above the TBFLAG field definitions. */
typedef struct CPUARMTBFlags {
uint32_t flags;
target_ulong flags2;
} CPUARMTBFlags;
#define SYSREG_OP0_SHIFT 20
#define SYSREG_OP0_MASK 0x3
#define SYSREG_OP0(sysreg) ((sysreg >> SYSREG_OP0_SHIFT) & SYSREG_OP0_MASK)
#define SYSREG_OP1_SHIFT 14
#define SYSREG_OP1_MASK 0x7
#define SYSREG_OP1(sysreg) ((sysreg >> SYSREG_OP1_SHIFT) & SYSREG_OP1_MASK)
#define SYSREG_CRN_SHIFT 10
#define SYSREG_CRN_MASK 0xf
#define SYSREG_CRN(sysreg) ((sysreg >> SYSREG_CRN_SHIFT) & SYSREG_CRN_MASK)
#define SYSREG_CRM_SHIFT 1
#define SYSREG_CRM_MASK 0xf
#define SYSREG_CRM(sysreg) ((sysreg >> SYSREG_CRM_SHIFT) & SYSREG_CRM_MASK)
#define SYSREG_OP2_SHIFT 17
#define SYSREG_OP2_MASK 0x7
#define SYSREG_OP2(sysreg) ((sysreg >> SYSREG_OP2_SHIFT) & SYSREG_OP2_MASK)
#define SYSREG(op0, op1, crn, crm, op2) \
((op0 << SYSREG_OP0_SHIFT) | (op1 << SYSREG_OP1_SHIFT) | (crn << SYSREG_CRN_SHIFT) | \
(crm << SYSREG_CRM_SHIFT) | (op2 << SYSREG_OP2_SHIFT))
#define SYSREG_MASK \
SYSREG(SYSREG_OP0_MASK, SYSREG_OP1_MASK, SYSREG_CRN_MASK, SYSREG_CRM_MASK, SYSREG_OP2_MASK)
#define SYSREG_OSLAR_EL1 SYSREG(2, 0, 1, 0, 4)
#define SYSREG_OSLSR_EL1 SYSREG(2, 0, 1, 1, 4)
#define SYSREG_OSDLR_EL1 SYSREG(2, 0, 1, 3, 4)
#define SYSREG_CNTPCT_EL0 SYSREG(3, 3, 14, 0, 1)
#define SYSREG_PMCR_EL0 SYSREG(3, 3, 9, 12, 0)
#define SYSREG_PMUSERENR_EL0 SYSREG(3, 3, 9, 14, 0)
#define SYSREG_PMCNTENSET_EL0 SYSREG(3, 3, 9, 12, 1)
#define SYSREG_PMCNTENCLR_EL0 SYSREG(3, 3, 9, 12, 2)
#define SYSREG_PMINTENCLR_EL1 SYSREG(3, 0, 9, 14, 2)
#define SYSREG_PMOVSCLR_EL0 SYSREG(3, 3, 9, 12, 3)
#define SYSREG_PMSWINC_EL0 SYSREG(3, 3, 9, 12, 4)
#define SYSREG_PMSELR_EL0 SYSREG(3, 3, 9, 12, 5)
#define SYSREG_PMCEID0_EL0 SYSREG(3, 3, 9, 12, 6)
#define SYSREG_PMCEID1_EL0 SYSREG(3, 3, 9, 12, 7)
#define SYSREG_PMCCNTR_EL0 SYSREG(3, 3, 9, 13, 0)
#define SYSREG_PMCCFILTR_EL0 SYSREG(3, 3, 14, 15, 7)
#define SYSREG_ICC_AP0R0_EL1 SYSREG(3, 0, 12, 8, 4)
#define SYSREG_ICC_AP0R1_EL1 SYSREG(3, 0, 12, 8, 5)
#define SYSREG_ICC_AP0R2_EL1 SYSREG(3, 0, 12, 8, 6)
#define SYSREG_ICC_AP0R3_EL1 SYSREG(3, 0, 12, 8, 7)
#define SYSREG_ICC_AP1R0_EL1 SYSREG(3, 0, 12, 9, 0)
#define SYSREG_ICC_AP1R1_EL1 SYSREG(3, 0, 12, 9, 1)
#define SYSREG_ICC_AP1R2_EL1 SYSREG(3, 0, 12, 9, 2)
#define SYSREG_ICC_AP1R3_EL1 SYSREG(3, 0, 12, 9, 3)
#define SYSREG_ICC_ASGI1R_EL1 SYSREG(3, 0, 12, 11, 6)
#define SYSREG_ICC_BPR0_EL1 SYSREG(3, 0, 12, 8, 3)
#define SYSREG_ICC_BPR1_EL1 SYSREG(3, 0, 12, 12, 3)
#define SYSREG_ICC_CTLR_EL1 SYSREG(3, 0, 12, 12, 4)
#define SYSREG_ICC_DIR_EL1 SYSREG(3, 0, 12, 11, 1)
#define SYSREG_ICC_EOIR0_EL1 SYSREG(3, 0, 12, 8, 1)
#define SYSREG_ICC_EOIR1_EL1 SYSREG(3, 0, 12, 12, 1)
#define SYSREG_ICC_HPPIR0_EL1 SYSREG(3, 0, 12, 8, 2)
#define SYSREG_ICC_HPPIR1_EL1 SYSREG(3, 0, 12, 12, 2)
#define SYSREG_ICC_IAR0_EL1 SYSREG(3, 0, 12, 8, 0)
#define SYSREG_ICC_IAR1_EL1 SYSREG(3, 0, 12, 12, 0)
#define SYSREG_ICC_IGRPEN0_EL1 SYSREG(3, 0, 12, 12, 6)
#define SYSREG_ICC_IGRPEN1_EL1 SYSREG(3, 0, 12, 12, 7)
#define SYSREG_ICC_PMR_EL1 SYSREG(3, 0, 4, 6, 0)
#define SYSREG_ICC_RPR_EL1 SYSREG(3, 0, 12, 11, 3)
#define SYSREG_ICC_SGI0R_EL1 SYSREG(3, 0, 12, 11, 7)
#define SYSREG_ICC_SGI1R_EL1 SYSREG(3, 0, 12, 11, 5)
#define SYSREG_ICC_SRE_EL1 SYSREG(3, 0, 12, 12, 5)
#define SYSREG_MDSCR_EL1 SYSREG(2, 0, 0, 2, 2)
#define SYSREG_DBGBVR0_EL1 SYSREG(2, 0, 0, 0, 4)
#define SYSREG_DBGBCR0_EL1 SYSREG(2, 0, 0, 0, 5)
#define SYSREG_DBGWVR0_EL1 SYSREG(2, 0, 0, 0, 6)
#define SYSREG_DBGWCR0_EL1 SYSREG(2, 0, 0, 0, 7)
#define SYSREG_DBGBVR1_EL1 SYSREG(2, 0, 0, 1, 4)
#define SYSREG_DBGBCR1_EL1 SYSREG(2, 0, 0, 1, 5)
#define SYSREG_DBGWVR1_EL1 SYSREG(2, 0, 0, 1, 6)
#define SYSREG_DBGWCR1_EL1 SYSREG(2, 0, 0, 1, 7)
#define SYSREG_DBGBVR2_EL1 SYSREG(2, 0, 0, 2, 4)
#define SYSREG_DBGBCR2_EL1 SYSREG(2, 0, 0, 2, 5)
#define SYSREG_DBGWVR2_EL1 SYSREG(2, 0, 0, 2, 6)
#define SYSREG_DBGWCR2_EL1 SYSREG(2, 0, 0, 2, 7)
#define SYSREG_DBGBVR3_EL1 SYSREG(2, 0, 0, 3, 4)
#define SYSREG_DBGBCR3_EL1 SYSREG(2, 0, 0, 3, 5)
#define SYSREG_DBGWVR3_EL1 SYSREG(2, 0, 0, 3, 6)
#define SYSREG_DBGWCR3_EL1 SYSREG(2, 0, 0, 3, 7)
#define SYSREG_DBGBVR4_EL1 SYSREG(2, 0, 0, 4, 4)
#define SYSREG_DBGBCR4_EL1 SYSREG(2, 0, 0, 4, 5)
#define SYSREG_DBGWVR4_EL1 SYSREG(2, 0, 0, 4, 6)
#define SYSREG_DBGWCR4_EL1 SYSREG(2, 0, 0, 4, 7)
#define SYSREG_DBGBVR5_EL1 SYSREG(2, 0, 0, 5, 4)
#define SYSREG_DBGBCR5_EL1 SYSREG(2, 0, 0, 5, 5)
#define SYSREG_DBGWVR5_EL1 SYSREG(2, 0, 0, 5, 6)
#define SYSREG_DBGWCR5_EL1 SYSREG(2, 0, 0, 5, 7)
#define SYSREG_DBGBVR6_EL1 SYSREG(2, 0, 0, 6, 4)
#define SYSREG_DBGBCR6_EL1 SYSREG(2, 0, 0, 6, 5)
#define SYSREG_DBGWVR6_EL1 SYSREG(2, 0, 0, 6, 6)
#define SYSREG_DBGWCR6_EL1 SYSREG(2, 0, 0, 6, 7)
#define SYSREG_DBGBVR7_EL1 SYSREG(2, 0, 0, 7, 4)
#define SYSREG_DBGBCR7_EL1 SYSREG(2, 0, 0, 7, 5)
#define SYSREG_DBGWVR7_EL1 SYSREG(2, 0, 0, 7, 6)
#define SYSREG_DBGWCR7_EL1 SYSREG(2, 0, 0, 7, 7)
#define SYSREG_DBGBVR8_EL1 SYSREG(2, 0, 0, 8, 4)
#define SYSREG_DBGBCR8_EL1 SYSREG(2, 0, 0, 8, 5)
#define SYSREG_DBGWVR8_EL1 SYSREG(2, 0, 0, 8, 6)
#define SYSREG_DBGWCR8_EL1 SYSREG(2, 0, 0, 8, 7)
#define SYSREG_DBGBVR9_EL1 SYSREG(2, 0, 0, 9, 4)
#define SYSREG_DBGBCR9_EL1 SYSREG(2, 0, 0, 9, 5)
#define SYSREG_DBGWVR9_EL1 SYSREG(2, 0, 0, 9, 6)
#define SYSREG_DBGWCR9_EL1 SYSREG(2, 0, 0, 9, 7)
#define SYSREG_DBGBVR10_EL1 SYSREG(2, 0, 0, 10, 4)
#define SYSREG_DBGBCR10_EL1 SYSREG(2, 0, 0, 10, 5)
#define SYSREG_DBGWVR10_EL1 SYSREG(2, 0, 0, 10, 6)
#define SYSREG_DBGWCR10_EL1 SYSREG(2, 0, 0, 10, 7)
#define SYSREG_DBGBVR11_EL1 SYSREG(2, 0, 0, 11, 4)
#define SYSREG_DBGBCR11_EL1 SYSREG(2, 0, 0, 11, 5)
#define SYSREG_DBGWVR11_EL1 SYSREG(2, 0, 0, 11, 6)
#define SYSREG_DBGWCR11_EL1 SYSREG(2, 0, 0, 11, 7)
#define SYSREG_DBGBVR12_EL1 SYSREG(2, 0, 0, 12, 4)
#define SYSREG_DBGBCR12_EL1 SYSREG(2, 0, 0, 12, 5)
#define SYSREG_DBGWVR12_EL1 SYSREG(2, 0, 0, 12, 6)
#define SYSREG_DBGWCR12_EL1 SYSREG(2, 0, 0, 12, 7)
#define SYSREG_DBGBVR13_EL1 SYSREG(2, 0, 0, 13, 4)
#define SYSREG_DBGBCR13_EL1 SYSREG(2, 0, 0, 13, 5)
#define SYSREG_DBGWVR13_EL1 SYSREG(2, 0, 0, 13, 6)
#define SYSREG_DBGWCR13_EL1 SYSREG(2, 0, 0, 13, 7)
#define SYSREG_DBGBVR14_EL1 SYSREG(2, 0, 0, 14, 4)
#define SYSREG_DBGBCR14_EL1 SYSREG(2, 0, 0, 14, 5)
#define SYSREG_DBGWVR14_EL1 SYSREG(2, 0, 0, 14, 6)
#define SYSREG_DBGWCR14_EL1 SYSREG(2, 0, 0, 14, 7)
#define SYSREG_DBGBVR15_EL1 SYSREG(2, 0, 0, 15, 4)
#define SYSREG_DBGBCR15_EL1 SYSREG(2, 0, 0, 15, 5)
#define SYSREG_DBGWVR15_EL1 SYSREG(2, 0, 0, 15, 6)
#define SYSREG_DBGWCR15_EL1 SYSREG(2, 0, 0, 15, 7)
#define WFX_IS_WFE (1 << 0)
#define TMR_CTL_ENABLE (1 << 0)
#define TMR_CTL_IMASK (1 << 1)
#define TMR_CTL_ISTATUS (1 << 2)
/* Definitions for the PMU registers */
#define PMCRN_MASK 0xf800
#define PMCRN_SHIFT 11
#define PMCRLC 0x40
#define PMCRDP 0x20
#define PMCRX 0x10
#define PMCRD 0x8
#define PMCRC 0x4
#define PMCRP 0x2
#define PMCRE 0x1
/*
* Mask of PMCR bits writable by guest (not including WO bits like C, P,
* which can be written as 1 to trigger behaviour but which stay RAZ).
*/
#define PMCR_WRITABLE_MASK (PMCRLC | PMCRDP | PMCRX | PMCRD | PMCRE)
#define PMXEVTYPER_P 0x80000000
#define PMXEVTYPER_U 0x40000000
#define PMXEVTYPER_NSK 0x20000000
#define PMXEVTYPER_NSU 0x10000000
#define PMXEVTYPER_NSH 0x08000000
#define PMXEVTYPER_M 0x04000000
#define PMXEVTYPER_MT 0x02000000
#define PMXEVTYPER_EVTCOUNT 0x0000ffff
#define PMXEVTYPER_MASK \
(PMXEVTYPER_P | PMXEVTYPER_U | PMXEVTYPER_NSK | PMXEVTYPER_NSU | PMXEVTYPER_NSH | \
PMXEVTYPER_M | PMXEVTYPER_MT | PMXEVTYPER_EVTCOUNT)
#define PMCCFILTR 0xf8000000
#define PMCCFILTR_M PMXEVTYPER_M
#define PMCCFILTR_EL0 (PMCCFILTR | PMCCFILTR_M)
static inline uint32_t pmu_num_counters(HvfArm64State* env) {
return (0x410b3000 & PMCRN_MASK) >> PMCRN_SHIFT;
}
/* Bits allowed to be set/cleared for PMCNTEN* and PMINTEN* */
static inline uint64_t pmu_counter_mask(HvfArm64State* env) {
return (1 << 31) | ((1 << pmu_num_counters(env)) - 1);
}
/*
* Software neural-network floating-point types.
*/
typedef uint16_t bfloat16;
/*
* Software IEC/IEEE floating-point underflow tininess-detection mode.
*/
#define float_tininess_after_rounding false
#define float_tininess_before_rounding true
/*
*Software IEC/IEEE floating-point rounding mode.
*/
typedef enum __attribute__((__packed__)) {
float_round_nearest_even = 0,
float_round_down = 1,
float_round_up = 2,
float_round_to_zero = 3,
float_round_ties_away = 4,
/* Not an IEEE rounding mode: round to closest odd, overflow to max */
float_round_to_odd = 5,
/* Not an IEEE rounding mode: round to closest odd, overflow to inf */
float_round_to_odd_inf = 6,
} FloatRoundMode;
enum {
float_flag_invalid = 0x0001,
float_flag_divbyzero = 0x0002,
float_flag_overflow = 0x0004,
float_flag_underflow = 0x0008,
float_flag_inexact = 0x0010,
float_flag_input_denormal = 0x0020,
float_flag_output_denormal = 0x0040,
float_flag_invalid_isi = 0x0080, /* inf - inf */
float_flag_invalid_imz = 0x0100, /* inf * 0 */
float_flag_invalid_idi = 0x0200, /* inf / inf */
float_flag_invalid_zdz = 0x0400, /* 0 / 0 */
float_flag_invalid_sqrt = 0x0800, /* sqrt(-x) */
float_flag_invalid_cvti = 0x1000, /* non-nan to integer */
float_flag_invalid_snan = 0x2000, /* any operand was snan */
};
/*
* Rounding precision for floatx80.
*/
typedef enum __attribute__((__packed__)) {
floatx80_precision_x,
floatx80_precision_d,
floatx80_precision_s,
} FloatX80RoundPrec;
/*
* Floating Point Status. Individual architectures may maintain
* several versions of float_status for different functions. The
* correct status for the operation is then passed by reference to
* most of the softfloat functions.
*/
typedef struct float_status {
uint16_t float_exception_flags;
FloatRoundMode float_rounding_mode;
FloatX80RoundPrec floatx80_rounding_precision;
bool tininess_before_rounding;
/* should denormalised results go to zero and set the inexact flag? */
bool flush_to_zero;
/* should denormalised inputs go to zero and set the input_denormal flag? */
bool flush_inputs_to_zero;
bool default_nan_mode;
/*
* The flags below are not used on all specializations and may
* constant fold away (see snan_bit_is_one()/no_signalling_nans() in
* softfloat-specialize.inc.c)
*/
bool snan_bit_is_one;
bool use_first_nan;
bool no_signaling_nans;
} float_status;
typedef struct HvfArm64State {
/* Regs for current mode. */
uint32_t regs[16];
/* 32/64 switch only happens when taking and returning from
* exceptions so the overlap semantics are taken care of then
* instead of having a complicated union.
*/
/* Regs for A64 mode. */
uint64_t xregs[32];
uint64_t pc;
/* PSTATE isn't an architectural register for ARMv8. However, it is
* convenient for us to assemble the underlying state into a 32 bit format
* identical to the architectural format used for the SPSR. (This is also
* what the Linux kernel's 'pstate' field in signal handlers and KVM's
* 'pstate' register are.) Of the PSTATE bits:
* NZCV are kept in the split out env->CF/VF/NF/ZF, (which have the same
* semantics as for AArch32, as described in the comments on each field)
* nRW (also known as M[4]) is kept, inverted, in env->aarch64
* DAIF (exception masks) are kept in env->daif
* BTYPE is kept in env->btype
* SM and ZA are kept in env->svcr
* all other bits are stored in their correct places in env->pstate
*/
uint32_t pstate;
bool aarch64; /* True if CPU is in aarch64 state; inverse of PSTATE.nRW */
bool thumb; /* True if CPU is in thumb mode; cpsr[5] */
/* Cached TBFLAGS state. See below for which bits are included. */
CPUARMTBFlags hflags;
/* Frequently accessed CPSR bits are stored separately for efficiency.
This contains all the other bits. Use cpsr_{read,write} to access
the whole CPSR. */
uint32_t uncached_cpsr;
uint32_t spsr;
/* Banked registers. */
uint64_t banked_spsr[8];
uint32_t banked_r13[8];
uint32_t banked_r14[8];
/* These hold r8-r12. */
uint32_t usr_regs[5];
uint32_t fiq_regs[5];
/* cpsr flag cache for faster execution */
uint32_t CF; /* 0 or 1 */
uint32_t VF; /* V is the bit 31. All other bits are undefined */
uint32_t NF; /* N is bit 31. All other bits are undefined. */
uint32_t ZF; /* Z set if zero. */
uint32_t QF; /* 0 or 1 */
uint32_t GE; /* cpsr[19:16] */
uint32_t condexec_bits; /* IT bits. cpsr[15:10,26:25]. */
uint32_t btype; /* BTI branch type. spsr[11:10]. */
uint64_t daif; /* exception masks, in the bits they are in PSTATE */
uint64_t svcr; /* PSTATE.{SM,ZA} in the bits they are in SVCR */
uint64_t elr_el[4]; /* AArch64 exception link regs */
uint64_t sp_el[4]; /* AArch64 banked stack pointers */
/* System control coprocessor (cp15) */
struct {
uint32_t c0_cpuid;
union { /* Cache size selection */
struct {
uint64_t _unused_csselr0;
uint64_t csselr_ns;
uint64_t _unused_csselr1;
uint64_t csselr_s;
};
uint64_t csselr_el[4];
};
union { /* System control register. */
struct {
uint64_t _unused_sctlr;
uint64_t sctlr_ns;
uint64_t hsctlr;
uint64_t sctlr_s;
};
uint64_t sctlr_el[4];
};
uint64_t cpacr_el1; /* Architectural feature access control register */
uint64_t cptr_el[4]; /* ARMv8 feature trap registers */
uint32_t c1_xscaleauxcr; /* XScale auxiliary control register. */
uint64_t sder; /* Secure debug enable register. */
uint32_t nsacr; /* Non-secure access control register. */
union { /* MMU translation table base 0. */
struct {
uint64_t _unused_ttbr0_0;
uint64_t ttbr0_ns;
uint64_t _unused_ttbr0_1;
uint64_t ttbr0_s;
};
uint64_t ttbr0_el[4];
};
union { /* MMU translation table base 1. */
struct {
uint64_t _unused_ttbr1_0;
uint64_t ttbr1_ns;
uint64_t _unused_ttbr1_1;
uint64_t ttbr1_s;
};
uint64_t ttbr1_el[4];
};
uint64_t vttbr_el2; /* Virtualization Translation Table Base. */
uint64_t vsttbr_el2; /* Secure Virtualization Translation Table. */
/* MMU translation table base control. */
uint64_t tcr_el[4];
uint64_t vtcr_el2; /* Virtualization Translation Control. */
uint64_t vstcr_el2; /* Secure Virtualization Translation Control. */
uint32_t c2_data; /* MPU data cacheable bits. */
uint32_t c2_insn; /* MPU instruction cacheable bits. */
union { /* MMU domain access control register
* MPU write buffer control.
*/
struct {
uint64_t dacr_ns;
uint64_t dacr_s;
};
struct {
uint64_t dacr32_el2;
};
};
uint32_t pmsav5_data_ap; /* PMSAv5 MPU data access permissions */
uint32_t pmsav5_insn_ap; /* PMSAv5 MPU insn access permissions */
uint64_t hcr_el2; /* Hypervisor configuration register */
uint64_t hcrx_el2; /* Extended Hypervisor configuration register */
uint64_t scr_el3; /* Secure configuration register. */
union { /* Fault status registers. */
struct {
uint64_t ifsr_ns;
uint64_t ifsr_s;
};
struct {
uint64_t ifsr32_el2;
};
};
union {
struct {
uint64_t _unused_dfsr;
uint64_t dfsr_ns;
uint64_t hsr;
uint64_t dfsr_s;
};
uint64_t esr_el[4];
};
uint32_t c6_region[8]; /* MPU base/size registers. */
union { /* Fault address registers. */
struct {
uint64_t _unused_far0;
uint32_t dfar_ns;
uint32_t ifar_ns;
uint32_t dfar_s;
uint32_t ifar_s;
uint64_t _unused_far3;
};
uint64_t far_el[4];
};
uint64_t hpfar_el2;
uint64_t hstr_el2;
union { /* Translation result. */
struct {
uint64_t _unused_par_0;
uint64_t par_ns;
uint64_t _unused_par_1;
uint64_t par_s;
};
uint64_t par_el[4];
};
uint32_t c9_insn; /* Cache lockdown registers. */
uint32_t c9_data;
uint64_t c9_pmcr; /* performance monitor control register */
uint64_t c9_pmcnten; /* perf monitor counter enables */
uint64_t c9_pmovsr; /* perf monitor overflow status */
uint64_t c9_pmuserenr; /* perf monitor user enable */
uint64_t c9_pmselr; /* perf monitor counter selection register */
uint64_t c9_pminten; /* perf monitor interrupt enables */
union { /* Memory attribute redirection */
struct {
uint64_t _unused_mair_0;
uint32_t mair0_ns;
uint32_t mair1_ns;
uint64_t _unused_mair_1;
uint32_t mair0_s;
uint32_t mair1_s;
};
uint64_t mair_el[4];
};
union { /* vector base address register */
struct {
uint64_t _unused_vbar;
uint64_t vbar_ns;
uint64_t hvbar;
uint64_t vbar_s;
};
uint64_t vbar_el[4];
};
uint32_t mvbar; /* (monitor) vector base address register */
uint64_t rvbar; /* rvbar sampled from rvbar property at reset */
struct { /* FCSE PID. */
uint32_t fcseidr_ns;
uint32_t fcseidr_s;
};
union { /* Context ID. */
struct {
uint64_t _unused_contextidr_0;
uint64_t contextidr_ns;
uint64_t _unused_contextidr_1;
uint64_t contextidr_s;
};
uint64_t contextidr_el[4];
};
union { /* User RW Thread register. */
struct {
uint64_t tpidrurw_ns;
uint64_t tpidrprw_ns;
uint64_t htpidr;
uint64_t _tpidr_el3;
};
uint64_t tpidr_el[4];
};
uint64_t tpidr2_el0;
/* The secure banks of these registers don't map anywhere */
uint64_t tpidrurw_s;
uint64_t tpidrprw_s;
uint64_t tpidruro_s;
union { /* User RO Thread register. */
uint64_t tpidruro_ns;
uint64_t tpidrro_el[1];
};
uint64_t c14_cntfrq; /* Counter Frequency register */
uint64_t c14_cntkctl; /* Timer Control register */
uint32_t cnthctl_el2; /* Counter/Timer Hyp Control register */
uint64_t cntvoff_el2; /* Counter Virtual Offset register */
ARMGenericTimer c14_timer[NUM_GTIMERS];
uint32_t c15_cpar; /* XScale Coprocessor Access Register */
uint32_t c15_ticonfig; /* TI925T configuration byte. */
uint32_t c15_i_max; /* Maximum D-cache dirty line index. */
uint32_t c15_i_min; /* Minimum D-cache dirty line index. */
uint32_t c15_threadid; /* TI debugger thread-ID. */
uint32_t c15_config_base_address; /* SCU base address. */
uint32_t c15_diagnostic; /* diagnostic register */
uint32_t c15_power_diagnostic;
uint32_t c15_power_control; /* power control */
uint64_t dbgbvr[16]; /* breakpoint value registers */
uint64_t dbgbcr[16]; /* breakpoint control registers */
uint64_t dbgwvr[16]; /* watchpoint value registers */
uint64_t dbgwcr[16]; /* watchpoint control registers */
uint64_t mdscr_el1;
uint64_t oslsr_el1; /* OS Lock Status */
uint64_t osdlr_el1; /* OS DoubleLock status */
uint64_t mdcr_el2;
uint64_t mdcr_el3;
/* Stores the architectural value of the counter *the last time it was
* updated* by pmccntr_op_start. Accesses should always be surrounded
* by pmccntr_op_start/pmccntr_op_finish to guarantee the latest
* architecturally-correct value is being read/set.
*/
uint64_t c15_ccnt;
/* Stores the delta between the architectural value and the underlying
* cycle count during normal operation. It is used to update c15_ccnt
* to be the correct architectural value before accesses. During
* accesses, c15_ccnt_delta contains the underlying count being used
* for the access, after which it reverts to the delta value in
* pmccntr_op_finish.
*/
uint64_t c15_ccnt_delta;
uint64_t c14_pmevcntr[31];
uint64_t c14_pmevcntr_delta[31];
uint64_t c14_pmevtyper[31];
uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */
uint64_t vpidr_el2; /* Virtualization Processor ID Register */
uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */
uint64_t tfsr_el[4]; /* tfsre0_el1 is index 0. */
uint64_t gcr_el1;
uint64_t rgsr_el1;
/* Minimal RAS registers */
uint64_t disr_el1;
uint64_t vdisr_el2;
uint64_t vsesr_el2;
/* Apple-specific registers */
uint64_t vmsa_lock_el1;
uint64_t apctl_el1;
uint64_t apcfg_el1;
} cp15;
struct {
uint64_t gxf_config_el[4];
uint64_t gxf_enter_el[4];
uint64_t gxf_status_el[4];
uint64_t gxf_abort_el[4];
uint64_t sp_gl[4];
uint64_t tpidr_gl[4];
uint64_t vbar_gl[4];
uint64_t spsr_gl[4];
uint64_t aspsr_gl[4];
uint64_t esr_gl[4];
uint64_t elr_gl[4];
uint64_t far_gl[4];
} gxf;
struct {
uint64_t sprr_el_br_el1[4][2];
uint64_t sprr_config_el[4];
uint64_t mprr_el_br_el1[4][2];
} sprr;
struct {
/* M profile has up to 4 stack pointers:
* a Main Stack Pointer and a Process Stack Pointer for each
* of the Secure and Non-Secure states. (If the CPU doesn't support
* the security extension then it has only two SPs.)
* In QEMU we always store the currently active SP in regs[13],
* and the non-active SP for the current security state in
* v7m.other_sp. The stack pointers for the inactive security state
* are stored in other_ss_msp and other_ss_psp.
* switch_v7m_security_state() is responsible for rearranging them
* when we change security state.
*/
uint32_t other_sp;
uint32_t other_ss_msp;
uint32_t other_ss_psp;
uint32_t vecbase[M_REG_NUM_BANKS];
uint32_t basepri[M_REG_NUM_BANKS];
uint32_t control[M_REG_NUM_BANKS];
uint32_t ccr[M_REG_NUM_BANKS]; /* Configuration and Control */
uint32_t cfsr[M_REG_NUM_BANKS]; /* Configurable Fault Status */
uint32_t hfsr; /* HardFault Status */
uint32_t dfsr; /* Debug Fault Status Register */
uint32_t sfsr; /* Secure Fault Status Register */
uint32_t mmfar[M_REG_NUM_BANKS]; /* MemManage Fault Address */
uint32_t bfar; /* BusFault Address */
uint32_t sfar; /* Secure Fault Address Register */
unsigned mpu_ctrl[M_REG_NUM_BANKS]; /* MPU_CTRL */
int exception;
uint32_t primask[M_REG_NUM_BANKS];
uint32_t faultmask[M_REG_NUM_BANKS];
uint32_t aircr; /* only holds r/w state if security extn implemented */
uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
uint32_t csselr[M_REG_NUM_BANKS];
uint32_t scr[M_REG_NUM_BANKS];
uint32_t msplim[M_REG_NUM_BANKS];
uint32_t psplim[M_REG_NUM_BANKS];
uint32_t fpcar[M_REG_NUM_BANKS];
uint32_t fpccr[M_REG_NUM_BANKS];
uint32_t fpdscr[M_REG_NUM_BANKS];
uint32_t cpacr[M_REG_NUM_BANKS];
uint32_t nsacr;
uint32_t ltpsize;
uint32_t vpr;
} v7m;
/* Information associated with an exception about to be taken:
* code which raises an exception must set cs->exception_index and
* the relevant parts of this structure; the cpu_do_interrupt function
* will then set the guest-visible registers as part of the exception
* entry process.
*/
struct {
uint32_t syndrome; /* AArch64 format syndrome register */
uint32_t fsr; /* AArch32 format fault status register info */
uint64_t vaddress; /* virtual addr associated with exception, if any */
uint32_t target_el; /* EL the exception should be targeted for */
/* If we implement EL2 we will also need to store information
* about the intermediate physical address for stage 2 faults.
*/
} exception;
/* Information associated with an SError */
struct {
uint8_t pending;
uint8_t has_esr;
uint64_t esr;
} serror;
uint8_t ext_dabt_raised; /* Tracking/verifying injection of ext DABT */
/* State of our input IRQ/FIQ/VIRQ/VFIQ lines */
uint32_t irq_line_state;
/* Thumb-2 EE state. */
uint32_t teecr;
uint32_t teehbr;
/* VFP coprocessor state. */
struct {
ARMVectorReg zregs[32];
/* Store FFR as pregs[16] to make it easier to treat as any other. */
#define FFR_PRED_NUM 16
ARMPredicateReg pregs[17];
/* Scratch space for aa64 sve predicate temporary. */
ARMPredicateReg preg_tmp;
/* We store these fpcsr fields separately for convenience. */
uint32_t qc[4] __attribute__((aligned(16)));
int vec_len;
int vec_stride;
uint32_t xregs[16];
/* Scratch space for aa32 neon expansion. */
uint32_t scratch[8];
/* There are a number of distinct float control structures:
*
* fp_status: is the "normal" fp status.
* fp_status_fp16: used for half-precision calculations
* standard_fp_status : the ARM "Standard FPSCR Value"
* standard_fp_status_fp16 : used for half-precision
* calculations with the ARM "Standard FPSCR Value"
*
* Half-precision operations are governed by a separate
* flush-to-zero control bit in FPSCR:FZ16. We pass a separate
* status structure to control this.
*
* The "Standard FPSCR", ie default-NaN, flush-to-zero,
* round-to-nearest and is used by any operations (generally
* Neon) which the architecture defines as controlled by the
* standard FPSCR value rather than the FPSCR.
*
* The "standard FPSCR but for fp16 ops" is needed because
* the "standard FPSCR" tracks the FPSCR.FZ16 bit rather than
* using a fixed value for it.
*
* To avoid having to transfer exception bits around, we simply
* say that the FPSCR cumulative exception flags are the logical
* OR of the flags in the four fp statuses. This relies on the
* only thing which needs to read the exception flags being
* an explicit FPSCR read.
*/
float_status fp_status;
float_status fp_status_f16;
float_status standard_fp_status;
float_status standard_fp_status_f16;
uint64_t zcr_el[4]; /* ZCR_EL[1-3] */
uint64_t smcr_el[4]; /* SMCR_EL[1-3] */
} vfp;
uint64_t exclusive_addr;
uint64_t exclusive_val;
uint64_t exclusive_high;
/* iwMMXt coprocessor state. */
struct {
uint64_t regs[16];
uint64_t val;
uint32_t cregs[16];
} iwmmxt;
struct {
ARMPACKey apia;
ARMPACKey apib;
ARMPACKey apda;
ARMPACKey apdb;
ARMPACKey apga;
ARMPACKey kernel;
ARMPACKey m;
} keys;
uint64_t scxtnum_el[4];
/*
* SME ZA storage -- 256 x 256 byte array, with bytes in host word order,
* as we do with vfp.zregs[]. This corresponds to the architectural ZA
* array, where ZA[N] is in the least-significant bytes of env->zarray[N].
* When SVL is less than the architectural maximum, the accessible
* storage is restricted, such that if the SVL is X bytes the guest can
* see only the bottom X elements of zarray[], and only the least
* significant X bytes of each element of the array. (In other words,
* the observable part is always square.)
*
* The ZA storage can also be considered as a set of square tiles of
* elements of different sizes. The mapping from tiles to the ZA array
* is architecturally defined, such that for tiles of elements of esz
* bytes, the Nth row (or "horizontal slice") of tile T is in
* ZA[T + N * esz]. Note that this means that each tile is not contiguous
* in the ZA storage, because its rows are striped through the ZA array.
*
* Because this is so large, keep this toward the end of the reset area,
* to keep the offsets into the rest of the structure smaller.
*/
ARMVectorReg zarray[ARM_MAX_VQ * 16];
struct CPUBreakpoint* cpu_breakpoint[16];
struct CPUWatchpoint* cpu_watchpoint[16];
/* Fields up to this point are cleared by a CPU reset */
struct {
} end_reset_fields;
/* Fields after this point are preserved across CPU reset. */
/* Internal CPU feature flags. */
uint64_t features;
/* PMSAv7 MPU */
struct {
uint32_t* drbar;
uint32_t* drsr;
uint32_t* dracr;
uint32_t rnr[M_REG_NUM_BANKS];
} pmsav7;
/* PMSAv8 MPU */
struct {
/* The PMSAv8 implementation also shares some PMSAv7 config
* and state:
* pmsav7.rnr (region number register)
* pmsav7_dregion (number of configured regions)
*/
uint32_t* rbar[M_REG_NUM_BANKS];
uint32_t* rlar[M_REG_NUM_BANKS];
uint32_t mair0[M_REG_NUM_BANKS];
uint32_t mair1[M_REG_NUM_BANKS];
} pmsav8;
/* v8M SAU */
struct {
uint32_t* rbar;
uint32_t* rlar;
uint32_t rnr;
uint32_t ctrl;
} sau;
void* nvic;
const struct arm_boot_info* boot_info;
/* Store GICv3CPUState to access from this struct */
void* gicv3state;
#ifdef TARGET_TAGGED_ADDRESSES
/* Linux syscall tagged address support */
bool tagged_addr_enable;
#endif
} HvfArm64State;
/* When looking up a coprocessor register we look for it
* via an integer which encodes all of:
* coprocessor number
* Crn, Crm, opc1, opc2 fields
* 32 or 64 bit register (ie is it accessed via MRC/MCR
* or via MRRC/MCRR?)
* non-secure/secure bank (AArch32 only)
* We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field.
* (In this case crn and opc2 should be zero.)
* For AArch64, there is no 32/64 bit size distinction;
* instead all registers have a 2 bit op0, 3 bit op1 and op2,
* and 4 bit CRn and CRm. The encoding patterns are chosen
* to be easy to convert to and from the KVM encodings, and also
* so that the hashtable can contain both AArch32 and AArch64
* registers (to allow for interprocessing where we might run
* 32 bit code on a 64 bit core).
*/
/* This bit is private to our hashtable cpreg; in KVM register
* IDs the AArch64/32 distinction is the KVM_REG_ARM/ARM64
* in the upper bits of the 64 bit ID.
*/
#define CP_REG_AA64_SHIFT 28
#define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
/* To enable banking of coprocessor registers depending on ns-bit we
* add a bit to distinguish between secure and non-secure cpregs in the
* hashtable.
*/
#define CP_REG_NS_SHIFT 29
#define CP_REG_NS_MASK (1 << CP_REG_NS_SHIFT)
#define ENCODE_CP_REG(cp, is64, ns, crn, crm, opc1, opc2) \
((ns) << CP_REG_NS_SHIFT | ((cp) << 16) | ((is64) << 15) | ((crn) << 11) | ((crm) << 7) | \
((opc1) << 3) | (opc2))
#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
(CP_REG_AA64_MASK | ((cp) << CP_REG_ARM_COPROC_SHIFT) | \
((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | ((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \
((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | ((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) | \
((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT))
#define CP_REG_ARM64 0x6000000000000000ULL
#define CP_REG_ARM_COPROC_MASK 0x000000000FFF0000
#define CP_REG_ARM_COPROC_SHIFT 16
#define CP_REG_ARM64_SYSREG (0x0013 << CP_REG_ARM_COPROC_SHIFT)
#define CP_REG_ARM64_SYSREG_OP0_MASK 0x000000000000c000
#define CP_REG_ARM64_SYSREG_OP0_SHIFT 14
#define CP_REG_ARM64_SYSREG_OP1_MASK 0x0000000000003800
#define CP_REG_ARM64_SYSREG_OP1_SHIFT 11
#define CP_REG_ARM64_SYSREG_CRN_MASK 0x0000000000000780
#define CP_REG_ARM64_SYSREG_CRN_SHIFT 7
#define CP_REG_ARM64_SYSREG_CRM_MASK 0x0000000000000078
#define CP_REG_ARM64_SYSREG_CRM_SHIFT 3
#define CP_REG_ARM64_SYSREG_OP2_MASK 0x0000000000000007
#define CP_REG_ARM64_SYSREG_OP2_SHIFT 0
/* No kernel define but it's useful to QEMU */
#define CP_REG_ARM64_SYSREG_CP (CP_REG_ARM64_SYSREG >> CP_REG_ARM_COPROC_SHIFT)
#define HVF_SYSREG(crn, crm, op0, op1, op2) \
ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP, crn, crm, op0, op1, op2)
#define PL1_WRITE_MASK 0x4
typedef struct HVFVTimer {
/* Vtimer value during migration and paused state */
uint64_t vtimer_val;
} HVFVTimer;
static HVFVTimer vtimer;
/* The instance init functions for implementation-specific subclasses
* set these fields to specify the implementation-dependent values of
* various constant registers and reset values of non-constant
* registers.
* Some of these might become QOM properties eventually.
* Field names match the official register names as defined in the
* ARMv7AR ARM Architecture Reference Manual. A reset_ prefix
* is used for reset values of non-constant registers; no reset_
* prefix means a constant register.
* Some of these registers are split out into a substructure that
* is shared with the translators to control the ISA.
*
* Note that if you add an ID register to the ARMISARegisters struct
* you need to also update the 32-bit and 64-bit versions of the
* kvm_arm_get_host_cpu_features() function to correctly populate the
* field by reading the value from the KVM vCPU.
*/
struct ARMISARegisters {
uint32_t id_isar0;
uint32_t id_isar1;
uint32_t id_isar2;
uint32_t id_isar3;
uint32_t id_isar4;
uint32_t id_isar5;
uint32_t id_isar6;
uint32_t id_mmfr0;
uint32_t id_mmfr1;
uint32_t id_mmfr2;
uint32_t id_mmfr3;
uint32_t id_mmfr4;
uint32_t id_pfr0;
uint32_t id_pfr1;
uint32_t id_pfr2;
uint32_t mvfr0;
uint32_t mvfr1;
uint32_t mvfr2;
uint32_t id_dfr0;
uint32_t dbgdidr;
uint32_t dbgdevid;