Revision 1a14026e
b/hw/sun4m.c | ||
---|---|---|
404 | 404 |
qemu_register_reset(secondary_cpu_reset, env); |
405 | 405 |
env->halted = 1; |
406 | 406 |
} |
407 |
register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
|
|
407 |
register_savevm("cpu", i, 4, cpu_save, cpu_load, env);
|
|
408 | 408 |
cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS); |
409 | 409 |
env->prom_addr = hwdef->slavio_base; |
410 | 410 |
} |
... | ... | |
579 | 579 |
cpu_sparc_set_id(env, 0); |
580 | 580 |
|
581 | 581 |
qemu_register_reset(main_cpu_reset, env); |
582 |
register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
|
|
582 |
register_savevm("cpu", 0, 4, cpu_save, cpu_load, env);
|
|
583 | 583 |
cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS); |
584 | 584 |
env->prom_addr = hwdef->slavio_base; |
585 | 585 |
|
... | ... | |
1391 | 1391 |
qemu_register_reset(secondary_cpu_reset, env); |
1392 | 1392 |
env->halted = 1; |
1393 | 1393 |
} |
1394 |
register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
|
|
1394 |
register_savevm("cpu", i, 4, cpu_save, cpu_load, env);
|
|
1395 | 1395 |
cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS); |
1396 | 1396 |
env->prom_addr = hwdef->slavio_base; |
1397 | 1397 |
} |
b/hw/sun4u.c | ||
---|---|---|
260 | 260 |
bh = qemu_bh_new(hstick_irq, env); |
261 | 261 |
env->hstick = ptimer_init(bh); |
262 | 262 |
ptimer_set_period(env->hstick, 1ULL); |
263 |
register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
|
|
263 |
register_savevm("cpu", 0, 4, cpu_save, cpu_load, env);
|
|
264 | 264 |
qemu_register_reset(main_cpu_reset, env); |
265 | 265 |
main_cpu_reset(env); |
266 | 266 |
|
b/linux-user/main.c | ||
---|---|---|
626 | 626 |
can be found at http://www.sics.se/~psm/sparcstack.html */ |
627 | 627 |
static inline int get_reg_index(CPUSPARCState *env, int cwp, int index) |
628 | 628 |
{ |
629 |
index = (index + cwp * 16) & (16 * NWINDOWS - 1);
|
|
629 |
index = (index + cwp * 16) % (16 * env->nwindows);
|
|
630 | 630 |
/* wrap handling : if cwp is on the last window, then we use the |
631 | 631 |
registers 'after' the end */ |
632 |
if (index < 8 && env->cwp == (NWINDOWS - 1))
|
|
633 |
index += (16 * NWINDOWS);
|
|
632 |
if (index < 8 && env->cwp == env->nwindows - 1)
|
|
633 |
index += 16 * env->nwindows;
|
|
634 | 634 |
return index; |
635 | 635 |
} |
636 | 636 |
|
... | ... | |
656 | 656 |
{ |
657 | 657 |
#ifndef TARGET_SPARC64 |
658 | 658 |
unsigned int new_wim; |
659 |
new_wim = ((env->wim >> 1) | (env->wim << (NWINDOWS - 1))) &
|
|
660 |
((1LL << NWINDOWS) - 1);
|
|
661 |
save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1));
|
|
659 |
new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
|
|
660 |
((1LL << env->nwindows) - 1);
|
|
661 |
save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
|
|
662 | 662 |
env->wim = new_wim; |
663 | 663 |
#else |
664 |
save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1));
|
|
664 |
save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
|
|
665 | 665 |
env->cansave++; |
666 | 666 |
env->canrestore--; |
667 | 667 |
#endif |
... | ... | |
672 | 672 |
unsigned int new_wim, i, cwp1; |
673 | 673 |
abi_ulong sp_ptr; |
674 | 674 |
|
675 |
new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) &
|
|
676 |
((1LL << NWINDOWS) - 1);
|
|
675 |
new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
|
|
676 |
((1LL << env->nwindows) - 1);
|
|
677 | 677 |
|
678 | 678 |
/* restore the invalid window */ |
679 |
cwp1 = (env->cwp + 1) & (NWINDOWS - 1);
|
|
679 |
cwp1 = cpu_cwp_inc(env, env->cwp + 1);
|
|
680 | 680 |
sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)]; |
681 | 681 |
#if defined(DEBUG_WIN) |
682 | 682 |
printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n", |
... | ... | |
690 | 690 |
env->wim = new_wim; |
691 | 691 |
#ifdef TARGET_SPARC64 |
692 | 692 |
env->canrestore++; |
693 |
if (env->cleanwin < NWINDOWS - 1)
|
|
694 |
env->cleanwin++;
|
|
693 |
if (env->cleanwin < env->nwindows - 1)
|
|
694 |
env->cleanwin++;
|
|
695 | 695 |
env->cansave--; |
696 | 696 |
#endif |
697 | 697 |
} |
... | ... | |
703 | 703 |
offset = 1; |
704 | 704 |
for(;;) { |
705 | 705 |
/* if restore would invoke restore_window(), then we can stop */ |
706 |
cwp1 = (env->cwp + offset) & (NWINDOWS - 1);
|
|
706 |
cwp1 = cpu_cwp_inc(env, env->cwp + offset);
|
|
707 | 707 |
if (env->wim & (1 << cwp1)) |
708 | 708 |
break; |
709 | 709 |
save_window_offset(env, cwp1); |
710 | 710 |
offset++; |
711 | 711 |
} |
712 | 712 |
/* set wim so that restore will reload the registers */ |
713 |
cwp1 = (env->cwp + 1) & (NWINDOWS - 1);
|
|
713 |
cwp1 = cpu_cwp_inc(env, env->cwp + 1);
|
|
714 | 714 |
env->wim = 1 << cwp1; |
715 | 715 |
#if defined(DEBUG_WIN) |
716 | 716 |
printf("flush_windows: nb=%d\n", offset - 1); |
b/target-sparc/TODO | ||
---|---|---|
6 | 6 |
slot next page) |
7 | 7 |
- Atomical instructions |
8 | 8 |
- CPU features should match real CPUs (also ASI selection) |
9 |
- Allow choosing of NWINDOWS (CPU model specific and as a CPU feature) |
|
10 | 9 |
- Optimizations/improvements: |
11 | 10 |
- Condition code/branch handling like x86, also for FPU? |
12 | 11 |
- Remove remaining explicit alignment checks |
b/target-sparc/cpu.h | ||
---|---|---|
170 | 170 |
#define PG_MODIFIED_MASK (1 << PG_MODIFIED_BIT) |
171 | 171 |
#define PG_CACHE_MASK (1 << PG_CACHE_BIT) |
172 | 172 |
|
173 |
/* 2 <= NWINDOWS <= 32. In QEMU it must also be a power of two. */ |
|
174 |
#define NWINDOWS 8 |
|
173 |
/* 3 <= NWINDOWS <= 32. */ |
|
174 |
#define MIN_NWINDOWS 3 |
|
175 |
#define MAX_NWINDOWS 32 |
|
175 | 176 |
|
176 | 177 |
#if !defined(TARGET_SPARC64) |
177 | 178 |
#define NB_MMU_MODES 2 |
... | ... | |
222 | 223 |
uint32_t mmu_cxr_mask; |
223 | 224 |
uint32_t mmu_sfsr_mask; |
224 | 225 |
uint32_t mmu_trcr_mask; |
226 |
uint32_t nwindows; |
|
225 | 227 |
/* NOTE: we allow 8 more registers to handle wrapping */ |
226 |
target_ulong regbase[NWINDOWS * 16 + 8]; |
|
228 |
target_ulong regbase[MAX_NWINDOWS * 16 + 8];
|
|
227 | 229 |
|
228 | 230 |
CPU_COMMON |
229 | 231 |
|
... | ... | |
330 | 332 |
|
331 | 333 |
#ifndef NO_CPU_IO_DEFS |
332 | 334 |
void cpu_set_cwp(CPUSPARCState *env1, int new_cwp); |
335 |
|
|
336 |
static inline int cpu_cwp_inc(CPUSPARCState *env1, int cwp) |
|
337 |
{ |
|
338 |
if (unlikely(cwp >= env1->nwindows)) |
|
339 |
cwp -= env1->nwindows; |
|
340 |
return cwp; |
|
341 |
} |
|
342 |
|
|
343 |
static inline int cpu_cwp_dec(CPUSPARCState *env1, int cwp) |
|
344 |
{ |
|
345 |
if (unlikely(cwp < 0)) |
|
346 |
cwp += env1->nwindows; |
|
347 |
return cwp; |
|
348 |
} |
|
333 | 349 |
#endif |
334 | 350 |
|
335 | 351 |
#define PUT_PSR(env, val) do { int _tmp = val; \ |
... | ... | |
348 | 364 |
env->xcc = (_tmp >> 4) << 20; \ |
349 | 365 |
env->psr = (_tmp & 0xf) << 20; \ |
350 | 366 |
} while (0) |
351 |
#define GET_CWP64(env) (NWINDOWS - 1 - (env)->cwp) |
|
352 |
#define PUT_CWP64(env, val) \ |
|
353 |
cpu_set_cwp(env, NWINDOWS - 1 - ((val) & (NWINDOWS - 1))) |
|
367 |
#define GET_CWP64(env) (env->nwindows - 1 - (env)->cwp) |
|
368 |
|
|
369 |
static inline void PUT_CWP64(CPUSPARCState *env1, int cwp) |
|
370 |
{ |
|
371 |
if (unlikely(cwp >= env1->nwindows || cwp < 0)) |
|
372 |
cwp = 0; |
|
373 |
cpu_set_cwp(env1, env1->nwindows - 1 - cwp); |
|
374 |
} |
|
354 | 375 |
|
355 | 376 |
#endif |
356 | 377 |
|
b/target-sparc/helper.c | ||
---|---|---|
47 | 47 |
uint32_t mmu_sfsr_mask; |
48 | 48 |
uint32_t mmu_trcr_mask; |
49 | 49 |
uint32_t features; |
50 |
uint32_t nwindows; |
|
50 | 51 |
}; |
51 | 52 |
|
52 | 53 |
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model); |
... | ... | |
750 | 751 |
change_pstate(PS_PEF | PS_PRIV | PS_AG); |
751 | 752 |
|
752 | 753 |
if (intno == TT_CLRWIN) |
753 |
cpu_set_cwp(env, (env->cwp - 1) & (NWINDOWS - 1));
|
|
754 |
cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
|
|
754 | 755 |
else if ((intno & 0x1c0) == TT_SPILL) |
755 |
cpu_set_cwp(env, (env->cwp - env->cansave - 2) & (NWINDOWS - 1));
|
|
756 |
cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
|
|
756 | 757 |
else if ((intno & 0x1c0) == TT_FILL) |
757 |
cpu_set_cwp(env, (env->cwp + 1) & (NWINDOWS - 1));
|
|
758 |
cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
|
|
758 | 759 |
env->tbr &= ~0x7fffULL; |
759 | 760 |
env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5); |
760 | 761 |
if (env->tl < MAXTL - 1) { |
... | ... | |
853 | 854 |
} |
854 | 855 |
#endif |
855 | 856 |
env->psret = 0; |
856 |
cwp = (env->cwp - 1) & (NWINDOWS - 1);
|
|
857 |
cwp = cpu_cwp_dec(env, env->cwp - 1);
|
|
857 | 858 |
cpu_set_cwp(env, cwp); |
858 | 859 |
env->regwptr[9] = env->pc; |
859 | 860 |
env->regwptr[10] = env->npc; |
... | ... | |
887 | 888 |
#if defined(CONFIG_USER_ONLY) |
888 | 889 |
env->user_mode_only = 1; |
889 | 890 |
#ifdef TARGET_SPARC64 |
890 |
env->cleanwin = NWINDOWS - 2;
|
|
891 |
env->cansave = NWINDOWS - 2;
|
|
891 |
env->cleanwin = env->nwindows - 2;
|
|
892 |
env->cansave = env->nwindows - 2;
|
|
892 | 893 |
env->pstate = PS_RMO | PS_PEF | PS_IE; |
893 | 894 |
env->asi = 0x82; // Primary no-fault |
894 | 895 |
#endif |
... | ... | |
921 | 922 |
env->cpu_model_str = cpu_model; |
922 | 923 |
env->version = def->iu_version; |
923 | 924 |
env->fsr = def->fpu_version; |
925 |
env->nwindows = def->nwindows; |
|
924 | 926 |
#if !defined(TARGET_SPARC64) |
925 | 927 |
env->mmu_bm = def->mmu_bm; |
926 | 928 |
env->mmu_ctpr_mask = def->mmu_ctpr_mask; |
... | ... | |
929 | 931 |
env->mmu_trcr_mask = def->mmu_trcr_mask; |
930 | 932 |
env->mmuregs[0] |= def->mmu_version; |
931 | 933 |
cpu_sparc_set_id(env, 0); |
934 |
#else |
|
935 |
env->version |= def->nwindows - 1; |
|
932 | 936 |
#endif |
933 | 937 |
return 0; |
934 | 938 |
} |
... | ... | |
970 | 974 |
{ |
971 | 975 |
.name = "Fujitsu Sparc64", |
972 | 976 |
.iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24) |
973 |
| (MAXTL << 8) | (NWINDOWS - 1)),
|
|
977 |
| (MAXTL << 8)), |
|
974 | 978 |
.fpu_version = 0x00000000, |
975 | 979 |
.mmu_version = 0, |
980 |
.nwindows = 4, |
|
976 | 981 |
.features = CPU_DEFAULT_FEATURES, |
977 | 982 |
}, |
978 | 983 |
{ |
979 | 984 |
.name = "Fujitsu Sparc64 III", |
980 | 985 |
.iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24) |
981 |
| (MAXTL << 8) | (NWINDOWS - 1)),
|
|
986 |
| (MAXTL << 8)), |
|
982 | 987 |
.fpu_version = 0x00000000, |
983 | 988 |
.mmu_version = 0, |
989 |
.nwindows = 5, |
|
984 | 990 |
.features = CPU_DEFAULT_FEATURES, |
985 | 991 |
}, |
986 | 992 |
{ |
987 | 993 |
.name = "Fujitsu Sparc64 IV", |
988 | 994 |
.iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24) |
989 |
| (MAXTL << 8) | (NWINDOWS - 1)),
|
|
995 |
| (MAXTL << 8)), |
|
990 | 996 |
.fpu_version = 0x00000000, |
991 | 997 |
.mmu_version = 0, |
998 |
.nwindows = 8, |
|
992 | 999 |
.features = CPU_DEFAULT_FEATURES, |
993 | 1000 |
}, |
994 | 1001 |
{ |
995 | 1002 |
.name = "Fujitsu Sparc64 V", |
996 | 1003 |
.iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24) |
997 |
| (MAXTL << 8) | (NWINDOWS - 1)),
|
|
1004 |
| (MAXTL << 8)), |
|
998 | 1005 |
.fpu_version = 0x00000000, |
999 | 1006 |
.mmu_version = 0, |
1007 |
.nwindows = 8, |
|
1000 | 1008 |
.features = CPU_DEFAULT_FEATURES, |
1001 | 1009 |
}, |
1002 | 1010 |
{ |
1003 | 1011 |
.name = "TI UltraSparc I", |
1004 | 1012 |
.iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24) |
1005 |
| (MAXTL << 8) | (NWINDOWS - 1)),
|
|
1013 |
| (MAXTL << 8)), |
|
1006 | 1014 |
.fpu_version = 0x00000000, |
1007 | 1015 |
.mmu_version = 0, |
1016 |
.nwindows = 8, |
|
1008 | 1017 |
.features = CPU_DEFAULT_FEATURES, |
1009 | 1018 |
}, |
1010 | 1019 |
{ |
1011 | 1020 |
.name = "TI UltraSparc II", |
1012 | 1021 |
.iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24) |
1013 |
| (MAXTL << 8) | (NWINDOWS - 1)),
|
|
1022 |
| (MAXTL << 8)), |
|
1014 | 1023 |
.fpu_version = 0x00000000, |
1015 | 1024 |
.mmu_version = 0, |
1025 |
.nwindows = 8, |
|
1016 | 1026 |
.features = CPU_DEFAULT_FEATURES, |
1017 | 1027 |
}, |
1018 | 1028 |
{ |
1019 | 1029 |
.name = "TI UltraSparc IIi", |
1020 | 1030 |
.iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24) |
1021 |
| (MAXTL << 8) | (NWINDOWS - 1)),
|
|
1031 |
| (MAXTL << 8)), |
|
1022 | 1032 |
.fpu_version = 0x00000000, |
1023 | 1033 |
.mmu_version = 0, |
1034 |
.nwindows = 8, |
|
1024 | 1035 |
.features = CPU_DEFAULT_FEATURES, |
1025 | 1036 |
}, |
1026 | 1037 |
{ |
1027 | 1038 |
.name = "TI UltraSparc IIe", |
1028 | 1039 |
.iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24) |
1029 |
| (MAXTL << 8) | (NWINDOWS - 1)),
|
|
1040 |
| (MAXTL << 8)), |
|
1030 | 1041 |
.fpu_version = 0x00000000, |
1031 | 1042 |
.mmu_version = 0, |
1043 |
.nwindows = 8, |
|
1032 | 1044 |
.features = CPU_DEFAULT_FEATURES, |
1033 | 1045 |
}, |
1034 | 1046 |
{ |
1035 | 1047 |
.name = "Sun UltraSparc III", |
1036 | 1048 |
.iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24) |
1037 |
| (MAXTL << 8) | (NWINDOWS - 1)),
|
|
1049 |
| (MAXTL << 8)), |
|
1038 | 1050 |
.fpu_version = 0x00000000, |
1039 | 1051 |
.mmu_version = 0, |
1052 |
.nwindows = 8, |
|
1040 | 1053 |
.features = CPU_DEFAULT_FEATURES, |
1041 | 1054 |
}, |
1042 | 1055 |
{ |
1043 | 1056 |
.name = "Sun UltraSparc III Cu", |
1044 | 1057 |
.iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24) |
1045 |
| (MAXTL << 8) | (NWINDOWS - 1)),
|
|
1058 |
| (MAXTL << 8)), |
|
1046 | 1059 |
.fpu_version = 0x00000000, |
1047 | 1060 |
.mmu_version = 0, |
1061 |
.nwindows = 8, |
|
1048 | 1062 |
.features = CPU_DEFAULT_FEATURES, |
1049 | 1063 |
}, |
1050 | 1064 |
{ |
1051 | 1065 |
.name = "Sun UltraSparc IIIi", |
1052 | 1066 |
.iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24) |
1053 |
| (MAXTL << 8) | (NWINDOWS - 1)),
|
|
1067 |
| (MAXTL << 8)), |
|
1054 | 1068 |
.fpu_version = 0x00000000, |
1055 | 1069 |
.mmu_version = 0, |
1070 |
.nwindows = 8, |
|
1056 | 1071 |
.features = CPU_DEFAULT_FEATURES, |
1057 | 1072 |
}, |
1058 | 1073 |
{ |
1059 | 1074 |
.name = "Sun UltraSparc IV", |
1060 | 1075 |
.iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24) |
1061 |
| (MAXTL << 8) | (NWINDOWS - 1)),
|
|
1076 |
| (MAXTL << 8)), |
|
1062 | 1077 |
.fpu_version = 0x00000000, |
1063 | 1078 |
.mmu_version = 0, |
1079 |
.nwindows = 8, |
|
1064 | 1080 |
.features = CPU_DEFAULT_FEATURES, |
1065 | 1081 |
}, |
1066 | 1082 |
{ |
1067 | 1083 |
.name = "Sun UltraSparc IV+", |
1068 | 1084 |
.iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24) |
1069 |
| (MAXTL << 8) | (NWINDOWS - 1)),
|
|
1085 |
| (MAXTL << 8)), |
|
1070 | 1086 |
.fpu_version = 0x00000000, |
1071 | 1087 |
.mmu_version = 0, |
1088 |
.nwindows = 8, |
|
1072 | 1089 |
.features = CPU_DEFAULT_FEATURES, |
1073 | 1090 |
}, |
1074 | 1091 |
{ |
1075 | 1092 |
.name = "Sun UltraSparc IIIi+", |
1076 | 1093 |
.iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24) |
1077 |
| (MAXTL << 8) | (NWINDOWS - 1)),
|
|
1094 |
| (MAXTL << 8)), |
|
1078 | 1095 |
.fpu_version = 0x00000000, |
1079 | 1096 |
.mmu_version = 0, |
1097 |
.nwindows = 8, |
|
1080 | 1098 |
.features = CPU_DEFAULT_FEATURES, |
1081 | 1099 |
}, |
1082 | 1100 |
{ |
1083 | 1101 |
.name = "NEC UltraSparc I", |
1084 | 1102 |
.iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24) |
1085 |
| (MAXTL << 8) | (NWINDOWS - 1)),
|
|
1103 |
| (MAXTL << 8)), |
|
1086 | 1104 |
.fpu_version = 0x00000000, |
1087 | 1105 |
.mmu_version = 0, |
1106 |
.nwindows = 8, |
|
1088 | 1107 |
.features = CPU_DEFAULT_FEATURES, |
1089 | 1108 |
}, |
1090 | 1109 |
#else |
... | ... | |
1098 | 1117 |
.mmu_cxr_mask = 0x0000003f, |
1099 | 1118 |
.mmu_sfsr_mask = 0xffffffff, |
1100 | 1119 |
.mmu_trcr_mask = 0xffffffff, |
1120 |
.nwindows = 7, |
|
1101 | 1121 |
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD, |
1102 | 1122 |
}, |
1103 | 1123 |
{ |
... | ... | |
1110 | 1130 |
.mmu_cxr_mask = 0x000000ff, |
1111 | 1131 |
.mmu_sfsr_mask = 0x00016fff, |
1112 | 1132 |
.mmu_trcr_mask = 0x00ffffff, |
1133 |
.nwindows = 8, |
|
1113 | 1134 |
.features = CPU_DEFAULT_FEATURES, |
1114 | 1135 |
}, |
1115 | 1136 |
{ |
... | ... | |
1122 | 1143 |
.mmu_cxr_mask = 0x000000ff, |
1123 | 1144 |
.mmu_sfsr_mask = 0x00016fff, |
1124 | 1145 |
.mmu_trcr_mask = 0xffffffff, |
1146 |
.nwindows = 8, |
|
1125 | 1147 |
.features = CPU_DEFAULT_FEATURES, |
1126 | 1148 |
}, |
1127 | 1149 |
{ |
... | ... | |
1134 | 1156 |
.mmu_cxr_mask = 0x0000003f, |
1135 | 1157 |
.mmu_sfsr_mask = 0xffffffff, |
1136 | 1158 |
.mmu_trcr_mask = 0xffffffff, |
1159 |
.nwindows = 8, |
|
1137 | 1160 |
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT | |
1138 | 1161 |
CPU_FEATURE_FSMULD, |
1139 | 1162 |
}, |
... | ... | |
1147 | 1170 |
.mmu_cxr_mask = 0x0000003f, |
1148 | 1171 |
.mmu_sfsr_mask = 0xffffffff, |
1149 | 1172 |
.mmu_trcr_mask = 0xffffffff, |
1173 |
.nwindows = 8, |
|
1150 | 1174 |
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT | |
1151 | 1175 |
CPU_FEATURE_FSMULD, |
1152 | 1176 |
}, |
... | ... | |
1160 | 1184 |
.mmu_cxr_mask = 0x0000003f, |
1161 | 1185 |
.mmu_sfsr_mask = 0xffffffff, |
1162 | 1186 |
.mmu_trcr_mask = 0xffffffff, |
1187 |
.nwindows = 8, |
|
1163 | 1188 |
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT | |
1164 | 1189 |
CPU_FEATURE_FSMULD, |
1165 | 1190 |
}, |
... | ... | |
1173 | 1198 |
.mmu_cxr_mask = 0x0000ffff, |
1174 | 1199 |
.mmu_sfsr_mask = 0xffffffff, |
1175 | 1200 |
.mmu_trcr_mask = 0xffffffff, |
1201 |
.nwindows = 8, |
|
1176 | 1202 |
.features = CPU_DEFAULT_FEATURES, |
1177 | 1203 |
}, |
1178 | 1204 |
{ |
... | ... | |
1185 | 1211 |
.mmu_cxr_mask = 0x0000003f, |
1186 | 1212 |
.mmu_sfsr_mask = 0x00016fff, |
1187 | 1213 |
.mmu_trcr_mask = 0x0000003f, |
1214 |
.nwindows = 7, |
|
1188 | 1215 |
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL | |
1189 | 1216 |
CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | |
1190 | 1217 |
CPU_FEATURE_FMUL, |
... | ... | |
1199 | 1226 |
.mmu_cxr_mask = 0x000000ff, |
1200 | 1227 |
.mmu_sfsr_mask = 0x00016fff, |
1201 | 1228 |
.mmu_trcr_mask = 0x00ffffff, |
1229 |
.nwindows = 8, |
|
1202 | 1230 |
.features = CPU_DEFAULT_FEATURES, |
1203 | 1231 |
}, |
1204 | 1232 |
{ |
... | ... | |
1211 | 1239 |
.mmu_cxr_mask = 0x000000ff, |
1212 | 1240 |
.mmu_sfsr_mask = 0x00016bff, |
1213 | 1241 |
.mmu_trcr_mask = 0x00ffffff, |
1242 |
.nwindows = 8, |
|
1214 | 1243 |
.features = CPU_DEFAULT_FEATURES, |
1215 | 1244 |
}, |
1216 | 1245 |
{ |
... | ... | |
1223 | 1252 |
.mmu_cxr_mask = 0x0000ffff, |
1224 | 1253 |
.mmu_sfsr_mask = 0xffffffff, |
1225 | 1254 |
.mmu_trcr_mask = 0xffffffff, |
1255 |
.nwindows = 8, |
|
1226 | 1256 |
.features = CPU_DEFAULT_FEATURES, |
1227 | 1257 |
}, |
1228 | 1258 |
{ |
... | ... | |
1235 | 1265 |
.mmu_cxr_mask = 0x0000ffff, |
1236 | 1266 |
.mmu_sfsr_mask = 0xffffffff, |
1237 | 1267 |
.mmu_trcr_mask = 0xffffffff, |
1268 |
.nwindows = 8, |
|
1238 | 1269 |
.features = CPU_DEFAULT_FEATURES, |
1239 | 1270 |
}, |
1240 | 1271 |
{ |
... | ... | |
1247 | 1278 |
.mmu_cxr_mask = 0x0000ffff, |
1248 | 1279 |
.mmu_sfsr_mask = 0xffffffff, |
1249 | 1280 |
.mmu_trcr_mask = 0xffffffff, |
1281 |
.nwindows = 8, |
|
1250 | 1282 |
.features = CPU_DEFAULT_FEATURES, |
1251 | 1283 |
}, |
1252 | 1284 |
{ |
... | ... | |
1259 | 1291 |
.mmu_cxr_mask = 0x0000ffff, |
1260 | 1292 |
.mmu_sfsr_mask = 0xffffffff, |
1261 | 1293 |
.mmu_trcr_mask = 0xffffffff, |
1294 |
.nwindows = 8, |
|
1262 | 1295 |
.features = CPU_DEFAULT_FEATURES, |
1263 | 1296 |
}, |
1264 | 1297 |
{ |
... | ... | |
1271 | 1304 |
.mmu_cxr_mask = 0x0000ffff, |
1272 | 1305 |
.mmu_sfsr_mask = 0xffffffff, |
1273 | 1306 |
.mmu_trcr_mask = 0xffffffff, |
1307 |
.nwindows = 8, |
|
1274 | 1308 |
.features = CPU_DEFAULT_FEATURES, |
1275 | 1309 |
}, |
1276 | 1310 |
{ |
... | ... | |
1283 | 1317 |
.mmu_cxr_mask = 0x0000003f, |
1284 | 1318 |
.mmu_sfsr_mask = 0xffffffff, |
1285 | 1319 |
.mmu_trcr_mask = 0xffffffff, |
1320 |
.nwindows = 8, |
|
1286 | 1321 |
.features = CPU_DEFAULT_FEATURES, |
1287 | 1322 |
}, |
1288 | 1323 |
{ |
... | ... | |
1295 | 1330 |
.mmu_cxr_mask = 0x0000003f, |
1296 | 1331 |
.mmu_sfsr_mask = 0xffffffff, |
1297 | 1332 |
.mmu_trcr_mask = 0xffffffff, |
1333 |
.nwindows = 8, |
|
1298 | 1334 |
.features = CPU_DEFAULT_FEATURES, |
1299 | 1335 |
}, |
1300 | 1336 |
{ |
... | ... | |
1307 | 1343 |
.mmu_cxr_mask = 0x0000003f, |
1308 | 1344 |
.mmu_sfsr_mask = 0xffffffff, |
1309 | 1345 |
.mmu_trcr_mask = 0xffffffff, |
1346 |
.nwindows = 8, |
|
1310 | 1347 |
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT | |
1311 | 1348 |
CPU_FEATURE_FSMULD, |
1312 | 1349 |
}, |
... | ... | |
1320 | 1357 |
.mmu_cxr_mask = 0x0000003f, |
1321 | 1358 |
.mmu_sfsr_mask = 0xffffffff, |
1322 | 1359 |
.mmu_trcr_mask = 0xffffffff, |
1360 |
.nwindows = 8, |
|
1323 | 1361 |
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT | |
1324 | 1362 |
CPU_FEATURE_FSMULD, |
1325 | 1363 |
}, |
... | ... | |
1333 | 1371 |
.mmu_cxr_mask = 0x0000003f, |
1334 | 1372 |
.mmu_sfsr_mask = 0xffffffff, |
1335 | 1373 |
.mmu_trcr_mask = 0xffffffff, |
1374 |
.nwindows = 8, |
|
1336 | 1375 |
.features = CPU_DEFAULT_FEATURES, |
1337 | 1376 |
}, |
1338 | 1377 |
{ |
... | ... | |
1345 | 1384 |
.mmu_cxr_mask = 0x0000003f, |
1346 | 1385 |
.mmu_sfsr_mask = 0xffffffff, |
1347 | 1386 |
.mmu_trcr_mask = 0xffffffff, |
1387 |
.nwindows = 8, |
|
1348 | 1388 |
.features = CPU_DEFAULT_FEATURES, |
1349 | 1389 |
}, |
1350 | 1390 |
{ |
... | ... | |
1357 | 1397 |
.mmu_cxr_mask = 0x0000003f, |
1358 | 1398 |
.mmu_sfsr_mask = 0xffffffff, |
1359 | 1399 |
.mmu_trcr_mask = 0xffffffff, |
1400 |
.nwindows = 8, |
|
1360 | 1401 |
.features = CPU_DEFAULT_FEATURES, |
1361 | 1402 |
}, |
1362 | 1403 |
#endif |
... | ... | |
1411 | 1452 |
uint32_t plus_features = 0; |
1412 | 1453 |
uint32_t minus_features = 0; |
1413 | 1454 |
long long iu_version; |
1414 |
uint32_t fpu_version, mmu_version; |
|
1455 |
uint32_t fpu_version, mmu_version, nwindows;
|
|
1415 | 1456 |
|
1416 | 1457 |
for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) { |
1417 | 1458 |
if (strcasecmp(name, sparc_defs[i].name) == 0) { |
... | ... | |
1468 | 1509 |
#ifdef DEBUG_FEATURES |
1469 | 1510 |
fprintf(stderr, "mmu_version %llx\n", mmu_version); |
1470 | 1511 |
#endif |
1512 |
} else if (!strcmp(featurestr, "nwindows")) { |
|
1513 |
char *err; |
|
1514 |
|
|
1515 |
nwindows = strtol(val, &err, 0); |
|
1516 |
if (!*val || *err || nwindows > MAX_NWINDOWS || |
|
1517 |
nwindows < MIN_NWINDOWS) { |
|
1518 |
fprintf(stderr, "bad numerical value %s\n", val); |
|
1519 |
goto error; |
|
1520 |
} |
|
1521 |
cpu_def->nwindows = nwindows; |
|
1522 |
#ifdef DEBUG_FEATURES |
|
1523 |
fprintf(stderr, "nwindows %d\n", nwindows); |
|
1524 |
#endif |
|
1471 | 1525 |
} else { |
1472 | 1526 |
fprintf(stderr, "unrecognized feature %s\n", featurestr); |
1473 | 1527 |
goto error; |
... | ... | |
1497 | 1551 |
unsigned int i; |
1498 | 1552 |
|
1499 | 1553 |
for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) { |
1500 |
(*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x ", |
|
1554 |
(*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x NWINS %d ",
|
|
1501 | 1555 |
sparc_defs[i].name, |
1502 | 1556 |
sparc_defs[i].iu_version, |
1503 | 1557 |
sparc_defs[i].fpu_version, |
1504 |
sparc_defs[i].mmu_version); |
|
1558 |
sparc_defs[i].mmu_version, |
|
1559 |
sparc_defs[i].nwindows); |
|
1505 | 1560 |
print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES & |
1506 | 1561 |
~sparc_defs[i].features, "-"); |
1507 | 1562 |
print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES & |
... | ... | |
1512 | 1567 |
print_features(f, cpu_fprintf, -1, NULL); |
1513 | 1568 |
(*cpu_fprintf)(f, "\n"); |
1514 | 1569 |
(*cpu_fprintf)(f, "Numerical features (=): iu_version fpu_version " |
1515 |
"mmu_version\n"); |
|
1570 |
"mmu_version nwindows\n");
|
|
1516 | 1571 |
} |
1517 | 1572 |
|
1518 | 1573 |
#define GET_FLAG(a,b) ((env->psr & a)?b:'-') |
... | ... | |
1558 | 1613 |
cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d " |
1559 | 1614 |
"cleanwin %d cwp %d\n", |
1560 | 1615 |
env->cansave, env->canrestore, env->otherwin, env->wstate, |
1561 |
env->cleanwin, NWINDOWS - 1 - env->cwp);
|
|
1616 |
env->cleanwin, env->nwindows - 1 - env->cwp);
|
|
1562 | 1617 |
#else |
1563 | 1618 |
cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", |
1564 | 1619 |
GET_PSR(env), GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'), |
b/target-sparc/machine.c | ||
---|---|---|
31 | 31 |
|
32 | 32 |
for(i = 0; i < 8; i++) |
33 | 33 |
qemu_put_betls(f, &env->gregs[i]); |
34 |
for(i = 0; i < NWINDOWS * 16; i++) |
|
34 |
qemu_put_be32s(f, &env->nwindows); |
|
35 |
for(i = 0; i < env->nwindows * 16; i++) |
|
35 | 36 |
qemu_put_betls(f, &env->regbase[i]); |
36 | 37 |
|
37 | 38 |
/* FPU */ |
... | ... | |
65 | 66 |
int i; |
66 | 67 |
uint32_t tmp; |
67 | 68 |
|
69 |
if (version_id != 4) |
|
70 |
return -EINVAL; |
|
68 | 71 |
for(i = 0; i < 8; i++) |
69 | 72 |
qemu_get_betls(f, &env->gregs[i]); |
70 |
for(i = 0; i < NWINDOWS * 16; i++) |
|
73 |
qemu_get_be32s(f, &env->nwindows); |
|
74 |
for(i = 0; i < env->nwindows * 16; i++) |
|
71 | 75 |
qemu_get_betls(f, &env->regbase[i]); |
72 | 76 |
|
73 | 77 |
/* FPU */ |
b/target-sparc/op_helper.c | ||
---|---|---|
2178 | 2178 |
raise_exception(TT_ILL_INSN); |
2179 | 2179 |
|
2180 | 2180 |
env->psret = 1; |
2181 |
cwp = (env->cwp + 1) & (NWINDOWS - 1);
|
|
2181 |
cwp = cpu_cwp_inc(env, env->cwp + 1) ;
|
|
2182 | 2182 |
if (env->wim & (1 << cwp)) { |
2183 | 2183 |
raise_exception(TT_WIN_UNF); |
2184 | 2184 |
} |
... | ... | |
2399 | 2399 |
{ |
2400 | 2400 |
uint32_t cwp; |
2401 | 2401 |
|
2402 |
cwp = (env->cwp - 1) & (NWINDOWS - 1);
|
|
2402 |
cwp = cpu_cwp_dec(env, env->cwp - 1);
|
|
2403 | 2403 |
if (env->wim & (1 << cwp)) { |
2404 | 2404 |
raise_exception(TT_WIN_OVF); |
2405 | 2405 |
} |
... | ... | |
2410 | 2410 |
{ |
2411 | 2411 |
uint32_t cwp; |
2412 | 2412 |
|
2413 |
cwp = (env->cwp + 1) & (NWINDOWS - 1);
|
|
2413 |
cwp = cpu_cwp_inc(env, env->cwp + 1);
|
|
2414 | 2414 |
if (env->wim & (1 << cwp)) { |
2415 | 2415 |
raise_exception(TT_WIN_UNF); |
2416 | 2416 |
} |
... | ... | |
2419 | 2419 |
|
2420 | 2420 |
void helper_wrpsr(target_ulong new_psr) |
2421 | 2421 |
{ |
2422 |
if ((new_psr & PSR_CWP) >= NWINDOWS)
|
|
2422 |
if ((new_psr & PSR_CWP) >= env->nwindows)
|
|
2423 | 2423 |
raise_exception(TT_ILL_INSN); |
2424 | 2424 |
else |
2425 | 2425 |
PUT_PSR(env, new_psr); |
... | ... | |
2437 | 2437 |
{ |
2438 | 2438 |
uint32_t cwp; |
2439 | 2439 |
|
2440 |
cwp = (env->cwp - 1) & (NWINDOWS - 1);
|
|
2440 |
cwp = cpu_cwp_dec(env, env->cwp - 1);
|
|
2441 | 2441 |
if (env->cansave == 0) { |
2442 | 2442 |
raise_exception(TT_SPILL | (env->otherwin != 0 ? |
2443 | 2443 |
(TT_WOTHER | ((env->wstate & 0x38) >> 1)): |
... | ... | |
2458 | 2458 |
{ |
2459 | 2459 |
uint32_t cwp; |
2460 | 2460 |
|
2461 |
cwp = (env->cwp + 1) & (NWINDOWS - 1);
|
|
2461 |
cwp = cpu_cwp_inc(env, env->cwp + 1);
|
|
2462 | 2462 |
if (env->canrestore == 0) { |
2463 | 2463 |
raise_exception(TT_FILL | (env->otherwin != 0 ? |
2464 | 2464 |
(TT_WOTHER | ((env->wstate & 0x38) >> 1)): |
... | ... | |
2472 | 2472 |
|
2473 | 2473 |
void helper_flushw(void) |
2474 | 2474 |
{ |
2475 |
if (env->cansave != NWINDOWS - 2) {
|
|
2475 |
if (env->cansave != env->nwindows - 2) {
|
|
2476 | 2476 |
raise_exception(TT_SPILL | (env->otherwin != 0 ? |
2477 | 2477 |
(TT_WOTHER | ((env->wstate & 0x38) >> 1)): |
2478 | 2478 |
((env->wstate & 0x7) << 2))); |
... | ... | |
2491 | 2491 |
void helper_restored(void) |
2492 | 2492 |
{ |
2493 | 2493 |
env->canrestore++; |
2494 |
if (env->cleanwin < NWINDOWS - 1)
|
|
2494 |
if (env->cleanwin < env->nwindows - 1)
|
|
2495 | 2495 |
env->cleanwin++; |
2496 | 2496 |
if (env->otherwin == 0) |
2497 | 2497 |
env->cansave--; |
... | ... | |
2622 | 2622 |
void cpu_set_cwp(CPUState *env1, int new_cwp) |
2623 | 2623 |
{ |
2624 | 2624 |
/* put the modified wrap registers at their proper location */ |
2625 |
if (env1->cwp == (NWINDOWS - 1))
|
|
2626 |
memcpy32(env1->regbase, env1->regbase + NWINDOWS * 16);
|
|
2625 |
if (env1->cwp == env->nwindows - 1)
|
|
2626 |
memcpy32(env1->regbase, env1->regbase + env->nwindows * 16);
|
|
2627 | 2627 |
env1->cwp = new_cwp; |
2628 | 2628 |
/* put the wrap registers at their temporary location */ |
2629 |
if (new_cwp == (NWINDOWS - 1))
|
|
2630 |
memcpy32(env1->regbase + NWINDOWS * 16, env1->regbase);
|
|
2629 |
if (new_cwp == env->nwindows - 1)
|
|
2630 |
memcpy32(env1->regbase + env->nwindows * 16, env1->regbase);
|
|
2631 | 2631 |
env1->regwptr = env1->regbase + (new_cwp * 16); |
2632 | 2632 |
} |
2633 | 2633 |
|
b/target-sparc/translate.c | ||
---|---|---|
3442 | 3442 |
goto illegal_insn; |
3443 | 3443 |
} |
3444 | 3444 |
#else |
3445 |
tcg_gen_andi_tl(cpu_dst, cpu_dst, |
|
3446 |
((1 << NWINDOWS) - 1)); |
|
3447 | 3445 |
tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); |
3448 | 3446 |
tcg_gen_st_i32(cpu_tmp32, cpu_env, |
3449 | 3447 |
offsetof(CPUSPARCState, wim)); |
Also available in: Unified diff