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 95650b549SChetan Pant * version 2.1 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" 230b8fa32fSMarkus Armbruster #include "qemu/module.h" 240442428aSMarkus Armbruster #include "qemu/qemu-print.h" 2563c91552SPaolo Bonzini #include "exec/exec-all.h" 26de05005bSIgor Mammedov #include "hw/qdev-properties.h" 27de05005bSIgor Mammedov #include "qapi/visitor.h" 28ab3b491fSBlue Swirl 29ab3b491fSBlue Swirl //#define DEBUG_FEATURES 30ab3b491fSBlue Swirl 31*3b4fff1bSPeter Maydell static void sparc_cpu_reset_hold(Object *obj) 32ab7ab3d7SAndreas Färber { 33*3b4fff1bSPeter Maydell CPUState *s = CPU(obj); 34ab7ab3d7SAndreas Färber SPARCCPU *cpu = SPARC_CPU(s); 35ab7ab3d7SAndreas Färber SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(cpu); 36ab7ab3d7SAndreas Färber CPUSPARCState *env = &cpu->env; 37ab7ab3d7SAndreas Färber 38*3b4fff1bSPeter Maydell if (scc->parent_phases.hold) { 39*3b4fff1bSPeter Maydell scc->parent_phases.hold(obj); 40*3b4fff1bSPeter Maydell } 41ab7ab3d7SAndreas Färber 421f5c00cfSAlex Bennée memset(env, 0, offsetof(CPUSPARCState, end_reset_fields)); 43ab3b491fSBlue Swirl env->cwp = 0; 44ab3b491fSBlue Swirl #ifndef TARGET_SPARC64 45ab3b491fSBlue Swirl env->wim = 1; 46ab3b491fSBlue Swirl #endif 47ab3b491fSBlue Swirl env->regwptr = env->regbase + (env->cwp * 16); 48ab3b491fSBlue Swirl CC_OP = CC_OP_FLAGS; 49ab3b491fSBlue Swirl #if defined(CONFIG_USER_ONLY) 50ab3b491fSBlue Swirl #ifdef TARGET_SPARC64 51ab3b491fSBlue Swirl env->cleanwin = env->nwindows - 2; 52ab3b491fSBlue Swirl env->cansave = env->nwindows - 2; 53ab3b491fSBlue Swirl env->pstate = PS_RMO | PS_PEF | PS_IE; 54ab3b491fSBlue Swirl env->asi = 0x82; /* Primary no-fault */ 55ab3b491fSBlue Swirl #endif 56ab3b491fSBlue Swirl #else 57ab3b491fSBlue Swirl #if !defined(TARGET_SPARC64) 58ab3b491fSBlue Swirl env->psret = 0; 59ab3b491fSBlue Swirl env->psrs = 1; 60ab3b491fSBlue Swirl env->psrps = 1; 61ab3b491fSBlue Swirl #endif 62ab3b491fSBlue Swirl #ifdef TARGET_SPARC64 63cbc3a6a4SArtyom Tarasenko env->pstate = PS_PRIV | PS_RED | PS_PEF; 64cbc3a6a4SArtyom Tarasenko if (!cpu_has_hypervisor(env)) { 65cbc3a6a4SArtyom Tarasenko env->pstate |= PS_AG; 66cbc3a6a4SArtyom Tarasenko } 67ab3b491fSBlue Swirl env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0; 68ab3b491fSBlue Swirl env->tl = env->maxtl; 69cbc3a6a4SArtyom Tarasenko env->gl = 2; 70ab3b491fSBlue Swirl cpu_tsptr(env)->tt = TT_POWER_ON_RESET; 71ab3b491fSBlue Swirl env->lsu = 0; 72ab3b491fSBlue Swirl #else 73ab3b491fSBlue Swirl env->mmuregs[0] &= ~(MMU_E | MMU_NF); 74576e1c4cSIgor Mammedov env->mmuregs[0] |= env->def.mmu_bm; 75ab3b491fSBlue Swirl #endif 76ab3b491fSBlue Swirl env->pc = 0; 77ab3b491fSBlue Swirl env->npc = env->pc + 4; 78ab3b491fSBlue Swirl #endif 79ab3b491fSBlue Swirl env->cache_control = 0; 80ab3b491fSBlue Swirl } 81ab3b491fSBlue Swirl 82798ac8b5SPhilippe Mathieu-Daudé #ifndef CONFIG_USER_ONLY 8387afe467SRichard Henderson static bool sparc_cpu_exec_interrupt(CPUState *cs, int interrupt_request) 8487afe467SRichard Henderson { 8587afe467SRichard Henderson if (interrupt_request & CPU_INTERRUPT_HARD) { 8687afe467SRichard Henderson SPARCCPU *cpu = SPARC_CPU(cs); 8787afe467SRichard Henderson CPUSPARCState *env = &cpu->env; 8887afe467SRichard Henderson 8987afe467SRichard Henderson if (cpu_interrupts_enabled(env) && env->interrupt_index > 0) { 9087afe467SRichard Henderson int pil = env->interrupt_index & 0xf; 9187afe467SRichard Henderson int type = env->interrupt_index & 0xf0; 9287afe467SRichard Henderson 9387afe467SRichard Henderson if (type != TT_EXTINT || cpu_pil_allowed(env, pil)) { 9487afe467SRichard Henderson cs->exception_index = env->interrupt_index; 9587afe467SRichard Henderson sparc_cpu_do_interrupt(cs); 9687afe467SRichard Henderson return true; 9787afe467SRichard Henderson } 9887afe467SRichard Henderson } 9987afe467SRichard Henderson } 10087afe467SRichard Henderson return false; 10187afe467SRichard Henderson } 102798ac8b5SPhilippe Mathieu-Daudé #endif /* !CONFIG_USER_ONLY */ 10387afe467SRichard Henderson 104df0900ebSPeter Crosthwaite static void cpu_sparc_disas_set_info(CPUState *cpu, disassemble_info *info) 105df0900ebSPeter Crosthwaite { 106df0900ebSPeter Crosthwaite info->print_insn = print_insn_sparc; 107df0900ebSPeter Crosthwaite #ifdef TARGET_SPARC64 108df0900ebSPeter Crosthwaite info->mach = bfd_mach_sparc_v9b; 109df0900ebSPeter Crosthwaite #endif 110df0900ebSPeter Crosthwaite } 111df0900ebSPeter Crosthwaite 112d1853231SIgor Mammedov static void 113d1853231SIgor Mammedov cpu_add_feat_as_prop(const char *typename, const char *name, const char *val) 114ab3b491fSBlue Swirl { 115d1853231SIgor Mammedov GlobalProperty *prop = g_new0(typeof(*prop), 1); 116d1853231SIgor Mammedov prop->driver = typename; 117d1853231SIgor Mammedov prop->property = g_strdup(name); 118d1853231SIgor Mammedov prop->value = g_strdup(val); 119d1853231SIgor Mammedov qdev_prop_register_global(prop); 120433ac7a9SAndreas Färber } 121433ac7a9SAndreas Färber 122d1853231SIgor Mammedov /* Parse "+feature,-feature,feature=foo" CPU feature string */ 123d1853231SIgor Mammedov static void sparc_cpu_parse_features(const char *typename, char *features, 124d1853231SIgor Mammedov Error **errp) 125d1853231SIgor Mammedov { 126d1853231SIgor Mammedov GList *l, *plus_features = NULL, *minus_features = NULL; 127d1853231SIgor Mammedov char *featurestr; /* Single 'key=value" string being parsed */ 128d1853231SIgor Mammedov static bool cpu_globals_initialized; 129d1853231SIgor Mammedov 130d1853231SIgor Mammedov if (cpu_globals_initialized) { 131d1853231SIgor Mammedov return; 132d1853231SIgor Mammedov } 133d1853231SIgor Mammedov cpu_globals_initialized = true; 134d1853231SIgor Mammedov 135d1853231SIgor Mammedov if (!features) { 136d1853231SIgor Mammedov return; 137d1853231SIgor Mammedov } 138d1853231SIgor Mammedov 139d1853231SIgor Mammedov for (featurestr = strtok(features, ","); 140d1853231SIgor Mammedov featurestr; 141d1853231SIgor Mammedov featurestr = strtok(NULL, ",")) { 142d1853231SIgor Mammedov const char *name; 143d1853231SIgor Mammedov const char *val = NULL; 144d1853231SIgor Mammedov char *eq = NULL; 145d1853231SIgor Mammedov 146d1853231SIgor Mammedov /* Compatibility syntax: */ 147d1853231SIgor Mammedov if (featurestr[0] == '+') { 148d1853231SIgor Mammedov plus_features = g_list_append(plus_features, 149d1853231SIgor Mammedov g_strdup(featurestr + 1)); 150d1853231SIgor Mammedov continue; 151d1853231SIgor Mammedov } else if (featurestr[0] == '-') { 152d1853231SIgor Mammedov minus_features = g_list_append(minus_features, 153d1853231SIgor Mammedov g_strdup(featurestr + 1)); 154d1853231SIgor Mammedov continue; 155d1853231SIgor Mammedov } 156d1853231SIgor Mammedov 157d1853231SIgor Mammedov eq = strchr(featurestr, '='); 158d1853231SIgor Mammedov name = featurestr; 159d1853231SIgor Mammedov if (eq) { 160d1853231SIgor Mammedov *eq++ = 0; 161d1853231SIgor Mammedov val = eq; 162d1853231SIgor Mammedov 163d1853231SIgor Mammedov /* 164d1853231SIgor Mammedov * Temporarily, only +feat/-feat will be supported 165d1853231SIgor Mammedov * for boolean properties until we remove the 166d1853231SIgor Mammedov * minus-overrides-plus semantics and just follow 167d1853231SIgor Mammedov * the order options appear on the command-line. 168d1853231SIgor Mammedov * 169d1853231SIgor Mammedov * TODO: warn if user is relying on minus-override-plus semantics 170d1853231SIgor Mammedov * TODO: remove minus-override-plus semantics after 171d1853231SIgor Mammedov * warning for a few releases 172d1853231SIgor Mammedov */ 173d1853231SIgor Mammedov if (!strcasecmp(val, "on") || 174d1853231SIgor Mammedov !strcasecmp(val, "off") || 175d1853231SIgor Mammedov !strcasecmp(val, "true") || 176d1853231SIgor Mammedov !strcasecmp(val, "false")) { 177d1853231SIgor Mammedov error_setg(errp, "Boolean properties in format %s=%s" 178d1853231SIgor Mammedov " are not supported", name, val); 179d1853231SIgor Mammedov return; 180d1853231SIgor Mammedov } 181d1853231SIgor Mammedov } else { 182d1853231SIgor Mammedov error_setg(errp, "Unsupported property format: %s", name); 183d1853231SIgor Mammedov return; 184d1853231SIgor Mammedov } 185d1853231SIgor Mammedov cpu_add_feat_as_prop(typename, name, val); 186d1853231SIgor Mammedov } 187d1853231SIgor Mammedov 188d1853231SIgor Mammedov for (l = plus_features; l; l = l->next) { 189d1853231SIgor Mammedov const char *name = l->data; 190d1853231SIgor Mammedov cpu_add_feat_as_prop(typename, name, "on"); 191d1853231SIgor Mammedov } 192d1853231SIgor Mammedov g_list_free_full(plus_features, g_free); 193d1853231SIgor Mammedov 194d1853231SIgor Mammedov for (l = minus_features; l; l = l->next) { 195d1853231SIgor Mammedov const char *name = l->data; 196d1853231SIgor Mammedov cpu_add_feat_as_prop(typename, name, "off"); 197d1853231SIgor Mammedov } 198d1853231SIgor Mammedov g_list_free_full(minus_features, g_free); 199ab3b491fSBlue Swirl } 200ab3b491fSBlue Swirl 201ab3b491fSBlue Swirl void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu) 202ab3b491fSBlue Swirl { 203ab3b491fSBlue Swirl #if !defined(TARGET_SPARC64) 204ab3b491fSBlue Swirl env->mxccregs[7] = ((cpu + 8) & 0xf) << 24; 205ab3b491fSBlue Swirl #endif 206ab3b491fSBlue Swirl } 207ab3b491fSBlue Swirl 208ab3b491fSBlue Swirl static const sparc_def_t sparc_defs[] = { 209ab3b491fSBlue Swirl #ifdef TARGET_SPARC64 210ab3b491fSBlue Swirl { 211ab3b491fSBlue Swirl .name = "Fujitsu Sparc64", 212ab3b491fSBlue Swirl .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)), 213ab3b491fSBlue Swirl .fpu_version = 0x00000000, 214ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 215ab3b491fSBlue Swirl .nwindows = 4, 216ab3b491fSBlue Swirl .maxtl = 4, 217ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 218ab3b491fSBlue Swirl }, 219ab3b491fSBlue Swirl { 220ab3b491fSBlue Swirl .name = "Fujitsu Sparc64 III", 221ab3b491fSBlue Swirl .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)), 222ab3b491fSBlue Swirl .fpu_version = 0x00000000, 223ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 224ab3b491fSBlue Swirl .nwindows = 5, 225ab3b491fSBlue Swirl .maxtl = 4, 226ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 227ab3b491fSBlue Swirl }, 228ab3b491fSBlue Swirl { 229ab3b491fSBlue Swirl .name = "Fujitsu Sparc64 IV", 230ab3b491fSBlue Swirl .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)), 231ab3b491fSBlue Swirl .fpu_version = 0x00000000, 232ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 233ab3b491fSBlue Swirl .nwindows = 8, 234ab3b491fSBlue Swirl .maxtl = 5, 235ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 236ab3b491fSBlue Swirl }, 237ab3b491fSBlue Swirl { 238ab3b491fSBlue Swirl .name = "Fujitsu Sparc64 V", 239ab3b491fSBlue Swirl .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)), 240ab3b491fSBlue Swirl .fpu_version = 0x00000000, 241ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 242ab3b491fSBlue Swirl .nwindows = 8, 243ab3b491fSBlue Swirl .maxtl = 5, 244ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 245ab3b491fSBlue Swirl }, 246ab3b491fSBlue Swirl { 247ab3b491fSBlue Swirl .name = "TI UltraSparc I", 248ab3b491fSBlue Swirl .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)), 249ab3b491fSBlue Swirl .fpu_version = 0x00000000, 250ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 251ab3b491fSBlue Swirl .nwindows = 8, 252ab3b491fSBlue Swirl .maxtl = 5, 253ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 254ab3b491fSBlue Swirl }, 255ab3b491fSBlue Swirl { 256ab3b491fSBlue Swirl .name = "TI UltraSparc II", 257ab3b491fSBlue Swirl .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)), 258ab3b491fSBlue Swirl .fpu_version = 0x00000000, 259ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 260ab3b491fSBlue Swirl .nwindows = 8, 261ab3b491fSBlue Swirl .maxtl = 5, 262ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 263ab3b491fSBlue Swirl }, 264ab3b491fSBlue Swirl { 265ab3b491fSBlue Swirl .name = "TI UltraSparc IIi", 266ab3b491fSBlue Swirl .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)), 267ab3b491fSBlue Swirl .fpu_version = 0x00000000, 268ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 269ab3b491fSBlue Swirl .nwindows = 8, 270ab3b491fSBlue Swirl .maxtl = 5, 271ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 272ab3b491fSBlue Swirl }, 273ab3b491fSBlue Swirl { 274ab3b491fSBlue Swirl .name = "TI UltraSparc IIe", 275ab3b491fSBlue Swirl .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)), 276ab3b491fSBlue Swirl .fpu_version = 0x00000000, 277ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 278ab3b491fSBlue Swirl .nwindows = 8, 279ab3b491fSBlue Swirl .maxtl = 5, 280ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 281ab3b491fSBlue Swirl }, 282ab3b491fSBlue Swirl { 283ab3b491fSBlue Swirl .name = "Sun UltraSparc III", 284ab3b491fSBlue Swirl .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)), 285ab3b491fSBlue Swirl .fpu_version = 0x00000000, 286ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 287ab3b491fSBlue Swirl .nwindows = 8, 288ab3b491fSBlue Swirl .maxtl = 5, 289ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 290ab3b491fSBlue Swirl }, 291ab3b491fSBlue Swirl { 292ab3b491fSBlue Swirl .name = "Sun UltraSparc III Cu", 293ab3b491fSBlue Swirl .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)), 294ab3b491fSBlue Swirl .fpu_version = 0x00000000, 295ab3b491fSBlue Swirl .mmu_version = mmu_us_3, 296ab3b491fSBlue Swirl .nwindows = 8, 297ab3b491fSBlue Swirl .maxtl = 5, 298ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 299ab3b491fSBlue Swirl }, 300ab3b491fSBlue Swirl { 301ab3b491fSBlue Swirl .name = "Sun UltraSparc IIIi", 302ab3b491fSBlue Swirl .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)), 303ab3b491fSBlue Swirl .fpu_version = 0x00000000, 304ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 305ab3b491fSBlue Swirl .nwindows = 8, 306ab3b491fSBlue Swirl .maxtl = 5, 307ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 308ab3b491fSBlue Swirl }, 309ab3b491fSBlue Swirl { 310ab3b491fSBlue Swirl .name = "Sun UltraSparc IV", 311ab3b491fSBlue Swirl .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)), 312ab3b491fSBlue Swirl .fpu_version = 0x00000000, 313ab3b491fSBlue Swirl .mmu_version = mmu_us_4, 314ab3b491fSBlue Swirl .nwindows = 8, 315ab3b491fSBlue Swirl .maxtl = 5, 316ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 317ab3b491fSBlue Swirl }, 318ab3b491fSBlue Swirl { 319ab3b491fSBlue Swirl .name = "Sun UltraSparc IV+", 320ab3b491fSBlue Swirl .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)), 321ab3b491fSBlue Swirl .fpu_version = 0x00000000, 322ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 323ab3b491fSBlue Swirl .nwindows = 8, 324ab3b491fSBlue Swirl .maxtl = 5, 325ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT, 326ab3b491fSBlue Swirl }, 327ab3b491fSBlue Swirl { 328ab3b491fSBlue Swirl .name = "Sun UltraSparc IIIi+", 329ab3b491fSBlue Swirl .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)), 330ab3b491fSBlue Swirl .fpu_version = 0x00000000, 331ab3b491fSBlue Swirl .mmu_version = mmu_us_3, 332ab3b491fSBlue Swirl .nwindows = 8, 333ab3b491fSBlue Swirl .maxtl = 5, 334ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 335ab3b491fSBlue Swirl }, 336ab3b491fSBlue Swirl { 337ab3b491fSBlue Swirl .name = "Sun UltraSparc T1", 338ab3b491fSBlue Swirl /* defined in sparc_ifu_fdp.v and ctu.h */ 339ab3b491fSBlue Swirl .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)), 340ab3b491fSBlue Swirl .fpu_version = 0x00000000, 341ab3b491fSBlue Swirl .mmu_version = mmu_sun4v, 342ab3b491fSBlue Swirl .nwindows = 8, 343ab3b491fSBlue Swirl .maxtl = 6, 344ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT 345ab3b491fSBlue Swirl | CPU_FEATURE_GL, 346ab3b491fSBlue Swirl }, 347ab3b491fSBlue Swirl { 348ab3b491fSBlue Swirl .name = "Sun UltraSparc T2", 349ab3b491fSBlue Swirl /* defined in tlu_asi_ctl.v and n2_revid_cust.v */ 350ab3b491fSBlue Swirl .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)), 351ab3b491fSBlue Swirl .fpu_version = 0x00000000, 352ab3b491fSBlue Swirl .mmu_version = mmu_sun4v, 353ab3b491fSBlue Swirl .nwindows = 8, 354ab3b491fSBlue Swirl .maxtl = 6, 355ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT 356ab3b491fSBlue Swirl | CPU_FEATURE_GL, 357ab3b491fSBlue Swirl }, 358ab3b491fSBlue Swirl { 359ab3b491fSBlue Swirl .name = "NEC UltraSparc I", 360ab3b491fSBlue Swirl .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)), 361ab3b491fSBlue Swirl .fpu_version = 0x00000000, 362ab3b491fSBlue Swirl .mmu_version = mmu_us_12, 363ab3b491fSBlue Swirl .nwindows = 8, 364ab3b491fSBlue Swirl .maxtl = 5, 365ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 366ab3b491fSBlue Swirl }, 367ab3b491fSBlue Swirl #else 368ab3b491fSBlue Swirl { 369ab3b491fSBlue Swirl .name = "Fujitsu MB86904", 370ab3b491fSBlue Swirl .iu_version = 0x04 << 24, /* Impl 0, ver 4 */ 371ab3b491fSBlue Swirl .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ 372ab3b491fSBlue Swirl .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */ 373ab3b491fSBlue Swirl .mmu_bm = 0x00004000, 374ab3b491fSBlue Swirl .mmu_ctpr_mask = 0x00ffffc0, 375ab3b491fSBlue Swirl .mmu_cxr_mask = 0x000000ff, 376ab3b491fSBlue Swirl .mmu_sfsr_mask = 0x00016fff, 377ab3b491fSBlue Swirl .mmu_trcr_mask = 0x00ffffff, 378ab3b491fSBlue Swirl .nwindows = 8, 379ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 380ab3b491fSBlue Swirl }, 381ab3b491fSBlue Swirl { 382ab3b491fSBlue Swirl .name = "Fujitsu MB86907", 383ab3b491fSBlue Swirl .iu_version = 0x05 << 24, /* Impl 0, ver 5 */ 384ab3b491fSBlue Swirl .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ 385ab3b491fSBlue Swirl .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */ 386ab3b491fSBlue Swirl .mmu_bm = 0x00004000, 387ab3b491fSBlue Swirl .mmu_ctpr_mask = 0xffffffc0, 388ab3b491fSBlue Swirl .mmu_cxr_mask = 0x000000ff, 389ab3b491fSBlue Swirl .mmu_sfsr_mask = 0x00016fff, 390ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 391ab3b491fSBlue Swirl .nwindows = 8, 392ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 393ab3b491fSBlue Swirl }, 394ab3b491fSBlue Swirl { 395ab3b491fSBlue Swirl .name = "TI MicroSparc I", 396ab3b491fSBlue Swirl .iu_version = 0x41000000, 397ab3b491fSBlue Swirl .fpu_version = 4 << 17, 398ab3b491fSBlue Swirl .mmu_version = 0x41000000, 399ab3b491fSBlue Swirl .mmu_bm = 0x00004000, 400ab3b491fSBlue Swirl .mmu_ctpr_mask = 0x007ffff0, 401ab3b491fSBlue Swirl .mmu_cxr_mask = 0x0000003f, 402ab3b491fSBlue Swirl .mmu_sfsr_mask = 0x00016fff, 403ab3b491fSBlue Swirl .mmu_trcr_mask = 0x0000003f, 404ab3b491fSBlue Swirl .nwindows = 7, 405ab3b491fSBlue Swirl .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL | 406ab3b491fSBlue Swirl CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | 407ab3b491fSBlue Swirl CPU_FEATURE_FMUL, 408ab3b491fSBlue Swirl }, 409ab3b491fSBlue Swirl { 410ab3b491fSBlue Swirl .name = "TI MicroSparc II", 411ab3b491fSBlue Swirl .iu_version = 0x42000000, 412ab3b491fSBlue Swirl .fpu_version = 4 << 17, 413ab3b491fSBlue Swirl .mmu_version = 0x02000000, 414ab3b491fSBlue Swirl .mmu_bm = 0x00004000, 415ab3b491fSBlue Swirl .mmu_ctpr_mask = 0x00ffffc0, 416ab3b491fSBlue Swirl .mmu_cxr_mask = 0x000000ff, 417ab3b491fSBlue Swirl .mmu_sfsr_mask = 0x00016fff, 418ab3b491fSBlue Swirl .mmu_trcr_mask = 0x00ffffff, 419ab3b491fSBlue Swirl .nwindows = 8, 420ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 421ab3b491fSBlue Swirl }, 422ab3b491fSBlue Swirl { 423ab3b491fSBlue Swirl .name = "TI MicroSparc IIep", 424ab3b491fSBlue Swirl .iu_version = 0x42000000, 425ab3b491fSBlue Swirl .fpu_version = 4 << 17, 426ab3b491fSBlue Swirl .mmu_version = 0x04000000, 427ab3b491fSBlue Swirl .mmu_bm = 0x00004000, 428ab3b491fSBlue Swirl .mmu_ctpr_mask = 0x00ffffc0, 429ab3b491fSBlue Swirl .mmu_cxr_mask = 0x000000ff, 430ab3b491fSBlue Swirl .mmu_sfsr_mask = 0x00016bff, 431ab3b491fSBlue Swirl .mmu_trcr_mask = 0x00ffffff, 432ab3b491fSBlue Swirl .nwindows = 8, 433ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 434ab3b491fSBlue Swirl }, 435ab3b491fSBlue Swirl { 436ab3b491fSBlue Swirl .name = "TI SuperSparc 40", /* STP1020NPGA */ 437ab3b491fSBlue Swirl .iu_version = 0x41000000, /* SuperSPARC 2.x */ 438ab3b491fSBlue Swirl .fpu_version = 0 << 17, 439ab3b491fSBlue Swirl .mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */ 440ab3b491fSBlue Swirl .mmu_bm = 0x00002000, 441ab3b491fSBlue Swirl .mmu_ctpr_mask = 0xffffffc0, 442ab3b491fSBlue Swirl .mmu_cxr_mask = 0x0000ffff, 443ab3b491fSBlue Swirl .mmu_sfsr_mask = 0xffffffff, 444ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 445ab3b491fSBlue Swirl .nwindows = 8, 446ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 447ab3b491fSBlue Swirl }, 448ab3b491fSBlue Swirl { 449ab3b491fSBlue Swirl .name = "TI SuperSparc 50", /* STP1020PGA */ 450ab3b491fSBlue Swirl .iu_version = 0x40000000, /* SuperSPARC 3.x */ 451ab3b491fSBlue Swirl .fpu_version = 0 << 17, 452ab3b491fSBlue Swirl .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */ 453ab3b491fSBlue Swirl .mmu_bm = 0x00002000, 454ab3b491fSBlue Swirl .mmu_ctpr_mask = 0xffffffc0, 455ab3b491fSBlue Swirl .mmu_cxr_mask = 0x0000ffff, 456ab3b491fSBlue Swirl .mmu_sfsr_mask = 0xffffffff, 457ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 458ab3b491fSBlue Swirl .nwindows = 8, 459ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 460ab3b491fSBlue Swirl }, 461ab3b491fSBlue Swirl { 462ab3b491fSBlue Swirl .name = "TI SuperSparc 51", 463ab3b491fSBlue Swirl .iu_version = 0x40000000, /* SuperSPARC 3.x */ 464ab3b491fSBlue Swirl .fpu_version = 0 << 17, 465ab3b491fSBlue Swirl .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */ 466ab3b491fSBlue Swirl .mmu_bm = 0x00002000, 467ab3b491fSBlue Swirl .mmu_ctpr_mask = 0xffffffc0, 468ab3b491fSBlue Swirl .mmu_cxr_mask = 0x0000ffff, 469ab3b491fSBlue Swirl .mmu_sfsr_mask = 0xffffffff, 470ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 471ab3b491fSBlue Swirl .mxcc_version = 0x00000104, 472ab3b491fSBlue Swirl .nwindows = 8, 473ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 474ab3b491fSBlue Swirl }, 475ab3b491fSBlue Swirl { 476ab3b491fSBlue Swirl .name = "TI SuperSparc 60", /* STP1020APGA */ 477ab3b491fSBlue Swirl .iu_version = 0x40000000, /* SuperSPARC 3.x */ 478ab3b491fSBlue Swirl .fpu_version = 0 << 17, 479ab3b491fSBlue Swirl .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */ 480ab3b491fSBlue Swirl .mmu_bm = 0x00002000, 481ab3b491fSBlue Swirl .mmu_ctpr_mask = 0xffffffc0, 482ab3b491fSBlue Swirl .mmu_cxr_mask = 0x0000ffff, 483ab3b491fSBlue Swirl .mmu_sfsr_mask = 0xffffffff, 484ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 485ab3b491fSBlue Swirl .nwindows = 8, 486ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 487ab3b491fSBlue Swirl }, 488ab3b491fSBlue Swirl { 489ab3b491fSBlue Swirl .name = "TI SuperSparc 61", 490ab3b491fSBlue Swirl .iu_version = 0x44000000, /* SuperSPARC 3.x */ 491ab3b491fSBlue Swirl .fpu_version = 0 << 17, 492ab3b491fSBlue Swirl .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */ 493ab3b491fSBlue Swirl .mmu_bm = 0x00002000, 494ab3b491fSBlue Swirl .mmu_ctpr_mask = 0xffffffc0, 495ab3b491fSBlue Swirl .mmu_cxr_mask = 0x0000ffff, 496ab3b491fSBlue Swirl .mmu_sfsr_mask = 0xffffffff, 497ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 498ab3b491fSBlue Swirl .mxcc_version = 0x00000104, 499ab3b491fSBlue Swirl .nwindows = 8, 500ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 501ab3b491fSBlue Swirl }, 502ab3b491fSBlue Swirl { 503ab3b491fSBlue Swirl .name = "TI SuperSparc II", 504ab3b491fSBlue Swirl .iu_version = 0x40000000, /* SuperSPARC II 1.x */ 505ab3b491fSBlue Swirl .fpu_version = 0 << 17, 506ab3b491fSBlue Swirl .mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */ 507ab3b491fSBlue Swirl .mmu_bm = 0x00002000, 508ab3b491fSBlue Swirl .mmu_ctpr_mask = 0xffffffc0, 509ab3b491fSBlue Swirl .mmu_cxr_mask = 0x0000ffff, 510ab3b491fSBlue Swirl .mmu_sfsr_mask = 0xffffffff, 511ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 512ab3b491fSBlue Swirl .mxcc_version = 0x00000104, 513ab3b491fSBlue Swirl .nwindows = 8, 514ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES, 515ab3b491fSBlue Swirl }, 516ab3b491fSBlue Swirl { 517ab3b491fSBlue Swirl .name = "LEON2", 518ab3b491fSBlue Swirl .iu_version = 0xf2000000, 519ab3b491fSBlue Swirl .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ 520ab3b491fSBlue Swirl .mmu_version = 0xf2000000, 521ab3b491fSBlue Swirl .mmu_bm = 0x00004000, 522ab3b491fSBlue Swirl .mmu_ctpr_mask = 0x007ffff0, 523ab3b491fSBlue Swirl .mmu_cxr_mask = 0x0000003f, 524ab3b491fSBlue Swirl .mmu_sfsr_mask = 0xffffffff, 525ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 526ab3b491fSBlue Swirl .nwindows = 8, 527ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN, 528ab3b491fSBlue Swirl }, 529ab3b491fSBlue Swirl { 530ab3b491fSBlue Swirl .name = "LEON3", 531ab3b491fSBlue Swirl .iu_version = 0xf3000000, 532ab3b491fSBlue Swirl .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ 533ab3b491fSBlue Swirl .mmu_version = 0xf3000000, 534ab3b491fSBlue Swirl .mmu_bm = 0x00000000, 5357a0a9c2cSRonald Hecht .mmu_ctpr_mask = 0xfffffffc, 5367a0a9c2cSRonald Hecht .mmu_cxr_mask = 0x000000ff, 537ab3b491fSBlue Swirl .mmu_sfsr_mask = 0xffffffff, 538ab3b491fSBlue Swirl .mmu_trcr_mask = 0xffffffff, 539ab3b491fSBlue Swirl .nwindows = 8, 540ab3b491fSBlue Swirl .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN | 54116c358e9SSebastian Huber CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL | CPU_FEATURE_POWERDOWN | 54216c358e9SSebastian Huber CPU_FEATURE_CASA, 543ab3b491fSBlue Swirl }, 544ab3b491fSBlue Swirl #endif 545ab3b491fSBlue Swirl }; 546ab3b491fSBlue Swirl 547ab3b491fSBlue Swirl static const char * const feature_name[] = { 548ab3b491fSBlue Swirl "float", 549ab3b491fSBlue Swirl "float128", 550ab3b491fSBlue Swirl "swap", 551ab3b491fSBlue Swirl "mul", 552ab3b491fSBlue Swirl "div", 553ab3b491fSBlue Swirl "flush", 554ab3b491fSBlue Swirl "fsqrt", 555ab3b491fSBlue Swirl "fmul", 556ab3b491fSBlue Swirl "vis1", 557ab3b491fSBlue Swirl "vis2", 558ab3b491fSBlue Swirl "fsmuld", 559ab3b491fSBlue Swirl "hypv", 560ab3b491fSBlue Swirl "cmt", 561ab3b491fSBlue Swirl "gl", 562ab3b491fSBlue Swirl }; 563ab3b491fSBlue Swirl 5640442428aSMarkus Armbruster static void print_features(uint32_t features, const char *prefix) 565ab3b491fSBlue Swirl { 566ab3b491fSBlue Swirl unsigned int i; 567ab3b491fSBlue Swirl 568ab3b491fSBlue Swirl for (i = 0; i < ARRAY_SIZE(feature_name); i++) { 569ab3b491fSBlue Swirl if (feature_name[i] && (features & (1 << i))) { 570ab3b491fSBlue Swirl if (prefix) { 5710442428aSMarkus Armbruster qemu_printf("%s", prefix); 572ab3b491fSBlue Swirl } 5730442428aSMarkus Armbruster qemu_printf("%s ", feature_name[i]); 574ab3b491fSBlue Swirl } 575ab3b491fSBlue Swirl } 576ab3b491fSBlue Swirl } 577ab3b491fSBlue Swirl 5780442428aSMarkus Armbruster void sparc_cpu_list(void) 579ab3b491fSBlue Swirl { 580ab3b491fSBlue Swirl unsigned int i; 581ab3b491fSBlue Swirl 582ab3b491fSBlue Swirl for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) { 5830442428aSMarkus Armbruster qemu_printf("Sparc %16s IU " TARGET_FMT_lx 584ab3b491fSBlue Swirl " FPU %08x MMU %08x NWINS %d ", 585ab3b491fSBlue Swirl sparc_defs[i].name, 586ab3b491fSBlue Swirl sparc_defs[i].iu_version, 587ab3b491fSBlue Swirl sparc_defs[i].fpu_version, 588ab3b491fSBlue Swirl sparc_defs[i].mmu_version, 589ab3b491fSBlue Swirl sparc_defs[i].nwindows); 5900442428aSMarkus Armbruster print_features(CPU_DEFAULT_FEATURES & ~sparc_defs[i].features, "-"); 5910442428aSMarkus Armbruster print_features(~CPU_DEFAULT_FEATURES & sparc_defs[i].features, "+"); 5920442428aSMarkus Armbruster qemu_printf("\n"); 593ab3b491fSBlue Swirl } 5940442428aSMarkus Armbruster qemu_printf("Default CPU feature flags (use '-' to remove): "); 5950442428aSMarkus Armbruster print_features(CPU_DEFAULT_FEATURES, NULL); 5960442428aSMarkus Armbruster qemu_printf("\n"); 5970442428aSMarkus Armbruster qemu_printf("Available CPU feature flags (use '+' to add): "); 5980442428aSMarkus Armbruster print_features(~CPU_DEFAULT_FEATURES, NULL); 5990442428aSMarkus Armbruster qemu_printf("\n"); 6000442428aSMarkus Armbruster qemu_printf("Numerical features (use '=' to set): iu_version " 601ab3b491fSBlue Swirl "fpu_version mmu_version nwindows\n"); 602ab3b491fSBlue Swirl } 603ab3b491fSBlue Swirl 60490c84c56SMarkus Armbruster static void cpu_print_cc(FILE *f, uint32_t cc) 605ab3b491fSBlue Swirl { 60690c84c56SMarkus Armbruster qemu_fprintf(f, "%c%c%c%c", cc & PSR_NEG ? 'N' : '-', 607ab3b491fSBlue Swirl cc & PSR_ZERO ? 'Z' : '-', cc & PSR_OVF ? 'V' : '-', 608ab3b491fSBlue Swirl cc & PSR_CARRY ? 'C' : '-'); 609ab3b491fSBlue Swirl } 610ab3b491fSBlue Swirl 611ab3b491fSBlue Swirl #ifdef TARGET_SPARC64 612ab3b491fSBlue Swirl #define REGS_PER_LINE 4 613ab3b491fSBlue Swirl #else 614ab3b491fSBlue Swirl #define REGS_PER_LINE 8 615ab3b491fSBlue Swirl #endif 616ab3b491fSBlue Swirl 6179ac200acSPhilippe Mathieu-Daudé static void sparc_cpu_dump_state(CPUState *cs, FILE *f, int flags) 618ab3b491fSBlue Swirl { 619878096eeSAndreas Färber SPARCCPU *cpu = SPARC_CPU(cs); 620878096eeSAndreas Färber CPUSPARCState *env = &cpu->env; 621ab3b491fSBlue Swirl int i, x; 622ab3b491fSBlue Swirl 62390c84c56SMarkus Armbruster qemu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc, 624ab3b491fSBlue Swirl env->npc); 625ab3b491fSBlue Swirl 626ab3b491fSBlue Swirl for (i = 0; i < 8; i++) { 627ab3b491fSBlue Swirl if (i % REGS_PER_LINE == 0) { 62890c84c56SMarkus Armbruster qemu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1); 629ab3b491fSBlue Swirl } 63090c84c56SMarkus Armbruster qemu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]); 631ab3b491fSBlue Swirl if (i % REGS_PER_LINE == REGS_PER_LINE - 1) { 63290c84c56SMarkus Armbruster qemu_fprintf(f, "\n"); 633ab3b491fSBlue Swirl } 634ab3b491fSBlue Swirl } 635ab3b491fSBlue Swirl for (x = 0; x < 3; x++) { 636ab3b491fSBlue Swirl for (i = 0; i < 8; i++) { 637ab3b491fSBlue Swirl if (i % REGS_PER_LINE == 0) { 63890c84c56SMarkus Armbruster qemu_fprintf(f, "%%%c%d-%d: ", 639ab3b491fSBlue Swirl x == 0 ? 'o' : (x == 1 ? 'l' : 'i'), 640ab3b491fSBlue Swirl i, i + REGS_PER_LINE - 1); 641ab3b491fSBlue Swirl } 64290c84c56SMarkus Armbruster qemu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]); 643ab3b491fSBlue Swirl if (i % REGS_PER_LINE == REGS_PER_LINE - 1) { 64490c84c56SMarkus Armbruster qemu_fprintf(f, "\n"); 645ab3b491fSBlue Swirl } 646ab3b491fSBlue Swirl } 647ab3b491fSBlue Swirl } 64876a23ca0SRichard Henderson 649d13c394cSRichard Henderson if (flags & CPU_DUMP_FPU) { 65030038fd8SRichard Henderson for (i = 0; i < TARGET_DPREGS; i++) { 651ab3b491fSBlue Swirl if ((i & 3) == 0) { 65290c84c56SMarkus Armbruster qemu_fprintf(f, "%%f%02d: ", i * 2); 653ab3b491fSBlue Swirl } 65490c84c56SMarkus Armbruster qemu_fprintf(f, " %016" PRIx64, env->fpr[i].ll); 655ab3b491fSBlue Swirl if ((i & 3) == 3) { 65690c84c56SMarkus Armbruster qemu_fprintf(f, "\n"); 657ab3b491fSBlue Swirl } 658ab3b491fSBlue Swirl } 659d13c394cSRichard Henderson } 660d13c394cSRichard Henderson 661ab3b491fSBlue Swirl #ifdef TARGET_SPARC64 66290c84c56SMarkus Armbruster qemu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate, 663ab3b491fSBlue Swirl (unsigned)cpu_get_ccr(env)); 66490c84c56SMarkus Armbruster cpu_print_cc(f, cpu_get_ccr(env) << PSR_CARRY_SHIFT); 66590c84c56SMarkus Armbruster qemu_fprintf(f, " xcc: "); 66690c84c56SMarkus Armbruster cpu_print_cc(f, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4)); 66790c84c56SMarkus Armbruster qemu_fprintf(f, ") asi: %02x tl: %d pil: %x gl: %d\n", env->asi, env->tl, 668cbc3a6a4SArtyom Tarasenko env->psrpil, env->gl); 66990c84c56SMarkus Armbruster qemu_fprintf(f, "tbr: " TARGET_FMT_lx " hpstate: " TARGET_FMT_lx " htba: " 670cbc3a6a4SArtyom Tarasenko TARGET_FMT_lx "\n", env->tbr, env->hpstate, env->htba); 67190c84c56SMarkus Armbruster qemu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d " 672ab3b491fSBlue Swirl "cleanwin: %d cwp: %d\n", 673ab3b491fSBlue Swirl env->cansave, env->canrestore, env->otherwin, env->wstate, 674ab3b491fSBlue Swirl env->cleanwin, env->nwindows - 1 - env->cwp); 67590c84c56SMarkus Armbruster qemu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: " 676ab3b491fSBlue Swirl TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs); 677cbc3a6a4SArtyom Tarasenko 678ab3b491fSBlue Swirl #else 67990c84c56SMarkus Armbruster qemu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env)); 68090c84c56SMarkus Armbruster cpu_print_cc(f, cpu_get_psr(env)); 68190c84c56SMarkus Armbruster qemu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs ? 'S' : '-', 682ab3b491fSBlue Swirl env->psrps ? 'P' : '-', env->psret ? 'E' : '-', 683ab3b491fSBlue Swirl env->wim); 68490c84c56SMarkus Armbruster qemu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n", 685ab3b491fSBlue Swirl env->fsr, env->y); 686ab3b491fSBlue Swirl #endif 68790c84c56SMarkus Armbruster qemu_fprintf(f, "\n"); 688ab3b491fSBlue Swirl } 689ab7ab3d7SAndreas Färber 690f45748f1SAndreas Färber static void sparc_cpu_set_pc(CPUState *cs, vaddr value) 691f45748f1SAndreas Färber { 692f45748f1SAndreas Färber SPARCCPU *cpu = SPARC_CPU(cs); 693f45748f1SAndreas Färber 694f45748f1SAndreas Färber cpu->env.pc = value; 695f45748f1SAndreas Färber cpu->env.npc = value + 4; 696f45748f1SAndreas Färber } 697f45748f1SAndreas Färber 698e4fdf9dfSRichard Henderson static vaddr sparc_cpu_get_pc(CPUState *cs) 699e4fdf9dfSRichard Henderson { 700e4fdf9dfSRichard Henderson SPARCCPU *cpu = SPARC_CPU(cs); 701e4fdf9dfSRichard Henderson 702e4fdf9dfSRichard Henderson return cpu->env.pc; 703e4fdf9dfSRichard Henderson } 704e4fdf9dfSRichard Henderson 70504a37d4cSRichard Henderson static void sparc_cpu_synchronize_from_tb(CPUState *cs, 70604a37d4cSRichard Henderson const TranslationBlock *tb) 707bdf7ae5bSAndreas Färber { 708bdf7ae5bSAndreas Färber SPARCCPU *cpu = SPARC_CPU(cs); 709bdf7ae5bSAndreas Färber 710fbf59aadSRichard Henderson cpu->env.pc = tb_pc(tb); 711bdf7ae5bSAndreas Färber cpu->env.npc = tb->cs_base; 712bdf7ae5bSAndreas Färber } 713bdf7ae5bSAndreas Färber 7148c2e1b00SAndreas Färber static bool sparc_cpu_has_work(CPUState *cs) 7158c2e1b00SAndreas Färber { 7168c2e1b00SAndreas Färber SPARCCPU *cpu = SPARC_CPU(cs); 7178c2e1b00SAndreas Färber CPUSPARCState *env = &cpu->env; 7188c2e1b00SAndreas Färber 7198c2e1b00SAndreas Färber return (cs->interrupt_request & CPU_INTERRUPT_HARD) && 7208c2e1b00SAndreas Färber cpu_interrupts_enabled(env); 7218c2e1b00SAndreas Färber } 7228c2e1b00SAndreas Färber 72312a6c15eSIgor Mammedov static char *sparc_cpu_type_name(const char *cpu_model) 72412a6c15eSIgor Mammedov { 7251d4bfc54SIgor Mammedov char *name = g_strdup_printf(SPARC_CPU_TYPE_NAME("%s"), cpu_model); 72612a6c15eSIgor Mammedov char *s = name; 72712a6c15eSIgor Mammedov 72812a6c15eSIgor Mammedov /* SPARC cpu model names happen to have whitespaces, 72912a6c15eSIgor Mammedov * as type names shouldn't have spaces replace them with '-' 73012a6c15eSIgor Mammedov */ 73112a6c15eSIgor Mammedov while ((s = strchr(s, ' '))) { 73212a6c15eSIgor Mammedov *s = '-'; 73312a6c15eSIgor Mammedov } 73412a6c15eSIgor Mammedov 73512a6c15eSIgor Mammedov return name; 73612a6c15eSIgor Mammedov } 73712a6c15eSIgor Mammedov 73812a6c15eSIgor Mammedov static ObjectClass *sparc_cpu_class_by_name(const char *cpu_model) 73912a6c15eSIgor Mammedov { 74012a6c15eSIgor Mammedov ObjectClass *oc; 74112a6c15eSIgor Mammedov char *typename; 74212a6c15eSIgor Mammedov 74312a6c15eSIgor Mammedov typename = sparc_cpu_type_name(cpu_model); 74412a6c15eSIgor Mammedov oc = object_class_by_name(typename); 74512a6c15eSIgor Mammedov g_free(typename); 74612a6c15eSIgor Mammedov return oc; 74712a6c15eSIgor Mammedov } 74812a6c15eSIgor Mammedov 749b6e91ebfSAndreas Färber static void sparc_cpu_realizefn(DeviceState *dev, Error **errp) 750b6e91ebfSAndreas Färber { 751ce5b1bbfSLaurent Vivier CPUState *cs = CPU(dev); 752b6e91ebfSAndreas Färber SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev); 753ce5b1bbfSLaurent Vivier Error *local_err = NULL; 754247bf011SAndreas Färber SPARCCPU *cpu = SPARC_CPU(dev); 755247bf011SAndreas Färber CPUSPARCState *env = &cpu->env; 756247bf011SAndreas Färber 75770054962SIgor Mammedov #if defined(CONFIG_USER_ONLY) 758576e1c4cSIgor Mammedov if ((env->def.features & CPU_FEATURE_FLOAT)) { 759576e1c4cSIgor Mammedov env->def.features |= CPU_FEATURE_FLOAT128; 760247bf011SAndreas Färber } 761247bf011SAndreas Färber #endif 762b6e91ebfSAndreas Färber 76370054962SIgor Mammedov env->version = env->def.iu_version; 76470054962SIgor Mammedov env->fsr = env->def.fpu_version; 76570054962SIgor Mammedov env->nwindows = env->def.nwindows; 76670054962SIgor Mammedov #if !defined(TARGET_SPARC64) 76770054962SIgor Mammedov env->mmuregs[0] |= env->def.mmu_version; 76870054962SIgor Mammedov cpu_sparc_set_id(env, 0); 76970054962SIgor Mammedov env->mxccregs[7] |= env->def.mxcc_version; 77070054962SIgor Mammedov #else 77170054962SIgor Mammedov env->mmu_version = env->def.mmu_version; 77270054962SIgor Mammedov env->maxtl = env->def.maxtl; 77370054962SIgor Mammedov env->version |= env->def.maxtl << 8; 77470054962SIgor Mammedov env->version |= env->def.nwindows - 1; 77570054962SIgor Mammedov #endif 77670054962SIgor Mammedov 777ce5b1bbfSLaurent Vivier cpu_exec_realizefn(cs, &local_err); 778ce5b1bbfSLaurent Vivier if (local_err != NULL) { 779ce5b1bbfSLaurent Vivier error_propagate(errp, local_err); 780ce5b1bbfSLaurent Vivier return; 781ce5b1bbfSLaurent Vivier } 782ce5b1bbfSLaurent Vivier 783ce5b1bbfSLaurent Vivier qemu_init_vcpu(cs); 78414a10fc3SAndreas Färber 785b6e91ebfSAndreas Färber scc->parent_realize(dev, errp); 786b6e91ebfSAndreas Färber } 787b6e91ebfSAndreas Färber 788ab7ab3d7SAndreas Färber static void sparc_cpu_initfn(Object *obj) 789ab7ab3d7SAndreas Färber { 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 7947506ed90SRichard Henderson cpu_set_cpustate_pointers(cpu); 7955266d20aSAndreas Färber 796576e1c4cSIgor Mammedov if (scc->cpu_def) { 797576e1c4cSIgor Mammedov env->def = *scc->cpu_def; 798ab7ab3d7SAndreas Färber } 799ab7ab3d7SAndreas Färber } 800ab7ab3d7SAndreas Färber 801de05005bSIgor Mammedov static void sparc_get_nwindows(Object *obj, Visitor *v, const char *name, 802de05005bSIgor Mammedov void *opaque, Error **errp) 803de05005bSIgor Mammedov { 804de05005bSIgor Mammedov SPARCCPU *cpu = SPARC_CPU(obj); 805de05005bSIgor Mammedov int64_t value = cpu->env.def.nwindows; 806de05005bSIgor Mammedov 807de05005bSIgor Mammedov visit_type_int(v, name, &value, errp); 808de05005bSIgor Mammedov } 809de05005bSIgor Mammedov 810de05005bSIgor Mammedov static void sparc_set_nwindows(Object *obj, Visitor *v, const char *name, 811de05005bSIgor Mammedov void *opaque, Error **errp) 812de05005bSIgor Mammedov { 813de05005bSIgor Mammedov const int64_t min = MIN_NWINDOWS; 814de05005bSIgor Mammedov const int64_t max = MAX_NWINDOWS; 815de05005bSIgor Mammedov SPARCCPU *cpu = SPARC_CPU(obj); 816de05005bSIgor Mammedov int64_t value; 817de05005bSIgor Mammedov 818668f62ecSMarkus Armbruster if (!visit_type_int(v, name, &value, errp)) { 819de05005bSIgor Mammedov return; 820de05005bSIgor Mammedov } 821de05005bSIgor Mammedov 822de05005bSIgor Mammedov if (value < min || value > max) { 823de05005bSIgor Mammedov error_setg(errp, "Property %s.%s doesn't take value %" PRId64 824de05005bSIgor Mammedov " (minimum: %" PRId64 ", maximum: %" PRId64 ")", 825de05005bSIgor Mammedov object_get_typename(obj), name ? name : "null", 826de05005bSIgor Mammedov value, min, max); 827de05005bSIgor Mammedov return; 828de05005bSIgor Mammedov } 829de05005bSIgor Mammedov cpu->env.def.nwindows = value; 830de05005bSIgor Mammedov } 831de05005bSIgor Mammedov 832de05005bSIgor Mammedov static PropertyInfo qdev_prop_nwindows = { 833de05005bSIgor Mammedov .name = "int", 834de05005bSIgor Mammedov .get = sparc_get_nwindows, 835de05005bSIgor Mammedov .set = sparc_set_nwindows, 836de05005bSIgor Mammedov }; 837de05005bSIgor Mammedov 838de05005bSIgor Mammedov static Property sparc_cpu_properties[] = { 839de05005bSIgor Mammedov DEFINE_PROP_BIT("float", SPARCCPU, env.def.features, 0, false), 840de05005bSIgor Mammedov DEFINE_PROP_BIT("float128", SPARCCPU, env.def.features, 1, false), 841de05005bSIgor Mammedov DEFINE_PROP_BIT("swap", SPARCCPU, env.def.features, 2, false), 842de05005bSIgor Mammedov DEFINE_PROP_BIT("mul", SPARCCPU, env.def.features, 3, false), 843de05005bSIgor Mammedov DEFINE_PROP_BIT("div", SPARCCPU, env.def.features, 4, false), 844de05005bSIgor Mammedov DEFINE_PROP_BIT("flush", SPARCCPU, env.def.features, 5, false), 845de05005bSIgor Mammedov DEFINE_PROP_BIT("fsqrt", SPARCCPU, env.def.features, 6, false), 846de05005bSIgor Mammedov DEFINE_PROP_BIT("fmul", SPARCCPU, env.def.features, 7, false), 847de05005bSIgor Mammedov DEFINE_PROP_BIT("vis1", SPARCCPU, env.def.features, 8, false), 848de05005bSIgor Mammedov DEFINE_PROP_BIT("vis2", SPARCCPU, env.def.features, 9, false), 849de05005bSIgor Mammedov DEFINE_PROP_BIT("fsmuld", SPARCCPU, env.def.features, 10, false), 850de05005bSIgor Mammedov DEFINE_PROP_BIT("hypv", SPARCCPU, env.def.features, 11, false), 851de05005bSIgor Mammedov DEFINE_PROP_BIT("cmt", SPARCCPU, env.def.features, 12, false), 852de05005bSIgor Mammedov DEFINE_PROP_BIT("gl", SPARCCPU, env.def.features, 13, false), 853de05005bSIgor Mammedov DEFINE_PROP_UNSIGNED("iu-version", SPARCCPU, env.def.iu_version, 0, 854de05005bSIgor Mammedov qdev_prop_uint64, target_ulong), 855de05005bSIgor Mammedov DEFINE_PROP_UINT32("fpu-version", SPARCCPU, env.def.fpu_version, 0), 856de05005bSIgor Mammedov DEFINE_PROP_UINT32("mmu-version", SPARCCPU, env.def.mmu_version, 0), 85743b6ab4cSEduardo Habkost DEFINE_PROP("nwindows", SPARCCPU, env.def.nwindows, 85843b6ab4cSEduardo Habkost qdev_prop_nwindows, uint32_t), 859de05005bSIgor Mammedov DEFINE_PROP_END_OF_LIST() 860de05005bSIgor Mammedov }; 861de05005bSIgor Mammedov 8628b80bd28SPhilippe Mathieu-Daudé #ifndef CONFIG_USER_ONLY 8638b80bd28SPhilippe Mathieu-Daudé #include "hw/core/sysemu-cpu-ops.h" 8648b80bd28SPhilippe Mathieu-Daudé 8658b80bd28SPhilippe Mathieu-Daudé static const struct SysemuCPUOps sparc_sysemu_ops = { 86608928c6dSPhilippe Mathieu-Daudé .get_phys_page_debug = sparc_cpu_get_phys_page_debug, 867feece4d0SPhilippe Mathieu-Daudé .legacy_vmsd = &vmstate_sparc_cpu, 8688b80bd28SPhilippe Mathieu-Daudé }; 8698b80bd28SPhilippe Mathieu-Daudé #endif 8708b80bd28SPhilippe Mathieu-Daudé 87178271684SClaudio Fontana #ifdef CONFIG_TCG 87278271684SClaudio Fontana #include "hw/core/tcg-cpu-ops.h" 87378271684SClaudio Fontana 87411906557SRichard Henderson static const struct TCGCPUOps sparc_tcg_ops = { 87578271684SClaudio Fontana .initialize = sparc_tcg_init, 87678271684SClaudio Fontana .synchronize_from_tb = sparc_cpu_synchronize_from_tb, 877f36aaa53SRichard Henderson .restore_state_to_opc = sparc_restore_state_to_opc, 87878271684SClaudio Fontana 87978271684SClaudio Fontana #ifndef CONFIG_USER_ONLY 880caac44a5SRichard Henderson .tlb_fill = sparc_cpu_tlb_fill, 881798ac8b5SPhilippe Mathieu-Daudé .cpu_exec_interrupt = sparc_cpu_exec_interrupt, 88278271684SClaudio Fontana .do_interrupt = sparc_cpu_do_interrupt, 88378271684SClaudio Fontana .do_transaction_failed = sparc_cpu_do_transaction_failed, 88478271684SClaudio Fontana .do_unaligned_access = sparc_cpu_do_unaligned_access, 88578271684SClaudio Fontana #endif /* !CONFIG_USER_ONLY */ 88678271684SClaudio Fontana }; 88778271684SClaudio Fontana #endif /* CONFIG_TCG */ 88878271684SClaudio Fontana 889ab7ab3d7SAndreas Färber static void sparc_cpu_class_init(ObjectClass *oc, void *data) 890ab7ab3d7SAndreas Färber { 891ab7ab3d7SAndreas Färber SPARCCPUClass *scc = SPARC_CPU_CLASS(oc); 892ab7ab3d7SAndreas Färber CPUClass *cc = CPU_CLASS(oc); 893b6e91ebfSAndreas Färber DeviceClass *dc = DEVICE_CLASS(oc); 894*3b4fff1bSPeter Maydell ResettableClass *rc = RESETTABLE_CLASS(oc); 895b6e91ebfSAndreas Färber 896bf853881SPhilippe Mathieu-Daudé device_class_set_parent_realize(dc, sparc_cpu_realizefn, 897bf853881SPhilippe Mathieu-Daudé &scc->parent_realize); 8984f67d30bSMarc-André Lureau device_class_set_props(dc, sparc_cpu_properties); 899ab7ab3d7SAndreas Färber 900*3b4fff1bSPeter Maydell resettable_class_set_parent_phases(rc, NULL, sparc_cpu_reset_hold, NULL, 901*3b4fff1bSPeter Maydell &scc->parent_phases); 90297a8ea5aSAndreas Färber 90312a6c15eSIgor Mammedov cc->class_by_name = sparc_cpu_class_by_name; 904d1853231SIgor Mammedov cc->parse_features = sparc_cpu_parse_features; 9058c2e1b00SAndreas Färber cc->has_work = sparc_cpu_has_work; 906878096eeSAndreas Färber cc->dump_state = sparc_cpu_dump_state; 907f3659eeeSAndreas Färber #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) 908f3659eeeSAndreas Färber cc->memory_rw_debug = sparc_cpu_memory_rw_debug; 909f3659eeeSAndreas Färber #endif 910f45748f1SAndreas Färber cc->set_pc = sparc_cpu_set_pc; 911e4fdf9dfSRichard Henderson cc->get_pc = sparc_cpu_get_pc; 9125b50e790SAndreas Färber cc->gdb_read_register = sparc_cpu_gdb_read_register; 9135b50e790SAndreas Färber cc->gdb_write_register = sparc_cpu_gdb_write_register; 914e84942f2SRichard Henderson #ifndef CONFIG_USER_ONLY 9158b80bd28SPhilippe Mathieu-Daudé cc->sysemu_ops = &sparc_sysemu_ops; 91600b941e5SAndreas Färber #endif 917df0900ebSPeter Crosthwaite cc->disas_set_info = cpu_sparc_disas_set_info; 918a0e372f0SAndreas Färber 919a0e372f0SAndreas Färber #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) 920a0e372f0SAndreas Färber cc->gdb_num_core_regs = 86; 921a0e372f0SAndreas Färber #else 922a0e372f0SAndreas Färber cc->gdb_num_core_regs = 72; 923a0e372f0SAndreas Färber #endif 92478271684SClaudio Fontana cc->tcg_ops = &sparc_tcg_ops; 925ab7ab3d7SAndreas Färber } 926ab7ab3d7SAndreas Färber 927ab7ab3d7SAndreas Färber static const TypeInfo sparc_cpu_type_info = { 928ab7ab3d7SAndreas Färber .name = TYPE_SPARC_CPU, 929ab7ab3d7SAndreas Färber .parent = TYPE_CPU, 930ab7ab3d7SAndreas Färber .instance_size = sizeof(SPARCCPU), 931ab7ab3d7SAndreas Färber .instance_init = sparc_cpu_initfn, 93212a6c15eSIgor Mammedov .abstract = true, 933ab7ab3d7SAndreas Färber .class_size = sizeof(SPARCCPUClass), 934ab7ab3d7SAndreas Färber .class_init = sparc_cpu_class_init, 935ab7ab3d7SAndreas Färber }; 936ab7ab3d7SAndreas Färber 93712a6c15eSIgor Mammedov static void sparc_cpu_cpudef_class_init(ObjectClass *oc, void *data) 93812a6c15eSIgor Mammedov { 93912a6c15eSIgor Mammedov SPARCCPUClass *scc = SPARC_CPU_CLASS(oc); 94012a6c15eSIgor Mammedov scc->cpu_def = data; 94112a6c15eSIgor Mammedov } 94212a6c15eSIgor Mammedov 94312a6c15eSIgor Mammedov static void sparc_register_cpudef_type(const struct sparc_def_t *def) 94412a6c15eSIgor Mammedov { 94512a6c15eSIgor Mammedov char *typename = sparc_cpu_type_name(def->name); 94612a6c15eSIgor Mammedov TypeInfo ti = { 94712a6c15eSIgor Mammedov .name = typename, 94812a6c15eSIgor Mammedov .parent = TYPE_SPARC_CPU, 94912a6c15eSIgor Mammedov .class_init = sparc_cpu_cpudef_class_init, 95012a6c15eSIgor Mammedov .class_data = (void *)def, 95112a6c15eSIgor Mammedov }; 95212a6c15eSIgor Mammedov 95312a6c15eSIgor Mammedov type_register(&ti); 95412a6c15eSIgor Mammedov g_free(typename); 95512a6c15eSIgor Mammedov } 95612a6c15eSIgor Mammedov 957ab7ab3d7SAndreas Färber static void sparc_cpu_register_types(void) 958ab7ab3d7SAndreas Färber { 95912a6c15eSIgor Mammedov int i; 96012a6c15eSIgor Mammedov 961ab7ab3d7SAndreas Färber type_register_static(&sparc_cpu_type_info); 96212a6c15eSIgor Mammedov for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) { 96312a6c15eSIgor Mammedov sparc_register_cpudef_type(&sparc_defs[i]); 96412a6c15eSIgor Mammedov } 965ab7ab3d7SAndreas Färber } 966ab7ab3d7SAndreas Färber 967ab7ab3d7SAndreas Färber type_init(sparc_cpu_register_types) 968