diff -urp qemu-20230327.orig/linux-user/sparc/target_elf.h qemu-20230327/linux-user/sparc/target_elf.h
--- qemu-20230327.orig/linux-user/sparc/target_elf.h	2023-03-27 15:41:42.000000000 +0200
+++ qemu-20230327/linux-user/sparc/target_elf.h	2023-03-31 21:41:23.282183990 +0200
@@ -12,7 +12,7 @@ static inline const char *cpu_get_model(
 #ifdef TARGET_SPARC64
     return "TI UltraSparc II";
 #else
-    return "Fujitsu MB86904";
+    return "LEON3";
 #endif
 }
 #endif
diff -urp qemu-20230327.orig/linux-user/syscall.c qemu-20230327/linux-user/syscall.c
--- qemu-20230327.orig/linux-user/syscall.c	2023-03-27 15:41:42.000000000 +0200
+++ qemu-20230327/linux-user/syscall.c	2023-04-01 13:54:14.709136932 +0200
@@ -8286,7 +8286,11 @@ static int open_net_route(CPUArchState *
 #if defined(TARGET_SPARC)
 static int open_cpuinfo(CPUArchState *cpu_env, int fd)
 {
+#if defined(TARGET_SPARC64)
     dprintf(fd, "type\t\t: sun4u\n");
+#else
+    dprintf(fd, "type\t\t: sun4m\n");
+#endif
     return 0;
 }
 #endif
diff -urp qemu-20230327.orig/target/sparc/cpu.c qemu-20230327/target/sparc/cpu.c
--- qemu-20230327.orig/target/sparc/cpu.c	2023-03-27 15:41:42.000000000 +0200
+++ qemu-20230327/target/sparc/cpu.c	2023-03-31 21:32:54.927008782 +0200
@@ -560,6 +560,11 @@ static const char * const feature_name[]
     "hypv",
     "cmt",
     "gl",
+    "ta0shdn",
+    "asr17",
+    "cachectrl",
+    "powerdown",
+    "casa",
 };
 
 static void print_features(uint32_t features, const char *prefix)
@@ -852,6 +857,11 @@ static Property sparc_cpu_properties[] =
     DEFINE_PROP_BIT("hypv",     SPARCCPU, env.def.features, 11, false),
     DEFINE_PROP_BIT("cmt",      SPARCCPU, env.def.features, 12, false),
     DEFINE_PROP_BIT("gl",       SPARCCPU, env.def.features, 13, false),
+    DEFINE_PROP_BIT("ta0shdn",  SPARCCPU, env.def.features, 14, false),
+    DEFINE_PROP_BIT("asr17",    SPARCCPU, env.def.features, 15, false),
+    DEFINE_PROP_BIT("cachectrl",SPARCCPU, env.def.features, 16, false),
+    DEFINE_PROP_BIT("powerdown",SPARCCPU, env.def.features, 17, false),
+    DEFINE_PROP_BIT("casa",     SPARCCPU, env.def.features, 18, false),
     DEFINE_PROP_UNSIGNED("iu-version", SPARCCPU, env.def.iu_version, 0,
                          qdev_prop_uint64, target_ulong),
     DEFINE_PROP_UINT32("fpu-version", SPARCCPU, env.def.fpu_version, 0),
diff -urp qemu-20230327.orig/target/sparc/helper.h qemu-20230327/target/sparc/helper.h
--- qemu-20230327.orig/target/sparc/helper.h	2023-03-27 15:41:42.000000000 +0200
+++ qemu-20230327/target/sparc/helper.h	2023-03-31 20:41:36.084224862 +0200
@@ -38,10 +38,10 @@ DEF_HELPER_3(tsubcctv, tl, env, tl, tl)
 DEF_HELPER_FLAGS_3(sdivx, TCG_CALL_NO_WG, s64, env, s64, s64)
 DEF_HELPER_FLAGS_3(udivx, TCG_CALL_NO_WG, i64, env, i64, i64)
 #endif
-#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
+//#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
 DEF_HELPER_FLAGS_4(ld_asi, TCG_CALL_NO_WG, i64, env, tl, int, i32)
 DEF_HELPER_FLAGS_5(st_asi, TCG_CALL_NO_WG, void, env, tl, i64, int, i32)
-#endif
+//#endif
 DEF_HELPER_FLAGS_1(check_ieee_exceptions, TCG_CALL_NO_WG, tl, env)
 DEF_HELPER_FLAGS_3(ldfsr, TCG_CALL_NO_RWG, tl, env, tl, i32)
 DEF_HELPER_FLAGS_1(fabss, TCG_CALL_NO_RWG_SE, f32, f32)
