summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--disas/microblaze.c18
-rw-r--r--hw/display/xlnx_dp.c3
-rw-r--r--target/microblaze/cpu.c39
-rw-r--r--target/microblaze/cpu.h7
-rw-r--r--target/microblaze/translate.c77
5 files changed, 96 insertions, 48 deletions
diff --git a/disas/microblaze.c b/disas/microblaze.c
index 7795a0bdb9..598ecbc89d 100644
--- a/disas/microblaze.c
+++ b/disas/microblaze.c
@@ -272,7 +272,7 @@ enum microblaze_instr_type {
 
 #define MAX_OPCODES 280
 
-static struct op_code_struct {
+static const struct op_code_struct {
   const char *name;
   short inst_type; /* registers and immediate values involved */
   short inst_offset_type; /* immediate vals offset from PC? (= 1 for branches) */
@@ -596,10 +596,6 @@ static char * get_field_imm15 (long instr);
 #if 0
 static char * get_field_unsigned_imm (long instr);
 #endif
-char * get_field_special (long instr, struct op_code_struct * op);
-unsigned long read_insn_microblaze (bfd_vma memaddr, 
-		      struct disassemble_info *info,
-		      struct op_code_struct **opr);
 
 static char *
 get_field (long instr, long mask, unsigned short low)
@@ -664,8 +660,8 @@ get_field_unsigned_imm (long instr)
   }
 */
 
-char *
-get_field_special (long instr, struct op_code_struct * op)
+static char *
+get_field_special(long instr, const struct op_code_struct *op)
 {
    char tmpstr[25];
    char spr[6];
@@ -729,14 +725,14 @@ get_field_special (long instr, struct op_code_struct * op)
    return(strdup(tmpstr));
 }
 
-unsigned long
+static unsigned long
 read_insn_microblaze (bfd_vma memaddr, 
 		      struct disassemble_info *info,
-		      struct op_code_struct **opr)
+		      const struct op_code_struct **opr)
 {
   unsigned char       ibytes[4];
   int                 status;
-  struct op_code_struct * op;
+  const struct op_code_struct *op;
   unsigned long inst;
 
   status = info->read_memory_func (memaddr, ibytes, 4, info);
@@ -772,7 +768,7 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
   fprintf_function    fprintf_func = info->fprintf_func;
   void *              stream = info->stream;
   unsigned long       inst, prev_inst;
-  struct op_code_struct * op, *pop;
+  const struct op_code_struct *op, *pop;
   int                 immval = 0;
   bfd_boolean         immfound = FALSE;
   static bfd_vma prev_insn_addr = -1; /*init the prev insn addr */
diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
index f7b7b80c68..a77d7db22f 100644
--- a/hw/display/xlnx_dp.c
+++ b/hw/display/xlnx_dp.c
@@ -624,6 +624,9 @@ static void xlnx_dp_change_graphic_fmt(XlnxDPState *s)
     case 0:
         s->v_plane.format = PIXMAN_x8b8g8r8;
         break;
+    case DP_NL_VID_Y0_CB_Y1_CR:
+        s->v_plane.format = PIXMAN_yuy2;
+        break;
     case DP_NL_VID_RGBA8880:
         s->v_plane.format = PIXMAN_x8b8g8r8;
         break;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 3d58869716..f85ff01b39 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -64,6 +64,10 @@ static const struct {
     {"9.1", 0x1D},
     {"9.2", 0x1F},
     {"9.3", 0x20},
+    {"9.4", 0x21},
+    {"9.5", 0x22},
+    {"9.6", 0x23},
+    {"10.0", 0x24},
     {NULL, 0},
 };
 
@@ -147,23 +151,13 @@ static void mb_cpu_realizefn(DeviceState *dev, Error **errp)
 
     qemu_init_vcpu(cs);
 
-    env->pvr.regs[0] = PVR0_USE_BARREL_MASK \
-                       | PVR0_USE_DIV_MASK \
-                       | PVR0_USE_HW_MUL_MASK \
-                       | PVR0_USE_EXC_MASK \
+    env->pvr.regs[0] = PVR0_USE_EXC_MASK \
                        | PVR0_USE_ICACHE_MASK \
-                       | PVR0_USE_DCACHE_MASK \
-                       | (0xb << 8);
+                       | PVR0_USE_DCACHE_MASK;
     env->pvr.regs[2] = PVR2_D_OPB_MASK \
                         | PVR2_D_LMB_MASK \
                         | PVR2_I_OPB_MASK \
                         | PVR2_I_LMB_MASK \
-                        | PVR2_USE_MSR_INSTR \
-                        | PVR2_USE_PCMP_INSTR \
-                        | PVR2_USE_BARREL_MASK \
-                        | PVR2_USE_DIV_MASK \
-                        | PVR2_USE_HW_MUL_MASK \
-                        | PVR2_USE_MUL64_MASK \
                         | PVR2_FPU_EXC_MASK \
                         | 0;
 
@@ -180,13 +174,22 @@ static void mb_cpu_realizefn(DeviceState *dev, Error **errp)
 
     env->pvr.regs[0] |= (cpu->cfg.stackprot ? PVR0_SPROT_MASK : 0) |
                         (cpu->cfg.use_fpu ? PVR0_USE_FPU_MASK : 0) |
+                        (cpu->cfg.use_hw_mul ? PVR0_USE_HW_MUL_MASK : 0) |
+                        (cpu->cfg.use_barrel ? PVR0_USE_BARREL_MASK : 0) |
+                        (cpu->cfg.use_div ? PVR0_USE_DIV_MASK : 0) |
                         (cpu->cfg.use_mmu ? PVR0_USE_MMU_MASK : 0) |
                         (cpu->cfg.endi ? PVR0_ENDI_MASK : 0) |
-                        (version_code << 16) |
+                        (version_code << PVR0_VERSION_SHIFT) |
                         (cpu->cfg.pvr == C_PVR_FULL ? PVR0_PVR_FULL_MASK : 0);
 
     env->pvr.regs[2] |= (cpu->cfg.use_fpu ? PVR2_USE_FPU_MASK : 0) |
-                        (cpu->cfg.use_fpu > 1 ? PVR2_USE_FPU2_MASK : 0);
+                        (cpu->cfg.use_fpu > 1 ? PVR2_USE_FPU2_MASK : 0) |
+                        (cpu->cfg.use_hw_mul ? PVR2_USE_HW_MUL_MASK : 0) |
+                        (cpu->cfg.use_hw_mul > 1 ? PVR2_USE_MUL64_MASK : 0) |
+                        (cpu->cfg.use_barrel ? PVR2_USE_BARREL_MASK : 0) |
+                        (cpu->cfg.use_div ? PVR2_USE_DIV_MASK : 0) |
+                        (cpu->cfg.use_msr_instr ? PVR2_USE_MSR_INSTR : 0) |
+                        (cpu->cfg.use_pcmp_instr ? PVR2_USE_PCMP_INSTR : 0);
 
     env->pvr.regs[5] |= cpu->cfg.dcache_writeback ?
                                         PVR5_DCACHE_WRITEBACK_MASK : 0;
@@ -233,6 +236,14 @@ static Property mb_properties[] = {
      *                  are enabled
      */
     DEFINE_PROP_UINT8("use-fpu", MicroBlazeCPU, cfg.use_fpu, 2),
+    /* If use-hw-mul > 0 - Multiplier is enabled
+     * If use-hw-mul = 2 - 64-bit multiplier is enabled
+     */
+    DEFINE_PROP_UINT8("use-hw-mul", MicroBlazeCPU, cfg.use_hw_mul, 2),
+    DEFINE_PROP_BOOL("use-barrel", MicroBlazeCPU, cfg.use_barrel, true),
+    DEFINE_PROP_BOOL("use-div", MicroBlazeCPU, cfg.use_div, true),
+    DEFINE_PROP_BOOL("use-msr-instr", MicroBlazeCPU, cfg.use_msr_instr, true),
+    DEFINE_PROP_BOOL("use-pcmp-instr", MicroBlazeCPU, cfg.use_pcmp_instr, true),
     DEFINE_PROP_BOOL("use-mmu", MicroBlazeCPU, cfg.use_mmu, true),
     DEFINE_PROP_BOOL("dcache-writeback", MicroBlazeCPU, cfg.dcache_writeback,
                      false),
diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index bf6963bcb7..5ce4c82657 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -129,6 +129,8 @@ typedef struct CPUMBState CPUMBState;
 #define PVR0_USER1_MASK                 0x000000FF
 #define PVR0_SPROT_MASK                 0x00000001
 
+#define PVR0_VERSION_SHIFT              8
+
 /* User 2 PVR mask */
 #define PVR1_USER2_MASK                 0xFFFFFFFF
 
@@ -296,6 +298,11 @@ struct MicroBlazeCPU {
         bool stackprot;
         uint32_t base_vectors;
         uint8_t use_fpu;
+        uint8_t use_hw_mul;
+        bool use_barrel;
+        bool use_div;
+        bool use_msr_instr;
+        bool use_pcmp_instr;
         bool use_mmu;
         bool dcache_writeback;
         bool endi;
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 0bb609513c..cb65d1e129 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -326,7 +326,7 @@ static void dec_pattern(DisasContext *dc)
 
     if ((dc->tb_flags & MSR_EE_FLAG)
           && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
-          && !((dc->cpu->env.pvr.regs[2] & PVR2_USE_PCMP_INSTR))) {
+          && !dc->cpu->cfg.use_pcmp_instr) {
         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
     }
@@ -443,7 +443,7 @@ static void dec_msr(DisasContext *dc)
         LOG_DIS("msr%s r%d imm=%x\n", clr ? "clr" : "set",
                 dc->rd, dc->imm);
 
-        if (!(dc->cpu->env.pvr.regs[2] & PVR2_USE_MSR_INSTR)) {
+        if (!dc->cpu->cfg.use_msr_instr) {
             /* nop??? */
             return;
         }
@@ -589,7 +589,7 @@ static void dec_mul(DisasContext *dc)
 
     if ((dc->tb_flags & MSR_EE_FLAG)
          && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
-         && !(dc->cpu->env.pvr.regs[0] & PVR0_USE_HW_MUL_MASK)) {
+         && !dc->cpu->cfg.use_hw_mul) {
         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
         return;
@@ -604,8 +604,7 @@ static void dec_mul(DisasContext *dc)
     }
 
     /* mulh, mulhsu and mulhu are not available if C_USE_HW_MUL is < 2.  */
-    if (subcode >= 1 && subcode <= 3
-        && !((dc->cpu->env.pvr.regs[2] & PVR2_USE_MUL64_MASK))) {
+    if (subcode >= 1 && subcode <= 3 && dc->cpu->cfg.use_hw_mul < 2) {
         /* nop??? */
     }
 
@@ -643,7 +642,7 @@ static void dec_div(DisasContext *dc)
     LOG_DIS("div\n");
 
     if ((dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
-          && !((dc->cpu->env.pvr.regs[0] & PVR0_USE_DIV_MASK))) {
+          && !dc->cpu->cfg.use_div) {
         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
     }
@@ -661,34 +660,66 @@ static void dec_div(DisasContext *dc)
 static void dec_barrel(DisasContext *dc)
 {
     TCGv t0;
-    unsigned int s, t;
+    unsigned int imm_w, imm_s;
+    bool s, t, e = false, i = false;
 
     if ((dc->tb_flags & MSR_EE_FLAG)
           && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
-          && !(dc->cpu->env.pvr.regs[0] & PVR0_USE_BARREL_MASK)) {
+          && !dc->cpu->cfg.use_barrel) {
         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
         return;
     }
 
-    s = dc->imm & (1 << 10);
-    t = dc->imm & (1 << 9);
+    if (dc->type_b) {
+        /* Insert and extract are only available in immediate mode.  */
+        i = extract32(dc->imm, 15, 1);
+        e = extract32(dc->imm, 14, 1);
+    }
+    s = extract32(dc->imm, 10, 1);
+    t = extract32(dc->imm, 9, 1);
+    imm_w = extract32(dc->imm, 6, 5);
+    imm_s = extract32(dc->imm, 0, 5);
 
-    LOG_DIS("bs%s%s r%d r%d r%d\n",
+    LOG_DIS("bs%s%s%s r%d r%d r%d\n",
+            e ? "e" : "",
             s ? "l" : "r", t ? "a" : "l", dc->rd, dc->ra, dc->rb);
 
-    t0 = tcg_temp_new();
+    if (e) {
+        if (imm_w + imm_s > 32 || imm_w == 0) {
+            /* These inputs have an undefined behavior.  */
+            qemu_log_mask(LOG_GUEST_ERROR, "bsefi: Bad input w=%d s=%d\n",
+                          imm_w, imm_s);
+        } else {
+            tcg_gen_extract_i32(cpu_R[dc->rd], cpu_R[dc->ra], imm_s, imm_w);
+        }
+    } else if (i) {
+        int width = imm_w - imm_s + 1;
+
+        if (imm_w < imm_s) {
+            /* These inputs have an undefined behavior.  */
+            qemu_log_mask(LOG_GUEST_ERROR, "bsifi: Bad input w=%d s=%d\n",
+                          imm_w, imm_s);
+        } else {
+            tcg_gen_deposit_i32(cpu_R[dc->rd], cpu_R[dc->rd], cpu_R[dc->ra],
+                                imm_s, width);
+        }
+    } else {
+        t0 = tcg_temp_new();
 
-    tcg_gen_mov_tl(t0, *(dec_alu_op_b(dc)));
-    tcg_gen_andi_tl(t0, t0, 31);
+        tcg_gen_mov_tl(t0, *(dec_alu_op_b(dc)));
+        tcg_gen_andi_tl(t0, t0, 31);
 
-    if (s)
-        tcg_gen_shl_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
-    else {
-        if (t)
-            tcg_gen_sar_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
-        else
-            tcg_gen_shr_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
+        if (s) {
+            tcg_gen_shl_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
+        } else {
+            if (t) {
+                tcg_gen_sar_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
+            } else {
+                tcg_gen_shr_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
+            }
+        }
+        tcg_temp_free(t0);
     }
 }
 
@@ -763,11 +794,11 @@ static void dec_bit(DisasContext *dc)
         case 0xe0:
             if ((dc->tb_flags & MSR_EE_FLAG)
                 && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
-                && !((dc->cpu->env.pvr.regs[2] & PVR2_USE_PCMP_INSTR))) {
+                && !dc->cpu->cfg.use_pcmp_instr) {
                 tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
                 t_gen_raise_exception(dc, EXCP_HW_EXCP);
             }
-            if (dc->cpu->env.pvr.regs[2] & PVR2_USE_PCMP_INSTR) {
+            if (dc->cpu->cfg.use_pcmp_instr) {
                 tcg_gen_clzi_i32(cpu_R[dc->rd], cpu_R[dc->ra], 32);
             }
             break;