1ab3b491fSBlue Swirl /* 2ab3b491fSBlue Swirl * Sparc CPU init helpers 3ab3b491fSBlue Swirl * 4ab3b491fSBlue Swirl * Copyright (c) 2003-2005 Fabrice Bellard 5ab3b491fSBlue Swirl * 6ab3b491fSBlue Swirl * This library is free software; you can redistribute it and/or 7ab3b491fSBlue Swirl * modify it under the terms of the GNU Lesser General Public 8ab3b491fSBlue Swirl * License as published by the Free Software Foundation; either 9ab3b491fSBlue Swirl * version 2 of the License, or (at your option) any later version. 10ab3b491fSBlue Swirl * 11ab3b491fSBlue Swirl * This library is distributed in the hope that it will be useful, 12ab3b491fSBlue Swirl * but WITHOUT ANY WARRANTY; without even the implied warranty of 13ab3b491fSBlue Swirl * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14ab3b491fSBlue Swirl * Lesser General Public License for more details. 15ab3b491fSBlue Swirl * 16ab3b491fSBlue Swirl * You should have received a copy of the GNU Lesser General Public 17ab3b491fSBlue Swirl * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18ab3b491fSBlue Swirl */ 19ab3b491fSBlue Swirl 20db5ebe5fSPeter Maydell #include "qemu/osdep.h" 21da34e65cSMarkus Armbruster #include "qapi/error.h" 22ab3b491fSBlue Swirl #include "cpu.h" 23db5d39f7SAndreas Färber #include "qemu/error-report.h" 2463c91552SPaolo Bonzini #include "exec/exec-all.h" 25de05005bSIgor Mammedov #include "hw/qdev-properties.h" 26de05005bSIgor Mammedov #include "qapi/visitor.h" 27ab3b491fSBlue Swirl 28ab3b491fSBlue Swirl //#define DEBUG_FEATURES 29ab3b491fSBlue Swirl 30ab7ab3d7SAndreas Färber /* CPUClass::reset() */ 31ab7ab3d7SAndreas Färber static void sparc_cpu_reset(CPUState *s) 32ab7ab3d7SAndreas Färber { 33ab7ab3d7SAndreas Färber SPARCCPU *cpu = SPARC_CPU(s); 34ab7ab3d7SAndreas Färber SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(cpu); 35ab7ab3d7SAndreas Färber CPUSPARCState *env = &cpu->env; 36ab7ab3d7SAndreas Färber 37ab7ab3d7SAndreas Färber scc->parent_reset(s); 38ab7ab3d7SAndreas Färber 391f5c00cfSAlex Bennée memset(env, 0, offsetof(CPUSPARCState, end_reset_fields)); 40ab3b491fSBlue Swirl env->cwp = 0; 41ab3b491fSBlue Swirl #ifndef TARGET_SPARC64 42ab3b491fSBlue Swirl env->wim = 1; 43ab3b491fSBlue Swirl #endif 44ab3b491fSBlue Swirl env->regwptr = env->regbase + (env->cwp * 16); 45ab3b491fSBlue Swirl CC_OP = CC_OP_FLAGS; 46ab3b491fSBlue Swirl #if defined(CONFIG_USER_ONLY) 47ab3b491fSBlue Swirl #ifdef TARGET_SPARC64 48ab3b491fSBlue Swirl env->cleanwin = env->nwindows - 2; 49ab3b491fSBlue Swirl env->cansave = env->nwindows - 2; 50ab3b491fSBlue Swirl env->pstate = PS_RMO | PS_PEF | PS_IE; 51ab3b491fSBlue Swirl env->asi = 0x82; /* Primary no-fault */ 52ab3b491fSBlue Swirl #endif 53ab3b491fSBlue Swirl #else 54ab3b491fSBlue Swirl #if !defined(TARGET_SPARC64) 55ab3b491fSBlue Swirl env->psret = 0; 56ab3b491fSBlue Swirl env->psrs = 1; 57ab3b491fSBlue Swirl env->psrps = 1; 58ab3b491fSBlue Swirl #endif 59ab3b491fSBlue Swirl #ifdef TARGET_SPARC64 60cbc3a6a4SArtyom Tarasenko env->pstate = PS_PRIV | PS_RED | PS_PEF; 61cbc3a6a4SArtyom Tarasenko if (!cpu_has_hypervisor(env)) { 62cbc3a6a4SArtyom Tarasenko env->pstate |= PS_AG; 63cbc3a6a4SArtyom Tarasenko } 64ab3b491fSBlue Swirl env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0; 65ab3b491fSBlue Swirl env->tl = env->maxtl; 66cbc3a6a4SArtyom Tarasenko env->gl = 2; 67ab3b491fSBlue Swirl cpu_tsptr(env)->tt = TT_POWER_ON_RESET; 68ab3b491fSBlue Swirl env->lsu = 0; 69ab3b491fSBlue Swirl #else 70ab3b491fSBlue Swirl env->mmuregs[0] &= ~(MMU_E | MMU_NF); 71576e1c4cSIgor Mammedov env->mmuregs[0] |= env->def.mmu_bm; 72ab3b491fSBlue Swirl #endif 73ab3b491fSBlue Swirl env->pc = 0; 74ab3b491fSBlue Swirl env->npc = env->pc + 4; 75ab3b491fSBlue Swirl #endif 76ab3b491fSBlue Swirl env->cache_control = 0; 77ab3b491fSBlue Swirl } 78ab3b491fSBlue Swirl 7987afe467SRichard Henderson static bool sparc_cpu_exec_interrupt(CPUState *cs, int interrupt_request) 8087afe467SRichard Henderson { 8187afe467SRichard Henderson if (interrupt_request & CPU_INTERRUPT_HARD) { 8287afe467SRichard Henderson SPARCCPU *cpu = SPARC_CPU(cs); 8387afe467SRichard Henderson CPUSPARCState *env = &cpu->env; 8487afe467SRichard Henderson 8587afe467SRichard Henderson if (cpu_interrupts_enabled(env) && env->interrupt_index > 0) { 8687afe467SRichard Henderson int pil = env->interrupt_index & 0xf; 8787afe467SRichard Henderson int type = env->interrupt_index & 0xf0; 8887afe467SRichard Henderson 8987afe467SRichard Henderson if (type != TT_EXTINT || cpu_pil_allowed(env, pil)) { 9087afe467SRichard Henderson cs->exception_index = env->interrupt_index; 9187afe467SRichard Henderson sparc_cpu_do_interrupt(cs); 9287afe467SRichard Henderson return true; 9387afe467SRichard Henderson } 9487afe467SRichard Henderson } 9587afe467SRichard Henderson } 9687afe467SRichard Henderson return false; 9787afe467SRichard Henderson } 9887afe467SRichard Henderson 99df0900ebSPeter Crosthwaite static void cpu_sparc_disas_set_info(CPUState *cpu, disassemble_info *info) 100df0900ebSPeter Crosthwaite { 101df0900ebSPeter Crosthwaite info->print_insn = print_insn_sparc; 102df0900ebSPeter Crosthwaite #ifdef TARGET_SPARC64 103df0900ebSPeter Crosthwaite info->mach = bfd_mach_sparc_v9b; 104df0900ebSPeter Crosthwaite #endif 105df0900ebSPeter Crosthwaite } 106df0900ebSPeter Crosthwaite 107*d1853231SIgor Mammedov static void 108*d1853231SIgor Mammedov cpu_add_feat_as_prop(const char *typename, const char *name, const char *val) 109ab3b491fSBlue Swirl { 110*d1853231SIgor Mammedov GlobalProperty *prop = g_new0(typeof(*prop), 1); 111*d1853231SIgor Mammedov prop->driver = typename; 112*d1853231SIgor Mammedov prop->property = g_strdup(name); 113*d1853231SIgor Mammedov prop->value = g_strdup(val); 114*d1853231SIgor Mammedov prop->errp = &error_fatal; 115*d1853231SIgor Mammedov qdev_prop_register_global(prop); 116433ac7a9SAndreas Färber } 117433ac7a9SAndreas Färber 118*d1853231SIgor Mammedov /* Parse "+feature,-feature,feature=foo" CPU feature string */ 119*d1853231SIgor Mammedov static void sparc_cpu_parse_features(const char *typename, char *features, 120*d1853231SIgor Mammedov Error **errp) 121*d1853231SIgor Mammedov { 122*d1853231SIgor Mammedov GList *l, *plus_features = NULL, *minus_features = NULL; 123*d1853231SIgor Mammedov char *featurestr; /* Single 'key=value" string being parsed */ 124*d1853231SIgor Mammedov static bool cpu_globals_initialized; 125*d1853231SIgor Mammedov 126*d1853231SIgor Mammedov if (cpu_globals_initialized) { 127*d1853231SIgor Mammedov return; 128*d1853231SIgor Mammedov } 129*d1853231SIgor Mammedov cpu_globals_initialized = true; 130*d1853231SIgor Mammedov 131*d1853231SIgor Mammedov if (!features) { 132*d1853231SIgor Mammedov return; 133*d1853231SIgor Mammedov } 134*d1853231SIgor Mammedov 135*d1853231SIgor Mammedov for (featurestr = strtok(features, ","); 136*d1853231SIgor Mammedov featurestr; 137*d1853231SIgor Mammedov featurestr = strtok(NULL, ",")) { 138*d1853231SIgor Mammedov const char *name; 139*d1853231SIgor Mammedov const char *val = NULL; 140*d1853231SIgor Mammedov char *eq = NULL; 141*d1853231SIgor Mammedov 142*d1853231SIgor Mammedov /* Compatibility syntax: */ 143*d1853231SIgor Mammedov if (featurestr[0] == '+') { 144*d1853231SIgor Mammedov plus_features = g_list_append(plus_features, 145*d1853231SIgor Mammedov g_strdup(featurestr + 1)); 146*d1853231SIgor Mammedov continue; 147*d1853231SIgor Mammedov } else if (featurestr[0] == '-') { 148*d1853231SIgor Mammedov minus_features = g_list_append(minus_features, 149*d1853231SIgor Mammedov g_strdup(featurestr + 1)); 150*d1853231SIgor Mammedov continue; 151*d1853231SIgor Mammedov } 152*d1853231SIgor Mammedov 153*d1853231SIgor Mammedov eq = strchr(featurestr, '='); 154*d1853231SIgor Mammedov name = featurestr; 155*d1853231SIgor Mammedov if (eq) { 156*d1853231SIgor Mammedov *eq++ = 0; 157*d1853231SIgor Mammedov val = eq; 158*d1853231SIgor Mammedov 159*d1853231SIgor Mammedov /* 160*d1853231SIgor Mammedov * Temporarily, only +feat/-feat will be supported 161*d1853231SIgor Mammedov * for boolean properties until we remove the 162*d1853231SIgor Mammedov * minus-overrides-plus semantics and just follow 163*d1853231SIgor Mammedov * the order options appear on the command-line. 164*d1853231SIgor Mammedov * 165*d1853231SIgor Mammedov * TODO: warn if user is relying on minus-override-plus semantics 166*d1853231SIgor Mammedov * TODO: remove minus-override-plus semantics after 167*d1853231SIgor Mammedov * warning for a few releases 168*d1853231SIgor Mammedov */ 169*d1853231SIgor Mammedov if (!strcasecmp(val, "on") || 170*d1853231SIgor Mammedov !strcasecmp(val, "off") || 171*d1853231SIgor Mammedov !strcasecmp(val, "true") || 172*d1853231SIgor Mammedov !strcasecmp(val, "false")) { 173*d1853231SIgor Mammedov error_setg(errp, "Boolean properties in format %s=%s" 174*d1853231SIgor Mammedov " are not supported", name, val); 175*d1853231SIgor Mammedov return; 176*d1853231SIgor Mammedov } 177*d1853231SIgor Mammedov } else { 178*d1853231SIgor Mammedov error_setg(errp, "Unsupported property format: %s", name); 179*d1853231SIgor Mammedov return; 180*d1853231SIgor Mammedov } 181*d1853231SIgor Mammedov cpu_add_feat_as_prop(typename, name, val); 182*d1853231SIgor Mammedov } 183*d1853231SIgor Mammedov 184*d1853231SIgor Mammedov for (l = plus_features; l; l = l->next) { 185*d1853231SIgor Mammedov const char *name = l->data; 186*d1853231SIgor Mammedov cpu_add_feat_as_prop(typename, name, "on"); 187*d1853231SIgor Mammedov } 188*d1853231SIgor Mammedov g_list_free_full(plus_features, g_free); 189*d1853231SIgor Mammedov 190*d1853231SIgor Mammedov for (l = minus_features; l; l = l->next) { 191*d1853231SIgor Mammedov const char *name = l->data; 192*d1853231SIgor Mammedov cpu_add_feat_as_prop(typename, name, "off"); 193*d1853231SIgor Mammedov } 194*d1853231SIgor Mammedov g_list_free_full(minus_features, g_free); 195ab3b491fSBlue Swirl } 196ab3b491fSBlue Swirl 197e59be77aSAndreas Färber SPARCCPU *cpu_sparc_init(const char *cpu_model) 198ab3b491fSBlue Swirl { 199*d1853231SIgor Mammedov return SPARC_CPU(cpu_generic_init(TYPE_SPARC_CPU, cpu_model)); 200ab3b491fSBlue Swirl } 201ab3b491fSBlue Swirl 202ab3b491fSBlue Swirl void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu) 203ab3b491fSBlue Swirl { 204ab3b491fSBlue Swirl #if !defined(TARGET_SPARC64) 205ab3b491fSBlue Swirl env->mxccregs[7] = ((cpu + 8) & 0xf) << 24; 206ab3b491fSBlue Swirl #endif 207ab3b491fSBlue Swirl } 208ab3b491fSBlue Swirl 209ab3b491fSBlue Swirl static const sparc_def_t sparc_defs[] = { 210ab3b491fSBlue Swirl #ifdef TARGET_SPARC64 211ab3b491fSBlue Swirl { 212ab3b491fSBlue Swirl .name = "Fujitsu Sparc64", 213ab3b491fSBlue Swirl .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)), 214ab3b491fSBlue Swirl .fpu_version = 0x00000000, 215ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 216ab3b491fSBlue Swirl .nwindows = 4, 217ab3b491fSBlue Swirl .maxtl = 4, 218ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 219ab3b491fSBlue Swirl }, 220ab3b491fSBlue Swirl { 221ab3b491fSBlue Swirl .name = "Fujitsu Sparc64 III", 222ab3b491fSBlue Swirl .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)), 223ab3b491fSBlue Swirl .fpu_version = 0x00000000, 224ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 225ab3b491fSBlue Swirl .nwindows = 5, 226ab3b491fSBlue Swirl .maxtl = 4, 227ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 228ab3b491fSBlue Swirl }, 229ab3b491fSBlue Swirl { 230ab3b491fSBlue Swirl .name = "Fujitsu Sparc64 IV", 231ab3b491fSBlue Swirl .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)), 232ab3b491fSBlue Swirl .fpu_version = 0x00000000, 233ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 234ab3b491fSBlue Swirl .nwindows = 8, 235ab3b491fSBlue Swirl .maxtl = 5, 236ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 237ab3b491fSBlue Swirl }, 238ab3b491fSBlue Swirl { 239ab3b491fSBlue Swirl .name = "Fujitsu Sparc64 V", 240ab3b491fSBlue Swirl .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)), 241ab3b491fSBlue Swirl .fpu_version = 0x00000000, 242ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 243ab3b491fSBlue Swirl .nwindows = 8, 244ab3b491fSBlue Swirl .maxtl = 5, 245ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 246ab3b491fSBlue Swirl }, 247ab3b491fSBlue Swirl { 248ab3b491fSBlue Swirl .name = "TI UltraSparc I", 249ab3b491fSBlue Swirl .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)), 250ab3b491fSBlue Swirl .fpu_version = 0x00000000, 251ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 252ab3b491fSBlue Swirl .nwindows = 8, 253ab3b491fSBlue Swirl .maxtl = 5, 254ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 255ab3b491fSBlue Swirl }, 256ab3b491fSBlue Swirl { 257ab3b491fSBlue Swirl .name = "TI UltraSparc II", 258ab3b491fSBlue Swirl .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)), 259ab3b491fSBlue Swirl .fpu_version = 0x00000000, 260ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 261ab3b491fSBlue Swirl .nwindows = 8, 262ab3b491fSBlue Swirl .maxtl = 5, 263ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 264ab3b491fSBlue Swirl }, 265ab3b491fSBlue Swirl { 266ab3b491fSBlue Swirl .name = "TI UltraSparc IIi", 267ab3b491fSBlue Swirl .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)), 268ab3b491fSBlue Swirl .fpu_version = 0x00000000, 269ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 270ab3b491fSBlue Swirl .nwindows = 8, 271ab3b491fSBlue Swirl .maxtl = 5, 272ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 273ab3b491fSBlue Swirl }, 274ab3b491fSBlue Swirl { 275ab3b491fSBlue Swirl .name = "TI UltraSparc IIe", 276ab3b491fSBlue Swirl .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)), 277ab3b491fSBlue Swirl .fpu_version = 0x00000000, 278ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 279ab3b491fSBlue Swirl .nwindows = 8, 280ab3b491fSBlue Swirl .maxtl = 5, 281ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 282ab3b491fSBlue Swirl }, 283ab3b491fSBlue Swirl { 284ab3b491fSBlue Swirl .name = "Sun UltraSparc III", 285ab3b491fSBlue Swirl .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)), 286ab3b491fSBlue Swirl .fpu_version = 0x00000000, 287ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 288ab3b491fSBlue Swirl .nwindows = 8, 289ab3b491fSBlue Swirl .maxtl = 5, 290ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 291ab3b491fSBlue Swirl }, 292ab3b491fSBlue Swirl { 293ab3b491fSBlue Swirl .name = "Sun UltraSparc III Cu", 294ab3b491fSBlue Swirl .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)), 295ab3b491fSBlue Swirl .fpu_version = 0x00000000, 296ab3b491fSBlue Swirl .mmu_version = mmu_us_3, 297ab3b491fSBlue Swirl .nwindows = 8, 298ab3b491fSBlue Swirl .maxtl = 5, 299ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 300ab3b491fSBlue Swirl }, 301ab3b491fSBlue Swirl { 302ab3b491fSBlue Swirl .name = "Sun UltraSparc IIIi", 303ab3b491fSBlue Swirl .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)), 304ab3b491fSBlue Swirl .fpu_version = 0x00000000, 305ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 306ab3b491fSBlue Swirl .nwindows = 8, 307ab3b491fSBlue Swirl .maxtl = 5, 308ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 309ab3b491fSBlue Swirl }, 310ab3b491fSBlue Swirl { 311ab3b491fSBlue Swirl .name = "Sun UltraSparc IV", 312ab3b491fSBlue Swirl .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)), 313ab3b491fSBlue Swirl .fpu_version = 0x00000000, 314ab3b491fSBlue Swirl .mmu_version = mmu_us_4, 315ab3b491fSBlue Swirl .nwindows = 8, 316ab3b491fSBlue Swirl .maxtl = 5, 317ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 318ab3b491fSBlue Swirl }, 319ab3b491fSBlue Swirl { 320ab3b491fSBlue Swirl .name = "Sun UltraSparc IV+", 321ab3b491fSBlue Swirl .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)), 322ab3b491fSBlue Swirl .fpu_version = 0x00000000, 323ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 324ab3b491fSBlue Swirl .nwindows = 8, 325ab3b491fSBlue Swirl .maxtl = 5, 326ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT, 327ab3b491fSBlue Swirl }, 328ab3b491fSBlue Swirl { 329ab3b491fSBlue Swirl .name = "Sun UltraSparc IIIi+", 330ab3b491fSBlue Swirl .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)), 331ab3b491fSBlue Swirl .fpu_version = 0x00000000, 332ab3b491fSBlue Swirl .mmu_version = mmu_us_3, 333ab3b491fSBlue Swirl .nwindows = 8, 334ab3b491fSBlue Swirl .maxtl = 5, 335ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 336ab3b491fSBlue Swirl }, 337ab3b491fSBlue Swirl { 338ab3b491fSBlue Swirl .name = "Sun UltraSparc T1", 339ab3b491fSBlue Swirl /* defined in sparc_ifu_fdp.v and ctu.h */ 340ab3b491fSBlue Swirl .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)), 341ab3b491fSBlue Swirl .fpu_version = 0x00000000, 342ab3b491fSBlue Swirl .mmu_version = mmu_sun4v, 343ab3b491fSBlue Swirl .nwindows = 8, 344ab3b491fSBlue Swirl .maxtl = 6, 345ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT 346ab3b491fSBlue Swirl | CPU_FEATURE_GL, 347ab3b491fSBlue Swirl }, 348ab3b491fSBlue Swirl { 349ab3b491fSBlue Swirl .name = "Sun UltraSparc T2", 350ab3b491fSBlue Swirl /* defined in tlu_asi_ctl.v and n2_revid_cust.v */ 351ab3b491fSBlue Swirl .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)), 352ab3b491fSBlue Swirl .fpu_version = 0x00000000, 353ab3b491fSBlue Swirl .mmu_version = mmu_sun4v, 354ab3b491fSBlue Swirl .nwindows = 8, 355ab3b491fSBlue Swirl .maxtl = 6, 356ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT 357ab3b491fSBlue Swirl | CPU_FEATURE_GL, 358ab3b491fSBlue Swirl }, 359ab3b491fSBlue Swirl { 360ab3b491fSBlue Swirl .name = "NEC UltraSparc I", 361ab3b491fSBlue Swirl .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)), 362ab3b491fSBlue Swirl .fpu_version = 0x00000000, 363ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 364ab3b491fSBlue Swirl .nwindows = 8, 365ab3b491fSBlue Swirl .maxtl = 5, 366ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 367ab3b491fSBlue Swirl }, 368ab3b491fSBlue Swirl #else 369ab3b491fSBlue Swirl { 370ab3b491fSBlue Swirl .name = "Fujitsu MB86904", 371ab3b491fSBlue Swirl .iu_version = 0x04 << 24, /* Impl 0, ver 4 */ 372ab3b491fSBlue Swirl .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ 373ab3b491fSBlue Swirl .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */ 374ab3b491fSBlue Swirl .mmu_bm = 0x00004000, 375ab3b491fSBlue Swirl .mmu_ctpr_mask = 0x00ffffc0, 376ab3b491fSBlue Swirl .mmu_cxr_mask = 0x000000ff, 377ab3b491fSBlue Swirl .mmu_sfsr_mask = 0x00016fff, 378ab3b491fSBlue Swirl .mmu_trcr_mask = 0x00ffffff, 379ab3b491fSBlue Swirl .nwindows = 8, 380ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 381ab3b491fSBlue Swirl }, 382ab3b491fSBlue Swirl { 383ab3b491fSBlue Swirl .name = "Fujitsu MB86907", 384ab3b491fSBlue Swirl .iu_version = 0x05 << 24, /* Impl 0, ver 5 */ 385ab3b491fSBlue Swirl .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ 386ab3b491fSBlue Swirl .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */ 387ab3b491fSBlue Swirl .mmu_bm = 0x00004000, 388ab3b491fSBlue Swirl .mmu_ctpr_mask = 0xffffffc0, 389ab3b491fSBlue Swirl .mmu_cxr_mask = 0x000000ff, 390ab3b491fSBlue Swirl .mmu_sfsr_mask = 0x00016fff, 391ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 392ab3b491fSBlue Swirl .nwindows = 8, 393ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 394ab3b491fSBlue Swirl }, 395ab3b491fSBlue Swirl { 396ab3b491fSBlue Swirl .name = "TI MicroSparc I", 397ab3b491fSBlue Swirl .iu_version = 0x41000000, 398ab3b491fSBlue Swirl .fpu_version = 4 << 17, 399ab3b491fSBlue Swirl .mmu_version = 0x41000000, 400ab3b491fSBlue Swirl .mmu_bm = 0x00004000, 401ab3b491fSBlue Swirl .mmu_ctpr_mask = 0x007ffff0, 402ab3b491fSBlue Swirl .mmu_cxr_mask = 0x0000003f, 403ab3b491fSBlue Swirl .mmu_sfsr_mask = 0x00016fff, 404ab3b491fSBlue Swirl .mmu_trcr_mask = 0x0000003f, 405ab3b491fSBlue Swirl .nwindows = 7, 406ab3b491fSBlue Swirl .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL | 407ab3b491fSBlue Swirl CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | 408ab3b491fSBlue Swirl CPU_FEATURE_FMUL, 409ab3b491fSBlue Swirl }, 410ab3b491fSBlue Swirl { 411ab3b491fSBlue Swirl .name = "TI MicroSparc II", 412ab3b491fSBlue Swirl .iu_version = 0x42000000, 413ab3b491fSBlue Swirl .fpu_version = 4 << 17, 414ab3b491fSBlue Swirl .mmu_version = 0x02000000, 415ab3b491fSBlue Swirl .mmu_bm = 0x00004000, 416ab3b491fSBlue Swirl .mmu_ctpr_mask = 0x00ffffc0, 417ab3b491fSBlue Swirl .mmu_cxr_mask = 0x000000ff, 418ab3b491fSBlue Swirl .mmu_sfsr_mask = 0x00016fff, 419ab3b491fSBlue Swirl .mmu_trcr_mask = 0x00ffffff, 420ab3b491fSBlue Swirl .nwindows = 8, 421ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 422ab3b491fSBlue Swirl }, 423ab3b491fSBlue Swirl { 424ab3b491fSBlue Swirl .name = "TI MicroSparc IIep", 425ab3b491fSBlue Swirl .iu_version = 0x42000000, 426ab3b491fSBlue Swirl .fpu_version = 4 << 17, 427ab3b491fSBlue Swirl .mmu_version = 0x04000000, 428ab3b491fSBlue Swirl .mmu_bm = 0x00004000, 429ab3b491fSBlue Swirl .mmu_ctpr_mask = 0x00ffffc0, 430ab3b491fSBlue Swirl .mmu_cxr_mask = 0x000000ff, 431ab3b491fSBlue Swirl .mmu_sfsr_mask = 0x00016bff, 432ab3b491fSBlue Swirl .mmu_trcr_mask = 0x00ffffff, 433ab3b491fSBlue Swirl .nwindows = 8, 434ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 435ab3b491fSBlue Swirl }, 436ab3b491fSBlue Swirl { 437ab3b491fSBlue Swirl .name = "TI SuperSparc 40", /* STP1020NPGA */ 438ab3b491fSBlue Swirl .iu_version = 0x41000000, /* SuperSPARC 2.x */ 439ab3b491fSBlue Swirl .fpu_version = 0 << 17, 440ab3b491fSBlue Swirl .mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */ 441ab3b491fSBlue Swirl .mmu_bm = 0x00002000, 442ab3b491fSBlue Swirl .mmu_ctpr_mask = 0xffffffc0, 443ab3b491fSBlue Swirl .mmu_cxr_mask = 0x0000ffff, 444ab3b491fSBlue Swirl .mmu_sfsr_mask = 0xffffffff, 445ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 446ab3b491fSBlue Swirl .nwindows = 8, 447ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 448ab3b491fSBlue Swirl }, 449ab3b491fSBlue Swirl { 450ab3b491fSBlue Swirl .name = "TI SuperSparc 50", /* STP1020PGA */ 451ab3b491fSBlue Swirl .iu_version = 0x40000000, /* SuperSPARC 3.x */ 452ab3b491fSBlue Swirl .fpu_version = 0 << 17, 453ab3b491fSBlue Swirl .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */ 454ab3b491fSBlue Swirl .mmu_bm = 0x00002000, 455ab3b491fSBlue Swirl .mmu_ctpr_mask = 0xffffffc0, 456ab3b491fSBlue Swirl .mmu_cxr_mask = 0x0000ffff, 457ab3b491fSBlue Swirl .mmu_sfsr_mask = 0xffffffff, 458ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 459ab3b491fSBlue Swirl .nwindows = 8, 460ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 461ab3b491fSBlue Swirl }, 462ab3b491fSBlue Swirl { 463ab3b491fSBlue Swirl .name = "TI SuperSparc 51", 464ab3b491fSBlue Swirl .iu_version = 0x40000000, /* SuperSPARC 3.x */ 465ab3b491fSBlue Swirl .fpu_version = 0 << 17, 466ab3b491fSBlue Swirl .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */ 467ab3b491fSBlue Swirl .mmu_bm = 0x00002000, 468ab3b491fSBlue Swirl .mmu_ctpr_mask = 0xffffffc0, 469ab3b491fSBlue Swirl .mmu_cxr_mask = 0x0000ffff, 470ab3b491fSBlue Swirl .mmu_sfsr_mask = 0xffffffff, 471ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 472ab3b491fSBlue Swirl .mxcc_version = 0x00000104, 473ab3b491fSBlue Swirl .nwindows = 8, 474ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 475ab3b491fSBlue Swirl }, 476ab3b491fSBlue Swirl { 477ab3b491fSBlue Swirl .name = "TI SuperSparc 60", /* STP1020APGA */ 478ab3b491fSBlue Swirl .iu_version = 0x40000000, /* SuperSPARC 3.x */ 479ab3b491fSBlue Swirl .fpu_version = 0 << 17, 480ab3b491fSBlue Swirl .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */ 481ab3b491fSBlue Swirl .mmu_bm = 0x00002000, 482ab3b491fSBlue Swirl .mmu_ctpr_mask = 0xffffffc0, 483ab3b491fSBlue Swirl .mmu_cxr_mask = 0x0000ffff, 484ab3b491fSBlue Swirl .mmu_sfsr_mask = 0xffffffff, 485ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 486ab3b491fSBlue Swirl .nwindows = 8, 487ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 488ab3b491fSBlue Swirl }, 489ab3b491fSBlue Swirl { 490ab3b491fSBlue Swirl .name = "TI SuperSparc 61", 491ab3b491fSBlue Swirl .iu_version = 0x44000000, /* SuperSPARC 3.x */ 492ab3b491fSBlue Swirl .fpu_version = 0 << 17, 493ab3b491fSBlue Swirl .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */ 494ab3b491fSBlue Swirl .mmu_bm = 0x00002000, 495ab3b491fSBlue Swirl .mmu_ctpr_mask = 0xffffffc0, 496ab3b491fSBlue Swirl .mmu_cxr_mask = 0x0000ffff, 497ab3b491fSBlue Swirl .mmu_sfsr_mask = 0xffffffff, 498ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 499ab3b491fSBlue Swirl .mxcc_version = 0x00000104, 500ab3b491fSBlue Swirl .nwindows = 8, 501ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 502ab3b491fSBlue Swirl }, 503ab3b491fSBlue Swirl { 504ab3b491fSBlue Swirl .name = "TI SuperSparc II", 505ab3b491fSBlue Swirl .iu_version = 0x40000000, /* SuperSPARC II 1.x */ 506ab3b491fSBlue Swirl .fpu_version = 0 << 17, 507ab3b491fSBlue Swirl .mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */ 508ab3b491fSBlue Swirl .mmu_bm = 0x00002000, 509ab3b491fSBlue Swirl .mmu_ctpr_mask = 0xffffffc0, 510ab3b491fSBlue Swirl .mmu_cxr_mask = 0x0000ffff, 511ab3b491fSBlue Swirl .mmu_sfsr_mask = 0xffffffff, 512ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 513ab3b491fSBlue Swirl .mxcc_version = 0x00000104, 514ab3b491fSBlue Swirl .nwindows = 8, 515ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 516ab3b491fSBlue Swirl }, 517ab3b491fSBlue Swirl { 518ab3b491fSBlue Swirl .name = "LEON2", 519ab3b491fSBlue Swirl .iu_version = 0xf2000000, 520ab3b491fSBlue Swirl .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ 521ab3b491fSBlue Swirl .mmu_version = 0xf2000000, 522ab3b491fSBlue Swirl .mmu_bm = 0x00004000, 523ab3b491fSBlue Swirl .mmu_ctpr_mask = 0x007ffff0, 524ab3b491fSBlue Swirl .mmu_cxr_mask = 0x0000003f, 525ab3b491fSBlue Swirl .mmu_sfsr_mask = 0xffffffff, 526ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 527ab3b491fSBlue Swirl .nwindows = 8, 528ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN, 529ab3b491fSBlue Swirl }, 530ab3b491fSBlue Swirl { 531ab3b491fSBlue Swirl .name = "LEON3", 532ab3b491fSBlue Swirl .iu_version = 0xf3000000, 533ab3b491fSBlue Swirl .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ 534ab3b491fSBlue Swirl .mmu_version = 0xf3000000, 535ab3b491fSBlue Swirl .mmu_bm = 0x00000000, 5367a0a9c2cSRonald Hecht .mmu_ctpr_mask = 0xfffffffc, 5377a0a9c2cSRonald Hecht .mmu_cxr_mask = 0x000000ff, 538ab3b491fSBlue Swirl .mmu_sfsr_mask = 0xffffffff, 539ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 540ab3b491fSBlue Swirl .nwindows = 8, 541ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN | 54216c358e9SSebastian Huber CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL | CPU_FEATURE_POWERDOWN | 54316c358e9SSebastian Huber CPU_FEATURE_CASA, 544ab3b491fSBlue Swirl }, 545ab3b491fSBlue Swirl #endif 546ab3b491fSBlue Swirl }; 547ab3b491fSBlue Swirl 548ab3b491fSBlue Swirl static const char * const feature_name[] = { 549ab3b491fSBlue Swirl "float", 550ab3b491fSBlue Swirl "float128", 551ab3b491fSBlue Swirl "swap", 552ab3b491fSBlue Swirl "mul", 553ab3b491fSBlue Swirl "div", 554ab3b491fSBlue Swirl "flush", 555ab3b491fSBlue Swirl "fsqrt", 556ab3b491fSBlue Swirl "fmul", 557ab3b491fSBlue Swirl "vis1", 558ab3b491fSBlue Swirl "vis2", 559ab3b491fSBlue Swirl "fsmuld", 560ab3b491fSBlue Swirl "hypv", 561ab3b491fSBlue Swirl "cmt", 562ab3b491fSBlue Swirl "gl", 563ab3b491fSBlue Swirl }; 564ab3b491fSBlue Swirl 565ab3b491fSBlue Swirl static void print_features(FILE *f, fprintf_function cpu_fprintf, 566ab3b491fSBlue Swirl uint32_t features, const char *prefix) 567ab3b491fSBlue Swirl { 568ab3b491fSBlue Swirl unsigned int i; 569ab3b491fSBlue Swirl 570ab3b491fSBlue Swirl for (i = 0; i < ARRAY_SIZE(feature_name); i++) { 571ab3b491fSBlue Swirl if (feature_name[i] && (features & (1 << i))) { 572ab3b491fSBlue Swirl if (prefix) { 573ab3b491fSBlue Swirl (*cpu_fprintf)(f, "%s", prefix); 574ab3b491fSBlue Swirl } 575ab3b491fSBlue Swirl (*cpu_fprintf)(f, "%s ", feature_name[i]); 576ab3b491fSBlue Swirl } 577ab3b491fSBlue Swirl } 578ab3b491fSBlue Swirl } 579ab3b491fSBlue Swirl 580ab3b491fSBlue Swirl void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf) 581ab3b491fSBlue Swirl { 582ab3b491fSBlue Swirl unsigned int i; 583ab3b491fSBlue Swirl 584ab3b491fSBlue Swirl for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) { 585ab3b491fSBlue Swirl (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx 586ab3b491fSBlue Swirl " FPU %08x MMU %08x NWINS %d ", 587ab3b491fSBlue Swirl sparc_defs[i].name, 588ab3b491fSBlue Swirl sparc_defs[i].iu_version, 589ab3b491fSBlue Swirl sparc_defs[i].fpu_version, 590ab3b491fSBlue Swirl sparc_defs[i].mmu_version, 591ab3b491fSBlue Swirl sparc_defs[i].nwindows); 592ab3b491fSBlue Swirl print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES & 593ab3b491fSBlue Swirl ~sparc_defs[i].features, "-"); 594ab3b491fSBlue Swirl print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES & 595ab3b491fSBlue Swirl sparc_defs[i].features, "+"); 596ab3b491fSBlue Swirl (*cpu_fprintf)(f, "\n"); 597ab3b491fSBlue Swirl } 598ab3b491fSBlue Swirl (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): "); 599ab3b491fSBlue Swirl print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL); 600ab3b491fSBlue Swirl (*cpu_fprintf)(f, "\n"); 601ab3b491fSBlue Swirl (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): "); 602ab3b491fSBlue Swirl print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL); 603ab3b491fSBlue Swirl (*cpu_fprintf)(f, "\n"); 604ab3b491fSBlue Swirl (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version " 605ab3b491fSBlue Swirl "fpu_version mmu_version nwindows\n"); 606ab3b491fSBlue Swirl } 607ab3b491fSBlue Swirl 608ab3b491fSBlue Swirl static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf, 609ab3b491fSBlue Swirl uint32_t cc) 610ab3b491fSBlue Swirl { 611ab3b491fSBlue Swirl cpu_fprintf(f, "%c%c%c%c", cc & PSR_NEG ? 'N' : '-', 612ab3b491fSBlue Swirl cc & PSR_ZERO ? 'Z' : '-', cc & PSR_OVF ? 'V' : '-', 613ab3b491fSBlue Swirl cc & PSR_CARRY ? 'C' : '-'); 614ab3b491fSBlue Swirl } 615ab3b491fSBlue Swirl 616ab3b491fSBlue Swirl #ifdef TARGET_SPARC64 617ab3b491fSBlue Swirl #define REGS_PER_LINE 4 618ab3b491fSBlue Swirl #else 619ab3b491fSBlue Swirl #define REGS_PER_LINE 8 620ab3b491fSBlue Swirl #endif 621ab3b491fSBlue Swirl 622878096eeSAndreas Färber void sparc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, 623ab3b491fSBlue Swirl int flags) 624ab3b491fSBlue Swirl { 625878096eeSAndreas Färber SPARCCPU *cpu = SPARC_CPU(cs); 626878096eeSAndreas Färber CPUSPARCState *env = &cpu->env; 627ab3b491fSBlue Swirl int i, x; 628ab3b491fSBlue Swirl 629ab3b491fSBlue Swirl cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc, 630ab3b491fSBlue Swirl env->npc); 631ab3b491fSBlue Swirl 632ab3b491fSBlue Swirl for (i = 0; i < 8; i++) { 633ab3b491fSBlue Swirl if (i % REGS_PER_LINE == 0) { 634ab3b491fSBlue Swirl cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1); 635ab3b491fSBlue Swirl } 636ab3b491fSBlue Swirl cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]); 637ab3b491fSBlue Swirl if (i % REGS_PER_LINE == REGS_PER_LINE - 1) { 638ab3b491fSBlue Swirl cpu_fprintf(f, "\n"); 639ab3b491fSBlue Swirl } 640ab3b491fSBlue Swirl } 641ab3b491fSBlue Swirl for (x = 0; x < 3; x++) { 642ab3b491fSBlue Swirl for (i = 0; i < 8; i++) { 643ab3b491fSBlue Swirl if (i % REGS_PER_LINE == 0) { 644ab3b491fSBlue Swirl cpu_fprintf(f, "%%%c%d-%d: ", 645ab3b491fSBlue Swirl x == 0 ? 'o' : (x == 1 ? 'l' : 'i'), 646ab3b491fSBlue Swirl i, i + REGS_PER_LINE - 1); 647ab3b491fSBlue Swirl } 648ab3b491fSBlue Swirl cpu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]); 649ab3b491fSBlue Swirl if (i % REGS_PER_LINE == REGS_PER_LINE - 1) { 650ab3b491fSBlue Swirl cpu_fprintf(f, "\n"); 651ab3b491fSBlue Swirl } 652ab3b491fSBlue Swirl } 653ab3b491fSBlue Swirl } 65476a23ca0SRichard Henderson 65530038fd8SRichard Henderson for (i = 0; i < TARGET_DPREGS; i++) { 656ab3b491fSBlue Swirl if ((i & 3) == 0) { 65730038fd8SRichard Henderson cpu_fprintf(f, "%%f%02d: ", i * 2); 658ab3b491fSBlue Swirl } 65930038fd8SRichard Henderson cpu_fprintf(f, " %016" PRIx64, env->fpr[i].ll); 660ab3b491fSBlue Swirl if ((i & 3) == 3) { 661ab3b491fSBlue Swirl cpu_fprintf(f, "\n"); 662ab3b491fSBlue Swirl } 663ab3b491fSBlue Swirl } 664ab3b491fSBlue Swirl #ifdef TARGET_SPARC64 665ab3b491fSBlue Swirl cpu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate, 666ab3b491fSBlue Swirl (unsigned)cpu_get_ccr(env)); 667ab3b491fSBlue Swirl cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT); 668ab3b491fSBlue Swirl cpu_fprintf(f, " xcc: "); 669ab3b491fSBlue Swirl cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4)); 670cbc3a6a4SArtyom Tarasenko cpu_fprintf(f, ") asi: %02x tl: %d pil: %x gl: %d\n", env->asi, env->tl, 671cbc3a6a4SArtyom Tarasenko env->psrpil, env->gl); 672cbc3a6a4SArtyom Tarasenko cpu_fprintf(f, "tbr: " TARGET_FMT_lx " hpstate: " TARGET_FMT_lx " htba: " 673cbc3a6a4SArtyom Tarasenko TARGET_FMT_lx "\n", env->tbr, env->hpstate, env->htba); 674ab3b491fSBlue Swirl cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d " 675ab3b491fSBlue Swirl "cleanwin: %d cwp: %d\n", 676ab3b491fSBlue Swirl env->cansave, env->canrestore, env->otherwin, env->wstate, 677ab3b491fSBlue Swirl env->cleanwin, env->nwindows - 1 - env->cwp); 678ab3b491fSBlue Swirl cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: " 679ab3b491fSBlue Swirl TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs); 680cbc3a6a4SArtyom Tarasenko 681ab3b491fSBlue Swirl #else 682ab3b491fSBlue Swirl cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env)); 683ab3b491fSBlue Swirl cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env)); 684ab3b491fSBlue Swirl cpu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs ? 'S' : '-', 685ab3b491fSBlue Swirl env->psrps ? 'P' : '-', env->psret ? 'E' : '-', 686ab3b491fSBlue Swirl env->wim); 687ab3b491fSBlue Swirl cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n", 688ab3b491fSBlue Swirl env->fsr, env->y); 689ab3b491fSBlue Swirl #endif 69076a23ca0SRichard Henderson cpu_fprintf(f, "\n"); 691ab3b491fSBlue Swirl } 692ab7ab3d7SAndreas Färber 693f45748f1SAndreas Färber static void sparc_cpu_set_pc(CPUState *cs, vaddr value) 694f45748f1SAndreas Färber { 695f45748f1SAndreas Färber SPARCCPU *cpu = SPARC_CPU(cs); 696f45748f1SAndreas Färber 697f45748f1SAndreas Färber cpu->env.pc = value; 698f45748f1SAndreas Färber cpu->env.npc = value + 4; 699f45748f1SAndreas Färber } 700f45748f1SAndreas Färber 701bdf7ae5bSAndreas Färber static void sparc_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) 702bdf7ae5bSAndreas Färber { 703bdf7ae5bSAndreas Färber SPARCCPU *cpu = SPARC_CPU(cs); 704bdf7ae5bSAndreas Färber 705bdf7ae5bSAndreas Färber cpu->env.pc = tb->pc; 706bdf7ae5bSAndreas Färber cpu->env.npc = tb->cs_base; 707bdf7ae5bSAndreas Färber } 708bdf7ae5bSAndreas Färber 7098c2e1b00SAndreas Färber static bool sparc_cpu_has_work(CPUState *cs) 7108c2e1b00SAndreas Färber { 7118c2e1b00SAndreas Färber SPARCCPU *cpu = SPARC_CPU(cs); 7128c2e1b00SAndreas Färber CPUSPARCState *env = &cpu->env; 7138c2e1b00SAndreas Färber 7148c2e1b00SAndreas Färber return (cs->interrupt_request & CPU_INTERRUPT_HARD) && 7158c2e1b00SAndreas Färber cpu_interrupts_enabled(env); 7168c2e1b00SAndreas Färber } 7178c2e1b00SAndreas Färber 71812a6c15eSIgor Mammedov static char *sparc_cpu_type_name(const char *cpu_model) 71912a6c15eSIgor Mammedov { 72012a6c15eSIgor Mammedov char *name = g_strdup_printf("%s-" TYPE_SPARC_CPU, cpu_model); 72112a6c15eSIgor Mammedov char *s = name; 72212a6c15eSIgor Mammedov 72312a6c15eSIgor Mammedov /* SPARC cpu model names happen to have whitespaces, 72412a6c15eSIgor Mammedov * as type names shouldn't have spaces replace them with '-' 72512a6c15eSIgor Mammedov */ 72612a6c15eSIgor Mammedov while ((s = strchr(s, ' '))) { 72712a6c15eSIgor Mammedov *s = '-'; 72812a6c15eSIgor Mammedov } 72912a6c15eSIgor Mammedov 73012a6c15eSIgor Mammedov return name; 73112a6c15eSIgor Mammedov } 73212a6c15eSIgor Mammedov 73312a6c15eSIgor Mammedov static ObjectClass *sparc_cpu_class_by_name(const char *cpu_model) 73412a6c15eSIgor Mammedov { 73512a6c15eSIgor Mammedov ObjectClass *oc; 73612a6c15eSIgor Mammedov char *typename; 73712a6c15eSIgor Mammedov 73812a6c15eSIgor Mammedov if (cpu_model == NULL) { 73912a6c15eSIgor Mammedov return NULL; 74012a6c15eSIgor Mammedov } 74112a6c15eSIgor Mammedov 74212a6c15eSIgor Mammedov typename = sparc_cpu_type_name(cpu_model); 74312a6c15eSIgor Mammedov oc = object_class_by_name(typename); 74412a6c15eSIgor Mammedov g_free(typename); 74512a6c15eSIgor Mammedov return oc; 74612a6c15eSIgor Mammedov } 74712a6c15eSIgor Mammedov 748b6e91ebfSAndreas Färber static void sparc_cpu_realizefn(DeviceState *dev, Error **errp) 749b6e91ebfSAndreas Färber { 750ce5b1bbfSLaurent Vivier CPUState *cs = CPU(dev); 751b6e91ebfSAndreas Färber SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev); 752ce5b1bbfSLaurent Vivier Error *local_err = NULL; 753247bf011SAndreas Färber SPARCCPU *cpu = SPARC_CPU(dev); 754247bf011SAndreas Färber CPUSPARCState *env = &cpu->env; 755247bf011SAndreas Färber 75670054962SIgor Mammedov #if defined(CONFIG_USER_ONLY) 757576e1c4cSIgor Mammedov if ((env->def.features & CPU_FEATURE_FLOAT)) { 758576e1c4cSIgor Mammedov env->def.features |= CPU_FEATURE_FLOAT128; 759247bf011SAndreas Färber } 760247bf011SAndreas Färber #endif 761b6e91ebfSAndreas Färber 76270054962SIgor Mammedov env->version = env->def.iu_version; 76370054962SIgor Mammedov env->fsr = env->def.fpu_version; 76470054962SIgor Mammedov env->nwindows = env->def.nwindows; 76570054962SIgor Mammedov #if !defined(TARGET_SPARC64) 76670054962SIgor Mammedov env->mmuregs[0] |= env->def.mmu_version; 76770054962SIgor Mammedov cpu_sparc_set_id(env, 0); 76870054962SIgor Mammedov env->mxccregs[7] |= env->def.mxcc_version; 76970054962SIgor Mammedov #else 77070054962SIgor Mammedov env->mmu_version = env->def.mmu_version; 77170054962SIgor Mammedov env->maxtl = env->def.maxtl; 77270054962SIgor Mammedov env->version |= env->def.maxtl << 8; 77370054962SIgor Mammedov env->version |= env->def.nwindows - 1; 77470054962SIgor Mammedov #endif 77570054962SIgor Mammedov 776ce5b1bbfSLaurent Vivier cpu_exec_realizefn(cs, &local_err); 777ce5b1bbfSLaurent Vivier if (local_err != NULL) { 778ce5b1bbfSLaurent Vivier error_propagate(errp, local_err); 779ce5b1bbfSLaurent Vivier return; 780ce5b1bbfSLaurent Vivier } 781ce5b1bbfSLaurent Vivier 782ce5b1bbfSLaurent Vivier qemu_init_vcpu(cs); 78314a10fc3SAndreas Färber 784b6e91ebfSAndreas Färber scc->parent_realize(dev, errp); 785b6e91ebfSAndreas Färber } 786b6e91ebfSAndreas Färber 787ab7ab3d7SAndreas Färber static void sparc_cpu_initfn(Object *obj) 788ab7ab3d7SAndreas Färber { 789c05efcb1SAndreas Färber CPUState *cs = CPU(obj); 790ab7ab3d7SAndreas Färber SPARCCPU *cpu = SPARC_CPU(obj); 79112a6c15eSIgor Mammedov SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(obj); 792ab7ab3d7SAndreas Färber CPUSPARCState *env = &cpu->env; 793ab7ab3d7SAndreas Färber 794c05efcb1SAndreas Färber cs->env_ptr = env; 7955266d20aSAndreas Färber 7965266d20aSAndreas Färber if (tcg_enabled()) { 7975266d20aSAndreas Färber gen_intermediate_code_init(env); 7985266d20aSAndreas Färber } 79912a6c15eSIgor Mammedov 800576e1c4cSIgor Mammedov if (scc->cpu_def) { 801576e1c4cSIgor Mammedov env->def = *scc->cpu_def; 802ab7ab3d7SAndreas Färber } 803ab7ab3d7SAndreas Färber } 804ab7ab3d7SAndreas Färber 805de05005bSIgor Mammedov static void sparc_get_nwindows(Object *obj, Visitor *v, const char *name, 806de05005bSIgor Mammedov void *opaque, Error **errp) 807de05005bSIgor Mammedov { 808de05005bSIgor Mammedov SPARCCPU *cpu = SPARC_CPU(obj); 809de05005bSIgor Mammedov int64_t value = cpu->env.def.nwindows; 810de05005bSIgor Mammedov 811de05005bSIgor Mammedov visit_type_int(v, name, &value, errp); 812de05005bSIgor Mammedov } 813de05005bSIgor Mammedov 814de05005bSIgor Mammedov static void sparc_set_nwindows(Object *obj, Visitor *v, const char *name, 815de05005bSIgor Mammedov void *opaque, Error **errp) 816de05005bSIgor Mammedov { 817de05005bSIgor Mammedov const int64_t min = MIN_NWINDOWS; 818de05005bSIgor Mammedov const int64_t max = MAX_NWINDOWS; 819de05005bSIgor Mammedov SPARCCPU *cpu = SPARC_CPU(obj); 820de05005bSIgor Mammedov Error *err = NULL; 821de05005bSIgor Mammedov int64_t value; 822de05005bSIgor Mammedov 823de05005bSIgor Mammedov visit_type_int(v, name, &value, &err); 824de05005bSIgor Mammedov if (err) { 825de05005bSIgor Mammedov error_propagate(errp, err); 826de05005bSIgor Mammedov return; 827de05005bSIgor Mammedov } 828de05005bSIgor Mammedov 829de05005bSIgor Mammedov if (value < min || value > max) { 830de05005bSIgor Mammedov error_setg(errp, "Property %s.%s doesn't take value %" PRId64 831de05005bSIgor Mammedov " (minimum: %" PRId64 ", maximum: %" PRId64 ")", 832de05005bSIgor Mammedov object_get_typename(obj), name ? name : "null", 833de05005bSIgor Mammedov value, min, max); 834de05005bSIgor Mammedov return; 835de05005bSIgor Mammedov } 836de05005bSIgor Mammedov cpu->env.def.nwindows = value; 837de05005bSIgor Mammedov } 838de05005bSIgor Mammedov 839de05005bSIgor Mammedov static PropertyInfo qdev_prop_nwindows = { 840de05005bSIgor Mammedov .name = "int", 841de05005bSIgor Mammedov .get = sparc_get_nwindows, 842de05005bSIgor Mammedov .set = sparc_set_nwindows, 843de05005bSIgor Mammedov }; 844de05005bSIgor Mammedov 845de05005bSIgor Mammedov static Property sparc_cpu_properties[] = { 846de05005bSIgor Mammedov DEFINE_PROP_BIT("float", SPARCCPU, env.def.features, 0, false), 847de05005bSIgor Mammedov DEFINE_PROP_BIT("float128", SPARCCPU, env.def.features, 1, false), 848de05005bSIgor Mammedov DEFINE_PROP_BIT("swap", SPARCCPU, env.def.features, 2, false), 849de05005bSIgor Mammedov DEFINE_PROP_BIT("mul", SPARCCPU, env.def.features, 3, false), 850de05005bSIgor Mammedov DEFINE_PROP_BIT("div", SPARCCPU, env.def.features, 4, false), 851de05005bSIgor Mammedov DEFINE_PROP_BIT("flush", SPARCCPU, env.def.features, 5, false), 852de05005bSIgor Mammedov DEFINE_PROP_BIT("fsqrt", SPARCCPU, env.def.features, 6, false), 853de05005bSIgor Mammedov DEFINE_PROP_BIT("fmul", SPARCCPU, env.def.features, 7, false), 854de05005bSIgor Mammedov DEFINE_PROP_BIT("vis1", SPARCCPU, env.def.features, 8, false), 855de05005bSIgor Mammedov DEFINE_PROP_BIT("vis2", SPARCCPU, env.def.features, 9, false), 856de05005bSIgor Mammedov DEFINE_PROP_BIT("fsmuld", SPARCCPU, env.def.features, 10, false), 857de05005bSIgor Mammedov DEFINE_PROP_BIT("hypv", SPARCCPU, env.def.features, 11, false), 858de05005bSIgor Mammedov DEFINE_PROP_BIT("cmt", SPARCCPU, env.def.features, 12, false), 859de05005bSIgor Mammedov DEFINE_PROP_BIT("gl", SPARCCPU, env.def.features, 13, false), 860de05005bSIgor Mammedov DEFINE_PROP_UNSIGNED("iu-version", SPARCCPU, env.def.iu_version, 0, 861de05005bSIgor Mammedov qdev_prop_uint64, target_ulong), 862de05005bSIgor Mammedov DEFINE_PROP_UINT32("fpu-version", SPARCCPU, env.def.fpu_version, 0), 863de05005bSIgor Mammedov DEFINE_PROP_UINT32("mmu-version", SPARCCPU, env.def.mmu_version, 0), 864de05005bSIgor Mammedov { .name = "nwindows", .info = &qdev_prop_nwindows }, 865de05005bSIgor Mammedov DEFINE_PROP_END_OF_LIST() 866de05005bSIgor Mammedov }; 867de05005bSIgor Mammedov 868ab7ab3d7SAndreas Färber static void sparc_cpu_class_init(ObjectClass *oc, void *data) 869ab7ab3d7SAndreas Färber { 870ab7ab3d7SAndreas Färber SPARCCPUClass *scc = SPARC_CPU_CLASS(oc); 871ab7ab3d7SAndreas Färber CPUClass *cc = CPU_CLASS(oc); 872b6e91ebfSAndreas Färber DeviceClass *dc = DEVICE_CLASS(oc); 873b6e91ebfSAndreas Färber 874b6e91ebfSAndreas Färber scc->parent_realize = dc->realize; 875b6e91ebfSAndreas Färber dc->realize = sparc_cpu_realizefn; 876de05005bSIgor Mammedov dc->props = sparc_cpu_properties; 877ab7ab3d7SAndreas Färber 878ab7ab3d7SAndreas Färber scc->parent_reset = cc->reset; 879ab7ab3d7SAndreas Färber cc->reset = sparc_cpu_reset; 88097a8ea5aSAndreas Färber 88112a6c15eSIgor Mammedov cc->class_by_name = sparc_cpu_class_by_name; 882*d1853231SIgor Mammedov cc->parse_features = sparc_cpu_parse_features; 8838c2e1b00SAndreas Färber cc->has_work = sparc_cpu_has_work; 88497a8ea5aSAndreas Färber cc->do_interrupt = sparc_cpu_do_interrupt; 88587afe467SRichard Henderson cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt; 886878096eeSAndreas Färber cc->dump_state = sparc_cpu_dump_state; 887f3659eeeSAndreas Färber #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) 888f3659eeeSAndreas Färber cc->memory_rw_debug = sparc_cpu_memory_rw_debug; 889f3659eeeSAndreas Färber #endif 890f45748f1SAndreas Färber cc->set_pc = sparc_cpu_set_pc; 891bdf7ae5bSAndreas Färber cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb; 8925b50e790SAndreas Färber cc->gdb_read_register = sparc_cpu_gdb_read_register; 8935b50e790SAndreas Färber cc->gdb_write_register = sparc_cpu_gdb_write_register; 8947510454eSAndreas Färber #ifdef CONFIG_USER_ONLY 8957510454eSAndreas Färber cc->handle_mmu_fault = sparc_cpu_handle_mmu_fault; 8967510454eSAndreas Färber #else 89700b941e5SAndreas Färber cc->do_unassigned_access = sparc_cpu_unassigned_access; 89893e22326SPaolo Bonzini cc->do_unaligned_access = sparc_cpu_do_unaligned_access; 89900b941e5SAndreas Färber cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug; 900df32c8d4SJuan Quintela cc->vmsd = &vmstate_sparc_cpu; 90100b941e5SAndreas Färber #endif 902df0900ebSPeter Crosthwaite cc->disas_set_info = cpu_sparc_disas_set_info; 903a0e372f0SAndreas Färber 904a0e372f0SAndreas Färber #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) 905a0e372f0SAndreas Färber cc->gdb_num_core_regs = 86; 906a0e372f0SAndreas Färber #else 907a0e372f0SAndreas Färber cc->gdb_num_core_regs = 72; 908a0e372f0SAndreas Färber #endif 909ab7ab3d7SAndreas Färber } 910ab7ab3d7SAndreas Färber 911ab7ab3d7SAndreas Färber static const TypeInfo sparc_cpu_type_info = { 912ab7ab3d7SAndreas Färber .name = TYPE_SPARC_CPU, 913ab7ab3d7SAndreas Färber .parent = TYPE_CPU, 914ab7ab3d7SAndreas Färber .instance_size = sizeof(SPARCCPU), 915ab7ab3d7SAndreas Färber .instance_init = sparc_cpu_initfn, 91612a6c15eSIgor Mammedov .abstract = true, 917ab7ab3d7SAndreas Färber .class_size = sizeof(SPARCCPUClass), 918ab7ab3d7SAndreas Färber .class_init = sparc_cpu_class_init, 919ab7ab3d7SAndreas Färber }; 920ab7ab3d7SAndreas Färber 92112a6c15eSIgor Mammedov static void sparc_cpu_cpudef_class_init(ObjectClass *oc, void *data) 92212a6c15eSIgor Mammedov { 92312a6c15eSIgor Mammedov SPARCCPUClass *scc = SPARC_CPU_CLASS(oc); 92412a6c15eSIgor Mammedov scc->cpu_def = data; 92512a6c15eSIgor Mammedov } 92612a6c15eSIgor Mammedov 92712a6c15eSIgor Mammedov static void sparc_register_cpudef_type(const struct sparc_def_t *def) 92812a6c15eSIgor Mammedov { 92912a6c15eSIgor Mammedov char *typename = sparc_cpu_type_name(def->name); 93012a6c15eSIgor Mammedov TypeInfo ti = { 93112a6c15eSIgor Mammedov .name = typename, 93212a6c15eSIgor Mammedov .parent = TYPE_SPARC_CPU, 93312a6c15eSIgor Mammedov .class_init = sparc_cpu_cpudef_class_init, 93412a6c15eSIgor Mammedov .class_data = (void *)def, 93512a6c15eSIgor Mammedov }; 93612a6c15eSIgor Mammedov 93712a6c15eSIgor Mammedov type_register(&ti); 93812a6c15eSIgor Mammedov g_free(typename); 93912a6c15eSIgor Mammedov } 94012a6c15eSIgor Mammedov 941ab7ab3d7SAndreas Färber static void sparc_cpu_register_types(void) 942ab7ab3d7SAndreas Färber { 94312a6c15eSIgor Mammedov int i; 94412a6c15eSIgor Mammedov 945ab7ab3d7SAndreas Färber type_register_static(&sparc_cpu_type_info); 94612a6c15eSIgor Mammedov for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) { 94712a6c15eSIgor Mammedov sparc_register_cpudef_type(&sparc_defs[i]); 94812a6c15eSIgor Mammedov } 949ab7ab3d7SAndreas Färber } 950ab7ab3d7SAndreas Färber 951ab7ab3d7SAndreas Färber type_init(sparc_cpu_register_types) 952