374
360
* UltraSparc IIi I/DMMUs
376
static int get_physical_address_data(CPUState *env,
377
target_phys_addr_t *physical, int *prot,
378
target_ulong address, int rw, int is_user)
362
static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical, int *prot,
363
int *access_index, target_ulong address, int rw,
380
366
target_ulong mask;
383
369
if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
385
*prot = PAGE_READ | PAGE_WRITE;
371
*prot = PAGE_READ | PAGE_WRITE;
389
375
for (i = 0; i < 64; i++) {
390
switch ((env->dtlb_tte[i] >> 61) & 3) {
393
mask = 0xffffffffffffe000ULL;
396
mask = 0xffffffffffff0000ULL;
399
mask = 0xfffffffffff80000ULL;
402
mask = 0xffffffffffc00000ULL;
405
// ctx match, vaddr match?
406
if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
407
(address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
409
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0 ||
410
((env->dtlb_tte[i] & 0x4) && is_user) ||
411
(!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
412
if (env->dmmuregs[3]) /* Fault status register */
413
env->dmmuregs[3] = 2; /* overflow (not read before
415
env->dmmuregs[3] |= (is_user << 3) | ((rw == 1) << 2) | 1;
416
env->dmmuregs[4] = address; /* Fault address register */
417
env->exception_index = TT_DFAULT;
376
switch ((env->dtlb_tte[i] >> 61) & 3) {
379
mask = 0xffffffffffffe000ULL;
382
mask = 0xffffffffffff0000ULL;
385
mask = 0xfffffffffff80000ULL;
388
mask = 0xffffffffffc00000ULL;
391
// ctx match, vaddr match?
392
if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
393
(address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
395
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0 ||
396
((env->dtlb_tte[i] & 0x4) && is_user) ||
397
(!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
398
if (env->dmmuregs[3]) /* Fault status register */
399
env->dmmuregs[3] = 2; /* overflow (not read before another fault) */
400
env->dmmuregs[3] |= (is_user << 3) | ((rw == 1) << 2) | 1;
401
env->dmmuregs[4] = address; /* Fault address register */
402
env->exception_index = TT_DFAULT;
419
printf("DFAULT at 0x%" PRIx64 "\n", address);
404
printf("DFAULT at 0x%" PRIx64 "\n", address);
423
*physical = (env->dtlb_tte[i] & mask & 0x1fffffff000ULL) +
424
(address & ~mask & 0x1fffffff000ULL);
426
if (env->dtlb_tte[i] & 0x2)
408
*physical = (env->dtlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
410
if (env->dtlb_tte[i] & 0x2)
432
416
printf("DMISS at 0x%" PRIx64 "\n", address);
434
env->dmmuregs[6] = (address & ~0x1fffULL) | (env->dmmuregs[1] & 0x1fff);
435
418
env->exception_index = TT_DMISS;
439
static int get_physical_address_code(CPUState *env,
440
target_phys_addr_t *physical, int *prot,
441
target_ulong address, int is_user)
422
static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical, int *prot,
423
int *access_index, target_ulong address, int rw,
443
426
target_ulong mask;
446
429
if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
452
435
for (i = 0; i < 64; i++) {
453
switch ((env->itlb_tte[i] >> 61) & 3) {
456
mask = 0xffffffffffffe000ULL;
459
mask = 0xffffffffffff0000ULL;
462
mask = 0xfffffffffff80000ULL;
465
mask = 0xffffffffffc00000ULL;
468
// ctx match, vaddr match?
469
if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
470
(address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
472
if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0 ||
473
((env->itlb_tte[i] & 0x4) && is_user)) {
474
if (env->immuregs[3]) /* Fault status register */
475
env->immuregs[3] = 2; /* overflow (not read before
477
env->immuregs[3] |= (is_user << 3) | 1;
478
env->exception_index = TT_TFAULT;
436
switch ((env->itlb_tte[i] >> 61) & 3) {
439
mask = 0xffffffffffffe000ULL;
442
mask = 0xffffffffffff0000ULL;
445
mask = 0xfffffffffff80000ULL;
448
mask = 0xffffffffffc00000ULL;
451
// ctx match, vaddr match?
452
if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
453
(address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
455
if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0 ||
456
((env->itlb_tte[i] & 0x4) && is_user)) {
457
if (env->immuregs[3]) /* Fault status register */
458
env->immuregs[3] = 2; /* overflow (not read before another fault) */
459
env->immuregs[3] |= (is_user << 3) | 1;
460
env->exception_index = TT_TFAULT;
480
printf("TFAULT at 0x%" PRIx64 "\n", address);
462
printf("TFAULT at 0x%" PRIx64 "\n", address);
484
*physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) +
485
(address & ~mask & 0x1fffffff000ULL);
466
*physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
491
472
printf("TMISS at 0x%" PRIx64 "\n", address);
493
env->immuregs[6] = (address & ~0x1fffULL) | (env->dmmuregs[1] & 0x1fff);
494
474
env->exception_index = TT_TMISS;
498
static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
499
int *prot, int *access_index,
500
target_ulong address, int rw, int mmu_idx)
478
int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
479
int *access_index, target_ulong address, int rw,
502
int is_user = mmu_idx == MMU_USER_IDX;
505
return get_physical_address_code(env, physical, prot, address,
483
return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user);
508
return get_physical_address_data(env, physical, prot, address, rw,
485
return get_physical_address_data(env, physical, prot, access_index, address, rw, is_user);
512
488
/* Perform address translation */
513
489
int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
514
int mmu_idx, int is_softmmu)
490
int is_user, int is_softmmu)
516
492
target_ulong virt_addr, vaddr;
517
493
target_phys_addr_t paddr;
518
494
int error_code = 0, prot, ret = 0, access_index;
520
error_code = get_physical_address(env, &paddr, &prot, &access_index,
521
address, rw, mmu_idx);
496
error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
522
497
if (error_code == 0) {
523
virt_addr = address & TARGET_PAGE_MASK;
524
vaddr = virt_addr + ((address & TARGET_PAGE_MASK) &
525
(TARGET_PAGE_SIZE - 1));
498
virt_addr = address & TARGET_PAGE_MASK;
499
vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
527
printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64
528
"\n", address, paddr, vaddr);
501
printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64 "\n", address, paddr, vaddr);
530
ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
503
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
613
583
#endif /* TARGET_SPARC64 */
614
584
#endif /* !CONFIG_USER_ONLY */
617
#if defined(CONFIG_USER_ONLY)
618
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
624
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
626
target_phys_addr_t phys_addr;
627
int prot, access_index;
629
if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
630
MMU_KERNEL_IDX) != 0)
631
if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
632
0, MMU_KERNEL_IDX) != 0)
634
if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
640
void cpu_reset(CPUSPARCState *env)
645
env->regwptr = env->regbase + (env->cwp * 16);
646
#if defined(CONFIG_USER_ONLY)
647
env->user_mode_only = 1;
648
#ifdef TARGET_SPARC64
649
env->cleanwin = env->nwindows - 2;
650
env->cansave = env->nwindows - 2;
651
env->pstate = PS_RMO | PS_PEF | PS_IE;
652
env->asi = 0x82; // Primary no-fault
658
#ifdef TARGET_SPARC64
659
env->pstate = PS_PRIV;
660
env->hpstate = HS_PRIV;
661
env->tsptr = &env->ts[env->tl & MAXTL_MASK];
663
env->mmuregs[0] &= ~(MMU_E | MMU_NF);
664
env->mmuregs[0] |= env->def->mmu_bm;
667
env->npc = env->pc + 4;
671
static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
673
sparc_def_t def1, *def = &def1;
675
if (cpu_sparc_find_by_name(def, cpu_model) < 0)
678
env->def = qemu_mallocz(sizeof(*def));
679
memcpy(env->def, def, sizeof(*def));
680
#if defined(CONFIG_USER_ONLY)
681
if ((env->def->features & CPU_FEATURE_FLOAT))
682
env->def->features |= CPU_FEATURE_FLOAT128;
684
env->cpu_model_str = cpu_model;
685
env->version = def->iu_version;
686
env->fsr = def->fpu_version;
687
env->nwindows = def->nwindows;
688
#if !defined(TARGET_SPARC64)
689
env->mmuregs[0] |= def->mmu_version;
690
cpu_sparc_set_id(env, 0);
692
env->mmu_version = def->mmu_version;
693
env->maxtl = def->maxtl;
694
env->version |= def->maxtl << 8;
695
env->version |= def->nwindows - 1;
700
static void cpu_sparc_close(CPUSPARCState *env)
706
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
710
env = qemu_mallocz(sizeof(CPUSPARCState));
715
gen_intermediate_code_init(env);
717
if (cpu_sparc_register(env, cpu_model) < 0) {
718
cpu_sparc_close(env);
726
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
728
#if !defined(TARGET_SPARC64)
729
env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
733
static const sparc_def_t sparc_defs[] = {
734
#ifdef TARGET_SPARC64
736
.name = "Fujitsu Sparc64",
737
.iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
738
.fpu_version = 0x00000000,
739
.mmu_version = mmu_us_12,
742
.features = CPU_DEFAULT_FEATURES,
745
.name = "Fujitsu Sparc64 III",
746
.iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
747
.fpu_version = 0x00000000,
748
.mmu_version = mmu_us_12,
751
.features = CPU_DEFAULT_FEATURES,
754
.name = "Fujitsu Sparc64 IV",
755
.iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
756
.fpu_version = 0x00000000,
757
.mmu_version = mmu_us_12,
760
.features = CPU_DEFAULT_FEATURES,
763
.name = "Fujitsu Sparc64 V",
764
.iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
765
.fpu_version = 0x00000000,
766
.mmu_version = mmu_us_12,
769
.features = CPU_DEFAULT_FEATURES,
772
.name = "TI UltraSparc I",
773
.iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
774
.fpu_version = 0x00000000,
775
.mmu_version = mmu_us_12,
778
.features = CPU_DEFAULT_FEATURES,
781
.name = "TI UltraSparc II",
782
.iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
783
.fpu_version = 0x00000000,
784
.mmu_version = mmu_us_12,
787
.features = CPU_DEFAULT_FEATURES,
790
.name = "TI UltraSparc IIi",
791
.iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
792
.fpu_version = 0x00000000,
793
.mmu_version = mmu_us_12,
796
.features = CPU_DEFAULT_FEATURES,
799
.name = "TI UltraSparc IIe",
800
.iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
801
.fpu_version = 0x00000000,
802
.mmu_version = mmu_us_12,
805
.features = CPU_DEFAULT_FEATURES,
808
.name = "Sun UltraSparc III",
809
.iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
810
.fpu_version = 0x00000000,
811
.mmu_version = mmu_us_12,
814
.features = CPU_DEFAULT_FEATURES,
817
.name = "Sun UltraSparc III Cu",
818
.iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
819
.fpu_version = 0x00000000,
820
.mmu_version = mmu_us_3,
823
.features = CPU_DEFAULT_FEATURES,
826
.name = "Sun UltraSparc IIIi",
827
.iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
828
.fpu_version = 0x00000000,
829
.mmu_version = mmu_us_12,
832
.features = CPU_DEFAULT_FEATURES,
835
.name = "Sun UltraSparc IV",
836
.iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
837
.fpu_version = 0x00000000,
838
.mmu_version = mmu_us_4,
841
.features = CPU_DEFAULT_FEATURES,
844
.name = "Sun UltraSparc IV+",
845
.iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
846
.fpu_version = 0x00000000,
847
.mmu_version = mmu_us_12,
850
.features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
853
.name = "Sun UltraSparc IIIi+",
854
.iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
855
.fpu_version = 0x00000000,
856
.mmu_version = mmu_us_3,
859
.features = CPU_DEFAULT_FEATURES,
862
.name = "Sun UltraSparc T1",
863
// defined in sparc_ifu_fdp.v and ctu.h
864
.iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
865
.fpu_version = 0x00000000,
866
.mmu_version = mmu_sun4v,
869
.features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
873
.name = "Sun UltraSparc T2",
874
// defined in tlu_asi_ctl.v and n2_revid_cust.v
875
.iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
876
.fpu_version = 0x00000000,
877
.mmu_version = mmu_sun4v,
880
.features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
884
.name = "NEC UltraSparc I",
885
.iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
886
.fpu_version = 0x00000000,
887
.mmu_version = mmu_us_12,
890
.features = CPU_DEFAULT_FEATURES,
894
.name = "Fujitsu MB86900",
895
.iu_version = 0x00 << 24, /* Impl 0, ver 0 */
896
.fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
897
.mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
898
.mmu_bm = 0x00004000,
899
.mmu_ctpr_mask = 0x007ffff0,
900
.mmu_cxr_mask = 0x0000003f,
901
.mmu_sfsr_mask = 0xffffffff,
902
.mmu_trcr_mask = 0xffffffff,
904
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
907
.name = "Fujitsu MB86904",
908
.iu_version = 0x04 << 24, /* Impl 0, ver 4 */
909
.fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
910
.mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
911
.mmu_bm = 0x00004000,
912
.mmu_ctpr_mask = 0x00ffffc0,
913
.mmu_cxr_mask = 0x000000ff,
914
.mmu_sfsr_mask = 0x00016fff,
915
.mmu_trcr_mask = 0x00ffffff,
917
.features = CPU_DEFAULT_FEATURES,
920
.name = "Fujitsu MB86907",
921
.iu_version = 0x05 << 24, /* Impl 0, ver 5 */
922
.fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
923
.mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
924
.mmu_bm = 0x00004000,
925
.mmu_ctpr_mask = 0xffffffc0,
926
.mmu_cxr_mask = 0x000000ff,
927
.mmu_sfsr_mask = 0x00016fff,
928
.mmu_trcr_mask = 0xffffffff,
930
.features = CPU_DEFAULT_FEATURES,
933
.name = "LSI L64811",
934
.iu_version = 0x10 << 24, /* Impl 1, ver 0 */
935
.fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
936
.mmu_version = 0x10 << 24,
937
.mmu_bm = 0x00004000,
938
.mmu_ctpr_mask = 0x007ffff0,
939
.mmu_cxr_mask = 0x0000003f,
940
.mmu_sfsr_mask = 0xffffffff,
941
.mmu_trcr_mask = 0xffffffff,
943
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
947
.name = "Cypress CY7C601",
948
.iu_version = 0x11 << 24, /* Impl 1, ver 1 */
949
.fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
950
.mmu_version = 0x10 << 24,
951
.mmu_bm = 0x00004000,
952
.mmu_ctpr_mask = 0x007ffff0,
953
.mmu_cxr_mask = 0x0000003f,
954
.mmu_sfsr_mask = 0xffffffff,
955
.mmu_trcr_mask = 0xffffffff,
957
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
961
.name = "Cypress CY7C611",
962
.iu_version = 0x13 << 24, /* Impl 1, ver 3 */
963
.fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
964
.mmu_version = 0x10 << 24,
965
.mmu_bm = 0x00004000,
966
.mmu_ctpr_mask = 0x007ffff0,
967
.mmu_cxr_mask = 0x0000003f,
968
.mmu_sfsr_mask = 0xffffffff,
969
.mmu_trcr_mask = 0xffffffff,
971
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
975
.name = "TI SuperSparc II",
976
.iu_version = 0x40000000,
977
.fpu_version = 0 << 17,
978
.mmu_version = 0x04000000,
979
.mmu_bm = 0x00002000,
980
.mmu_ctpr_mask = 0xffffffc0,
981
.mmu_cxr_mask = 0x0000ffff,
982
.mmu_sfsr_mask = 0xffffffff,
983
.mmu_trcr_mask = 0xffffffff,
985
.features = CPU_DEFAULT_FEATURES,
988
.name = "TI MicroSparc I",
989
.iu_version = 0x41000000,
990
.fpu_version = 4 << 17,
991
.mmu_version = 0x41000000,
992
.mmu_bm = 0x00004000,
993
.mmu_ctpr_mask = 0x007ffff0,
994
.mmu_cxr_mask = 0x0000003f,
995
.mmu_sfsr_mask = 0x00016fff,
996
.mmu_trcr_mask = 0x0000003f,
998
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
999
CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
1003
.name = "TI MicroSparc II",
1004
.iu_version = 0x42000000,
1005
.fpu_version = 4 << 17,
1006
.mmu_version = 0x02000000,
1007
.mmu_bm = 0x00004000,
1008
.mmu_ctpr_mask = 0x00ffffc0,
1009
.mmu_cxr_mask = 0x000000ff,
1010
.mmu_sfsr_mask = 0x00016fff,
1011
.mmu_trcr_mask = 0x00ffffff,
1013
.features = CPU_DEFAULT_FEATURES,
1016
.name = "TI MicroSparc IIep",
1017
.iu_version = 0x42000000,
1018
.fpu_version = 4 << 17,
1019
.mmu_version = 0x04000000,
1020
.mmu_bm = 0x00004000,
1021
.mmu_ctpr_mask = 0x00ffffc0,
1022
.mmu_cxr_mask = 0x000000ff,
1023
.mmu_sfsr_mask = 0x00016bff,
1024
.mmu_trcr_mask = 0x00ffffff,
1026
.features = CPU_DEFAULT_FEATURES,
1029
.name = "TI SuperSparc 40", // STP1020NPGA
1030
.iu_version = 0x41000000,
1031
.fpu_version = 0 << 17,
1032
.mmu_version = 0x00000000,
1033
.mmu_bm = 0x00002000,
1034
.mmu_ctpr_mask = 0xffffffc0,
1035
.mmu_cxr_mask = 0x0000ffff,
1036
.mmu_sfsr_mask = 0xffffffff,
1037
.mmu_trcr_mask = 0xffffffff,
1039
.features = CPU_DEFAULT_FEATURES,
1042
.name = "TI SuperSparc 50", // STP1020PGA
1043
.iu_version = 0x40000000,
1044
.fpu_version = 0 << 17,
1045
.mmu_version = 0x04000000,
1046
.mmu_bm = 0x00002000,
1047
.mmu_ctpr_mask = 0xffffffc0,
1048
.mmu_cxr_mask = 0x0000ffff,
1049
.mmu_sfsr_mask = 0xffffffff,
1050
.mmu_trcr_mask = 0xffffffff,
1052
.features = CPU_DEFAULT_FEATURES,
1055
.name = "TI SuperSparc 51",
1056
.iu_version = 0x43000000,
1057
.fpu_version = 0 << 17,
1058
.mmu_version = 0x04000000,
1059
.mmu_bm = 0x00002000,
1060
.mmu_ctpr_mask = 0xffffffc0,
1061
.mmu_cxr_mask = 0x0000ffff,
1062
.mmu_sfsr_mask = 0xffffffff,
1063
.mmu_trcr_mask = 0xffffffff,
1065
.features = CPU_DEFAULT_FEATURES,
1068
.name = "TI SuperSparc 60", // STP1020APGA
1069
.iu_version = 0x40000000,
1070
.fpu_version = 0 << 17,
1071
.mmu_version = 0x03000000,
1072
.mmu_bm = 0x00002000,
1073
.mmu_ctpr_mask = 0xffffffc0,
1074
.mmu_cxr_mask = 0x0000ffff,
1075
.mmu_sfsr_mask = 0xffffffff,
1076
.mmu_trcr_mask = 0xffffffff,
1078
.features = CPU_DEFAULT_FEATURES,
1081
.name = "TI SuperSparc 61",
1082
.iu_version = 0x44000000,
1083
.fpu_version = 0 << 17,
1084
.mmu_version = 0x04000000,
1085
.mmu_bm = 0x00002000,
1086
.mmu_ctpr_mask = 0xffffffc0,
1087
.mmu_cxr_mask = 0x0000ffff,
1088
.mmu_sfsr_mask = 0xffffffff,
1089
.mmu_trcr_mask = 0xffffffff,
1091
.features = CPU_DEFAULT_FEATURES,
1094
.name = "Ross RT625",
1095
.iu_version = 0x1e000000,
1096
.fpu_version = 1 << 17,
1097
.mmu_version = 0x1e000000,
1098
.mmu_bm = 0x00004000,
1099
.mmu_ctpr_mask = 0x007ffff0,
1100
.mmu_cxr_mask = 0x0000003f,
1101
.mmu_sfsr_mask = 0xffffffff,
1102
.mmu_trcr_mask = 0xffffffff,
1104
.features = CPU_DEFAULT_FEATURES,
1107
.name = "Ross RT620",
1108
.iu_version = 0x1f000000,
1109
.fpu_version = 1 << 17,
1110
.mmu_version = 0x1f000000,
1111
.mmu_bm = 0x00004000,
1112
.mmu_ctpr_mask = 0x007ffff0,
1113
.mmu_cxr_mask = 0x0000003f,
1114
.mmu_sfsr_mask = 0xffffffff,
1115
.mmu_trcr_mask = 0xffffffff,
1117
.features = CPU_DEFAULT_FEATURES,
1120
.name = "BIT B5010",
1121
.iu_version = 0x20000000,
1122
.fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
1123
.mmu_version = 0x20000000,
1124
.mmu_bm = 0x00004000,
1125
.mmu_ctpr_mask = 0x007ffff0,
1126
.mmu_cxr_mask = 0x0000003f,
1127
.mmu_sfsr_mask = 0xffffffff,
1128
.mmu_trcr_mask = 0xffffffff,
1130
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1134
.name = "Matsushita MN10501",
1135
.iu_version = 0x50000000,
1136
.fpu_version = 0 << 17,
1137
.mmu_version = 0x50000000,
1138
.mmu_bm = 0x00004000,
1139
.mmu_ctpr_mask = 0x007ffff0,
1140
.mmu_cxr_mask = 0x0000003f,
1141
.mmu_sfsr_mask = 0xffffffff,
1142
.mmu_trcr_mask = 0xffffffff,
1144
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
1148
.name = "Weitek W8601",
1149
.iu_version = 0x90 << 24, /* Impl 9, ver 0 */
1150
.fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
1151
.mmu_version = 0x10 << 24,
1152
.mmu_bm = 0x00004000,
1153
.mmu_ctpr_mask = 0x007ffff0,
1154
.mmu_cxr_mask = 0x0000003f,
1155
.mmu_sfsr_mask = 0xffffffff,
1156
.mmu_trcr_mask = 0xffffffff,
1158
.features = CPU_DEFAULT_FEATURES,
1162
.iu_version = 0xf2000000,
1163
.fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1164
.mmu_version = 0xf2000000,
1165
.mmu_bm = 0x00004000,
1166
.mmu_ctpr_mask = 0x007ffff0,
1167
.mmu_cxr_mask = 0x0000003f,
1168
.mmu_sfsr_mask = 0xffffffff,
1169
.mmu_trcr_mask = 0xffffffff,
1171
.features = CPU_DEFAULT_FEATURES,
1175
.iu_version = 0xf3000000,
1176
.fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1177
.mmu_version = 0xf3000000,
1178
.mmu_bm = 0x00004000,
1179
.mmu_ctpr_mask = 0x007ffff0,
1180
.mmu_cxr_mask = 0x0000003f,
1181
.mmu_sfsr_mask = 0xffffffff,
1182
.mmu_trcr_mask = 0xffffffff,
1184
.features = CPU_DEFAULT_FEATURES,
1189
static const char * const feature_name[] = {
1206
static void print_features(FILE *f,
1207
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
1208
uint32_t features, const char *prefix)
1212
for (i = 0; i < ARRAY_SIZE(feature_name); i++)
1213
if (feature_name[i] && (features & (1 << i))) {
1215
(*cpu_fprintf)(f, "%s", prefix);
1216
(*cpu_fprintf)(f, "%s ", feature_name[i]);
1220
static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
1224
for (i = 0; i < ARRAY_SIZE(feature_name); i++)
1225
if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
1226
*features |= 1 << i;
1229
fprintf(stderr, "CPU feature %s not found\n", flagname);
1232
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
1235
const sparc_def_t *def = NULL;
1236
char *s = strdup(cpu_model);
1237
char *featurestr, *name = strtok(s, ",");
1238
uint32_t plus_features = 0;
1239
uint32_t minus_features = 0;
1240
long long iu_version;
1241
uint32_t fpu_version, mmu_version, nwindows;
1243
for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
1244
if (strcasecmp(name, sparc_defs[i].name) == 0) {
1245
def = &sparc_defs[i];
1250
memcpy(cpu_def, def, sizeof(*def));
1252
featurestr = strtok(NULL, ",");
1253
while (featurestr) {
1256
if (featurestr[0] == '+') {
1257
add_flagname_to_bitmaps(featurestr + 1, &plus_features);
1258
} else if (featurestr[0] == '-') {
1259
add_flagname_to_bitmaps(featurestr + 1, &minus_features);
1260
} else if ((val = strchr(featurestr, '='))) {
1262
if (!strcmp(featurestr, "iu_version")) {
1265
iu_version = strtoll(val, &err, 0);
1266
if (!*val || *err) {
1267
fprintf(stderr, "bad numerical value %s\n", val);
1270
cpu_def->iu_version = iu_version;
1271
#ifdef DEBUG_FEATURES
1272
fprintf(stderr, "iu_version %llx\n", iu_version);
1274
} else if (!strcmp(featurestr, "fpu_version")) {
1277
fpu_version = strtol(val, &err, 0);
1278
if (!*val || *err) {
1279
fprintf(stderr, "bad numerical value %s\n", val);
1282
cpu_def->fpu_version = fpu_version;
1283
#ifdef DEBUG_FEATURES
1284
fprintf(stderr, "fpu_version %llx\n", fpu_version);
1286
} else if (!strcmp(featurestr, "mmu_version")) {
1289
mmu_version = strtol(val, &err, 0);
1290
if (!*val || *err) {
1291
fprintf(stderr, "bad numerical value %s\n", val);
1294
cpu_def->mmu_version = mmu_version;
1295
#ifdef DEBUG_FEATURES
1296
fprintf(stderr, "mmu_version %llx\n", mmu_version);
1298
} else if (!strcmp(featurestr, "nwindows")) {
1301
nwindows = strtol(val, &err, 0);
1302
if (!*val || *err || nwindows > MAX_NWINDOWS ||
1303
nwindows < MIN_NWINDOWS) {
1304
fprintf(stderr, "bad numerical value %s\n", val);
1307
cpu_def->nwindows = nwindows;
1308
#ifdef DEBUG_FEATURES
1309
fprintf(stderr, "nwindows %d\n", nwindows);
1312
fprintf(stderr, "unrecognized feature %s\n", featurestr);
1316
fprintf(stderr, "feature string `%s' not in format "
1317
"(+feature|-feature|feature=xyz)\n", featurestr);
1320
featurestr = strtok(NULL, ",");
1322
cpu_def->features |= plus_features;
1323
cpu_def->features &= ~minus_features;
1324
#ifdef DEBUG_FEATURES
1325
print_features(stderr, fprintf, cpu_def->features, NULL);
1335
void sparc_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
1339
for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
1340
(*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x NWINS %d ",
1342
sparc_defs[i].iu_version,
1343
sparc_defs[i].fpu_version,
1344
sparc_defs[i].mmu_version,
1345
sparc_defs[i].nwindows);
1346
print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
1347
~sparc_defs[i].features, "-");
1348
print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
1349
sparc_defs[i].features, "+");
1350
(*cpu_fprintf)(f, "\n");
1352
(*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
1353
print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
1354
(*cpu_fprintf)(f, "\n");
1355
(*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
1356
print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
1357
(*cpu_fprintf)(f, "\n");
1358
(*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
1359
"fpu_version mmu_version nwindows\n");
1362
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
1364
void cpu_dump_state(CPUState *env, FILE *f,
1365
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
1370
cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc,
1372
cpu_fprintf(f, "General Registers:\n");
1373
for (i = 0; i < 4; i++)
1374
cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
1375
cpu_fprintf(f, "\n");
1377
cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
1378
cpu_fprintf(f, "\nCurrent Register Window:\n");
1379
for (x = 0; x < 3; x++) {
1380
for (i = 0; i < 4; i++)
1381
cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
1382
(x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
1383
env->regwptr[i + x * 8]);
1384
cpu_fprintf(f, "\n");
1386
cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
1387
(x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
1388
env->regwptr[i + x * 8]);
1389
cpu_fprintf(f, "\n");
1391
cpu_fprintf(f, "\nFloating Point Registers:\n");
1392
for (i = 0; i < 32; i++) {
1394
cpu_fprintf(f, "%%f%02d:", i);
1395
cpu_fprintf(f, " %016f", *(float *)&env->fpr[i]);
1397
cpu_fprintf(f, "\n");
1399
#ifdef TARGET_SPARC64
1400
cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
1401
env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
1402
cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d "
1403
"cleanwin %d cwp %d\n",
1404
env->cansave, env->canrestore, env->otherwin, env->wstate,
1405
env->cleanwin, env->nwindows - 1 - env->cwp);
1407
cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n",
1408
GET_PSR(env), GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
1409
GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
1410
env->psrs?'S':'-', env->psrps?'P':'-',
1411
env->psret?'E':'-', env->wim);
1413
cpu_fprintf(f, "fsr: 0x%08x\n", env->fsr);
586
void memcpy32(target_ulong *dst, const target_ulong *src)