Commit 2185c93b authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/edgar/tags/edgar/xilinx-next.for-upstream' into staging



edgar/xilinx-next.for-upstream

# gpg: Signature made Tue 04 Jul 2017 10:00:47 BST
# gpg:                using RSA key 0x29C596780F6BCA83
# gpg: Good signature from "Edgar E. Iglesias (Xilinx key) <edgar.iglesias@xilinx.com>"
# gpg:                 aka "Edgar E. Iglesias <edgar.iglesias@gmail.com>"
# Primary key fingerprint: AC44 FEDC 14F7 F1EB EDBF  4151 29C5 9678 0F6B CA83

* remotes/edgar/tags/edgar/xilinx-next.for-upstream:
  xilinx-dp: Add support for the yuy2 video format
  target-microblaze: Add CPU version 10.0
  target-microblaze: dec_barrel: Add BSIFI
  target-microblaze: dec_barrel: Add BSEFI
  target-microblaze: dec_barrel: Plug TCG temp leak
  target-microblaze: dec_barrel: Add braces around if-statements
  target-microblaze: dec_barrel: Use extract32
  target-microblaze: dec_barrel: Use bool instead of unsigned int
  target-microblaze: Introduce a use-pcmp-instr property
  target-microblaze: Introduce a use-msr-instr property
  target-microblaze: Introduce a use-hw-mul property
  target-microblaze: Introduce a use-div property
  target-microblaze: Introduce a use-barrel property
  target-microblaze: Add CPU versions 9.4, 9.5 and 9.6
  target-microblaze: Don't hard code 0xb as initial MB version
  target-microblaze: Correct bit shift for the PVR0 version field
  disas/microblaze: Add missing 'const' attributes

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 0c7a8b9b 31cf950e
Loading
Loading
Loading
Loading
+7 −11
Original line number Diff line number Diff line
@@ -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 */
+3 −0
Original line number Diff line number Diff line
@@ -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;
+25 −14
Original line number Diff line number Diff line
@@ -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),
+7 −0
Original line number Diff line number Diff line
@@ -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;
+54 −23
Original line number Diff line number Diff line
@@ -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,36 +660,68 @@ 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);

    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);

    if (s)
        if (s) {
            tcg_gen_shl_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
    else {
        if (t)
        } else {
            if (t) {
                tcg_gen_sar_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
        else
            } else {
                tcg_gen_shr_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
            }
        }
        tcg_temp_free(t0);
    }
}

static void dec_bit(DisasContext *dc)
{
@@ -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;