diff -urp qemu-20230327.orig/target/sparc/ldst_helper.c qemu-20230327/target/sparc/ldst_helper.c
--- qemu-20230327.orig/target/sparc/ldst_helper.c	2023-03-27 15:41:42.000000000 +0200
+++ qemu-20230327/target/sparc/ldst_helper.c	2023-03-31 21:02:21.897968335 +0200
@@ -593,6 +593,7 @@ uint64_t helper_ld_asi(CPUSPARCState *en
 #if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
     uint32_t last_addr = addr;
 #endif
+//#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
 
     do_check_align(env, addr, size - 1, GETPC());
     switch (asi) {
@@ -1167,7 +1168,19 @@ void helper_st_asi(CPUSPARCState *env, t
 #endif
 }
 
+#else /* CONFIG_USER_ONLY */
+uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
+                       int asi, uint32_t memop)
+{
+	return(0);
+}
+void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
+                   int asi, uint32_t memop)
+{
+}
+
 #endif /* CONFIG_USER_ONLY */
+
 #else /* TARGET_SPARC64 */
 
 #ifdef CONFIG_USER_ONLY
diff -urp qemu-20230327.orig/target/sparc/translate.c qemu-20230327/target/sparc/translate.c
--- qemu-20230327.orig/target/sparc/translate.c	2023-03-27 15:41:42.000000000 +0200
+++ qemu-20230327/target/sparc/translate.c	2023-04-01 15:24:18.293176711 +0200
@@ -1910,7 +1910,8 @@ static void gen_ldstub(DisasContext *dc,
 }
 
 /* asi moves */
-#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
+//#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
+#if 1
 typedef enum {
     GET_ASI_HELPER,
     GET_ASI_EXCP,
@@ -2975,7 +2976,7 @@ static void gen_faligndata(TCGv dst, TCG
 /* before an instruction, dc->pc must be static */
 static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
 {
-    unsigned int opc, rs1, rs2, rd;
+    unsigned int opc, rs1, rs2, rd, xop;
     TCGv cpu_src1, cpu_src2;
     TCGv_i32 cpu_src1_32, cpu_src2_32, cpu_dst_32;
     TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64;
@@ -2987,7 +2988,7 @@ static void disas_sparc_insn(DisasContex
     switch (opc) {
     case 0:                     /* branches/sethi */
         {
-            unsigned int xop = GET_FIELD(insn, 7, 9);
+            xop = GET_FIELD(insn, 7, 9);
             int32_t target;
             switch (xop) {
 #ifdef TARGET_SPARC64
@@ -3089,7 +3090,7 @@ static void disas_sparc_insn(DisasContex
         goto jmp_insn;
     case 2:                     /* FPU & Logical Operations */
         {
-            unsigned int xop = GET_FIELD(insn, 7, 12);
+            xop = GET_FIELD(insn, 7, 12);
             TCGv cpu_dst = tcg_temp_new();
             TCGv cpu_tmp0;
 
@@ -5152,7 +5153,7 @@ static void disas_sparc_insn(DisasContex
         break;
     case 3:                     /* load/store instructions */
         {
-            unsigned int xop = GET_FIELD(insn, 7, 12);
+            xop = GET_FIELD(insn, 7, 12);
             /* ??? gen_address_mask prevents us from using a source
                register directly.  Always generate a temporary.  */
             TCGv cpu_addr = tcg_temp_new();
@@ -5521,7 +5522,7 @@ static void disas_sparc_insn(DisasContex
                 case 0x37: /* stdc */
                     goto ncp_insn;
 #endif
-#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
+//#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
                 case 0x3c: /* V9 or LEON3 casa */
 #ifndef TARGET_SPARC64
                     CHECK_IU_FEATURE(dc, CASA);
@@ -5529,8 +5530,8 @@ static void disas_sparc_insn(DisasContex
                     rs2 = GET_FIELD(insn, 27, 31);
                     cpu_src2 = gen_load_gpr(dc, rs2);
                     gen_cas_asi(dc, cpu_addr, cpu_src2, insn, rd);
+//#endif
                     break;
-#endif
                 default:
                     goto illegal_insn;
                 }
@@ -5555,6 +5556,7 @@ static void disas_sparc_insn(DisasContex
  jmp_insn:
     return;
  illegal_insn:
+    //fprintf(stderr, "II: %08X opc=%02X, xop=%02X\n", insn, opc, xop);
     gen_exception(dc, TT_ILL_INSN);
     return;
  unimp_flush:
