static void arm_cpu_realizefn(DeviceState *dev, Error **errp)

{

    CPUState *cs = CPU(dev);

    ARMCPU *cpu = ARM_CPU(dev);

    ARMCPUClass *acc = ARM_CPU_GET_CLASS(dev);

    CPUARMState *env = &cpu->env;

    int pagebits;

    Error *local_err = NULL;

    cpu_exec_realizefn(cs, &local_err);

    if (local_err != NULL) {

        error_propagate(errp, local_err);

        return;

    }

    /* Some features automatically imply others: */

    if (arm_feature(env, ARM_FEATURE_V8)) {

        set_feature(env, ARM_FEATURE_V7);

        set_feature(env, ARM_FEATURE_ARM_DIV);

        set_feature(env, ARM_FEATURE_LPAE);

    }

    if (arm_feature(env, ARM_FEATURE_V7)) {

        set_feature(env, ARM_FEATURE_VAPA);

        set_feature(env, ARM_FEATURE_THUMB2);

        set_feature(env, ARM_FEATURE_MPIDR);

        if (!arm_feature(env, ARM_FEATURE_M)) {

            set_feature(env, ARM_FEATURE_V6K);

        } else {

            set_feature(env, ARM_FEATURE_V6);

        }

        /* Always define VBAR for V7 CPUs even if it doesn't exist in

         * non-EL3 configs. This is needed by some legacy boards.

         */

        set_feature(env, ARM_FEATURE_VBAR);

    }

    if (arm_feature(env, ARM_FEATURE_V6K)) {

        set_feature(env, ARM_FEATURE_V6);

        set_feature(env, ARM_FEATURE_MVFR);

    }

    if (arm_feature(env, ARM_FEATURE_V6)) {

        set_feature(env, ARM_FEATURE_V5);

        if (!arm_feature(env, ARM_FEATURE_M)) {

            set_feature(env, ARM_FEATURE_AUXCR);

        }

    }

    if (arm_feature(env, ARM_FEATURE_V5)) {

        set_feature(env, ARM_FEATURE_V4T);

    }

    if (arm_feature(env, ARM_FEATURE_M)) {

        set_feature(env, ARM_FEATURE_THUMB_DIV);

    }

    if (arm_feature(env, ARM_FEATURE_ARM_DIV)) {

        set_feature(env, ARM_FEATURE_THUMB_DIV);

    }

    if (arm_feature(env, ARM_FEATURE_VFP4)) {

        set_feature(env, ARM_FEATURE_VFP3);

        set_feature(env, ARM_FEATURE_VFP_FP16);

    }

    if (arm_feature(env, ARM_FEATURE_VFP3)) {

        set_feature(env, ARM_FEATURE_VFP);

    }

    if (arm_feature(env, ARM_FEATURE_LPAE)) {

        set_feature(env, ARM_FEATURE_V7MP);

        set_feature(env, ARM_FEATURE_PXN);

    }

    if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {

        set_feature(env, ARM_FEATURE_CBAR);

    }

    if (arm_feature(env, ARM_FEATURE_THUMB2) &&

        !arm_feature(env, ARM_FEATURE_M)) {

        set_feature(env, ARM_FEATURE_THUMB_DSP);

    }

    if (arm_feature(env, ARM_FEATURE_V7) &&

        !arm_feature(env, ARM_FEATURE_M) &&

        !arm_feature(env, ARM_FEATURE_PMSA)) {

        /* v7VMSA drops support for the old ARMv5 tiny pages, so we

         * can use 4K pages.

         */

        pagebits = 12;

    } else {

        /* For CPUs which might have tiny 1K pages, or which have an

         * MPU and might have small region sizes, stick with 1K pages.

         */

        pagebits = 10;

    }

    if (!set_preferred_target_page_bits(pagebits)) {

        /* This can only ever happen for hotplugging a CPU, or if

         * the board code incorrectly creates a CPU which it has

         * promised via minimum_page_size that it will not.

         */

        error_setg(errp, "This CPU requires a smaller page size than the "

                   "system is using");

        return;

    }

    /* This cpu-id-to-MPIDR affinity is used only for TCG; KVM will override it.

     * We don't support setting cluster ID ([16..23]) (known as Aff2

     * in later ARM ARM versions), or any of the higher affinity level fields,

     * so these bits always RAZ.

     */

    if (cpu->mp_affinity == ARM64_AFFINITY_INVALID) {

        cpu->mp_affinity = arm_cpu_mp_affinity(cs->cpu_index,

                                               ARM_DEFAULT_CPUS_PER_CLUSTER);

    }

    if (cpu->reset_hivecs) {

            cpu->reset_sctlr |= (1 << 13);

    }

    if (cpu->cfgend) {

        if (arm_feature(&cpu->env, ARM_FEATURE_V7)) {

            cpu->reset_sctlr |= SCTLR_EE;

        } else {

            cpu->reset_sctlr |= SCTLR_B;

        }

    }

    if (!cpu->has_el3) {

        /* If the has_el3 CPU property is disabled then we need to disable the

         * feature.

         */

        unset_feature(env, ARM_FEATURE_EL3);

        /* Disable the security extension feature bits in the processor feature

         * registers as well. These are id_pfr1[7:4] and id_aa64pfr0[15:12].

         */

        cpu->id_pfr1 &= ~0xf0;

        cpu->id_aa64pfr0 &= ~0xf000;

    }

    if (!cpu->has_el2) {

        unset_feature(env, ARM_FEATURE_EL2);

    }

    if (!cpu->has_pmu) {

        unset_feature(env, ARM_FEATURE_PMU);

        cpu->id_aa64dfr0 &= ~0xf00;

    }

    if (!arm_feature(env, ARM_FEATURE_EL2)) {

        /* Disable the hypervisor feature bits in the processor feature

         * registers if we don't have EL2. These are id_pfr1[15:12] and

         * id_aa64pfr0_el1[11:8].

         */

        cpu->id_aa64pfr0 &= ~0xf00;

        cpu->id_pfr1 &= ~0xf000;

    }

    /* MPU can be configured out of a PMSA CPU either by setting has-mpu

     * to false or by setting pmsav7-dregion to 0.

     */

    if (!cpu->has_mpu) {

        cpu->pmsav7_dregion = 0;

    }

    if (cpu->pmsav7_dregion == 0) {

        cpu->has_mpu = false;

    }

    if (arm_feature(env, ARM_FEATURE_PMSA) &&

        arm_feature(env, ARM_FEATURE_V7)) {

        uint32_t nr = cpu->pmsav7_dregion;

        if (nr > 0xff) {

            error_setg(errp, "PMSAv7 MPU #regions invalid %" PRIu32, nr);

            return;

        }

        if (nr) {

            if (arm_feature(env, ARM_FEATURE_V8)) {

                /* PMSAv8 */

                env->pmsav8.rbar[M_REG_NS] = g_new0(uint32_t, nr);

                env->pmsav8.rlar[M_REG_NS] = g_new0(uint32_t, nr);

                if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {

                    env->pmsav8.rbar[M_REG_S] = g_new0(uint32_t, nr);

                    env->pmsav8.rlar[M_REG_S] = g_new0(uint32_t, nr);

                }

            } else {

                env->pmsav7.drbar = g_new0(uint32_t, nr);

                env->pmsav7.drsr = g_new0(uint32_t, nr);

                env->pmsav7.dracr = g_new0(uint32_t, nr);

            }

        }

    }

    if (arm_feature(env, ARM_FEATURE_EL3)) {

        set_feature(env, ARM_FEATURE_VBAR);

    }

    register_cp_regs_for_features(cpu);

    arm_cpu_register_gdb_regs_for_features(cpu);

    init_cpreg_list(cpu);

#ifndef CONFIG_USER_ONLY

    if (cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY)) {

        AddressSpace *as;

        cs->num_ases = 2;

        if (!cpu->secure_memory) {

            cpu->secure_memory = cs->memory;

        }

        as = address_space_init_shareable(cpu->secure_memory,

                                          "cpu-secure-memory");

        cpu_address_space_init(cs, as, ARMASIdx_S);

    } else {

        cs->num_ases = 1;

    }

    cpu_address_space_init(cs,

                           address_space_init_shareable(cs->memory,

                                                        "cpu-memory"),

                           ARMASIdx_NS);

#endif

    qemu_init_vcpu(cs);

    cpu_reset(cs);

    acc->parent_realize(dev, errp);

}


static void wait_for_serial(const char *side)

{

    char *serialpath = g_strdup_printf("%s/%s", tmpfs, side);

    FILE *serialfile = fopen(serialpath, "r");

    const char *arch = qtest_get_arch();

    int started = (strcmp(side, "src_serial") == 0 &&

                   strcmp(arch, "ppc64") == 0) ? 0 : 1;

    do {

        int readvalue = fgetc(serialfile);

        if (!started) {

            /* SLOF prints its banner before starting test,

             * to ignore it, mark the start of the test with '_',

             * ignore all characters until this marker

             */

            switch (readvalue) {

            case '_':

                started = 1;

                break;

            case EOF:

                fseek(serialfile, 0, SEEK_SET);

                usleep(1000);

                break;

            }

            continue;

        }

        switch (readvalue) {

        case 'A':

            /* Fine */

            break;

        case 'B':

            /* It's alive! */

            fclose(serialfile);

            g_free(serialpath);

            return;

        case EOF:

            started = (strcmp(side, "src_serial") == 0 &&

                       strcmp(arch, "ppc64") == 0) ? 0 : 1;

            fseek(serialfile, 0, SEEK_SET);

            usleep(1000);

            break;

        default:

            fprintf(stderr, "Unexpected %d on %s serial\n", readvalue, side);

            g_assert_not_reached();

        }

    } while (true);

}


static void disas_thumb_insn(CPUARMState *env, DisasContext *s)

{

    uint32_t val, insn, op, rm, rn, rd, shift, cond;

    int32_t offset;

    int i;

    TCGv_i32 tmp;

    TCGv_i32 tmp2;

    TCGv_i32 addr;

    if (s->condexec_mask) {

        cond = s->condexec_cond;

        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */

          s->condlabel = gen_new_label();

          arm_gen_test_cc(cond ^ 1, s->condlabel);

          s->condjmp = 1;

        }

    }

    insn = arm_lduw_code(env, s->pc, s->sctlr_b);

    s->pc += 2;

    switch (insn >> 12) {

    case 0: case 1:

        rd = insn & 7;

        op = (insn >> 11) & 3;

        if (op == 3) {

            /* add/subtract */

            rn = (insn >> 3) & 7;

            tmp = load_reg(s, rn);

            if (insn & (1 << 10)) {

                /* immediate */

                tmp2 = tcg_temp_new_i32();

                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);

            } else {

                /* reg */

                rm = (insn >> 6) & 7;

                tmp2 = load_reg(s, rm);

            }

            if (insn & (1 << 9)) {

                if (s->condexec_mask)

                    tcg_gen_sub_i32(tmp, tmp, tmp2);

                else

                    gen_sub_CC(tmp, tmp, tmp2);

            } else {

                if (s->condexec_mask)

                    tcg_gen_add_i32(tmp, tmp, tmp2);

                else

                    gen_add_CC(tmp, tmp, tmp2);

            }

            tcg_temp_free_i32(tmp2);

            store_reg(s, rd, tmp);

        } else {

            /* shift immediate */

            rm = (insn >> 3) & 7;

            shift = (insn >> 6) & 0x1f;

            tmp = load_reg(s, rm);

            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            store_reg(s, rd, tmp);

        }

        break;

    case 2: case 3:

        /* arithmetic large immediate */

        op = (insn >> 11) & 3;

        rd = (insn >> 8) & 0x7;

        if (op == 0) { /* mov */

            tmp = tcg_temp_new_i32();

            tcg_gen_movi_i32(tmp, insn & 0xff);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            store_reg(s, rd, tmp);

        } else {

            tmp = load_reg(s, rd);

            tmp2 = tcg_temp_new_i32();

            tcg_gen_movi_i32(tmp2, insn & 0xff);

            switch (op) {

            case 1: /* cmp */

                gen_sub_CC(tmp, tmp, tmp2);

                tcg_temp_free_i32(tmp);

                tcg_temp_free_i32(tmp2);

                break;

            case 2: /* add */

                if (s->condexec_mask)

                    tcg_gen_add_i32(tmp, tmp, tmp2);

                else

                    gen_add_CC(tmp, tmp, tmp2);

                tcg_temp_free_i32(tmp2);

                store_reg(s, rd, tmp);

                break;

            case 3: /* sub */

                if (s->condexec_mask)

                    tcg_gen_sub_i32(tmp, tmp, tmp2);

                else

                    gen_sub_CC(tmp, tmp, tmp2);

                tcg_temp_free_i32(tmp2);

                store_reg(s, rd, tmp);

                break;

            }

        }

        break;

    case 4:

        if (insn & (1 << 11)) {

            rd = (insn >> 8) & 7;

            /* load pc-relative.  Bit 1 of PC is ignored.  */

            val = s->pc + 2 + ((insn & 0xff) * 4);

            val &= ~(uint32_t)2;

            addr = tcg_temp_new_i32();

            tcg_gen_movi_i32(addr, val);

            tmp = tcg_temp_new_i32();

            gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),

                               rd | ISSIs16Bit);

            tcg_temp_free_i32(addr);

            store_reg(s, rd, tmp);

            break;

        }

        if (insn & (1 << 10)) {

            /* data processing extended or blx */

            rd = (insn & 7) | ((insn >> 4) & 8);

            rm = (insn >> 3) & 0xf;

            op = (insn >> 8) & 3;

            switch (op) {

            case 0: /* add */

                tmp = load_reg(s, rd);

                tmp2 = load_reg(s, rm);

                tcg_gen_add_i32(tmp, tmp, tmp2);

                tcg_temp_free_i32(tmp2);

                store_reg(s, rd, tmp);

                break;

            case 1: /* cmp */

                tmp = load_reg(s, rd);

                tmp2 = load_reg(s, rm);

                gen_sub_CC(tmp, tmp, tmp2);

                tcg_temp_free_i32(tmp2);

                tcg_temp_free_i32(tmp);

                break;

            case 2: /* mov/cpy */

                tmp = load_reg(s, rm);

                store_reg(s, rd, tmp);

                break;

            case 3:/* branch [and link] exchange thumb register */

                tmp = load_reg(s, rm);

                if (insn & (1 << 7)) {

                    ARCH(5);

                    val = (uint32_t)s->pc | 1;

                    tmp2 = tcg_temp_new_i32();

                    tcg_gen_movi_i32(tmp2, val);

                    store_reg(s, 14, tmp2);

                    gen_bx(s, tmp);

                } else {

                    /* Only BX works as exception-return, not BLX */

                    gen_bx_excret(s, tmp);

                }

                break;

            }

            break;

        }

        /* data processing register */

        rd = insn & 7;

        rm = (insn >> 3) & 7;

        op = (insn >> 6) & 0xf;

        if (op == 2 || op == 3 || op == 4 || op == 7) {

            /* the shift/rotate ops want the operands backwards */

            val = rm;

            rm = rd;

            rd = val;

            val = 1;

        } else {

            val = 0;

        }

        if (op == 9) { /* neg */

            tmp = tcg_temp_new_i32();

            tcg_gen_movi_i32(tmp, 0);

        } else if (op != 0xf) { /* mvn doesn't read its first operand */

            tmp = load_reg(s, rd);

        } else {

            TCGV_UNUSED_I32(tmp);

        }

        tmp2 = load_reg(s, rm);

        switch (op) {

        case 0x0: /* and */

            tcg_gen_and_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0x1: /* eor */

            tcg_gen_xor_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0x2: /* lsl */

            if (s->condexec_mask) {

                gen_shl(tmp2, tmp2, tmp);

            } else {

                gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x3: /* lsr */

            if (s->condexec_mask) {

                gen_shr(tmp2, tmp2, tmp);

            } else {

                gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x4: /* asr */

            if (s->condexec_mask) {

                gen_sar(tmp2, tmp2, tmp);

            } else {

                gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x5: /* adc */

            if (s->condexec_mask) {

                gen_adc(tmp, tmp2);

            } else {

                gen_adc_CC(tmp, tmp, tmp2);

            }

            break;

        case 0x6: /* sbc */

            if (s->condexec_mask) {

                gen_sub_carry(tmp, tmp, tmp2);

            } else {

                gen_sbc_CC(tmp, tmp, tmp2);

            }

            break;

        case 0x7: /* ror */

            if (s->condexec_mask) {

                tcg_gen_andi_i32(tmp, tmp, 0x1f);

                tcg_gen_rotr_i32(tmp2, tmp2, tmp);

            } else {

                gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x8: /* tst */

            tcg_gen_and_i32(tmp, tmp, tmp2);

            gen_logic_CC(tmp);

            rd = 16;

            break;

        case 0x9: /* neg */

            if (s->condexec_mask)

                tcg_gen_neg_i32(tmp, tmp2);

            else

                gen_sub_CC(tmp, tmp, tmp2);

            break;

        case 0xa: /* cmp */

            gen_sub_CC(tmp, tmp, tmp2);

            rd = 16;

            break;

        case 0xb: /* cmn */

            gen_add_CC(tmp, tmp, tmp2);

            rd = 16;

            break;

        case 0xc: /* orr */

            tcg_gen_or_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0xd: /* mul */

            tcg_gen_mul_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0xe: /* bic */

            tcg_gen_andc_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0xf: /* mvn */

            tcg_gen_not_i32(tmp2, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp2);

            val = 1;

            rm = rd;

            break;

        }

        if (rd != 16) {

            if (val) {

                store_reg(s, rm, tmp2);

                if (op != 0xf)

                    tcg_temp_free_i32(tmp);

            } else {

                store_reg(s, rd, tmp);

                tcg_temp_free_i32(tmp2);

            }

        } else {

            tcg_temp_free_i32(tmp);

            tcg_temp_free_i32(tmp2);

        }

        break;

    case 5:

        /* load/store register offset.  */

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        rm = (insn >> 6) & 7;

        op = (insn >> 9) & 7;

        addr = load_reg(s, rn);

        tmp = load_reg(s, rm);

        tcg_gen_add_i32(addr, addr, tmp);

        tcg_temp_free_i32(tmp);

        if (op < 3) { /* store */

            tmp = load_reg(s, rd);

        } else {

            tmp = tcg_temp_new_i32();

        }

        switch (op) {

        case 0: /* str */

            gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);

            break;

        case 1: /* strh */

            gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);

            break;

        case 2: /* strb */

            gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);

            break;

        case 3: /* ldrsb */

            gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);

            break;

        case 4: /* ldr */

            gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);

            break;

        case 5: /* ldrh */

            gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);

            break;

        case 6: /* ldrb */

            gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);

            break;

        case 7: /* ldrsh */

            gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);

            break;

        }

        if (op >= 3) { /* load */

            store_reg(s, rd, tmp);

        } else {

            tcg_temp_free_i32(tmp);

        }

        tcg_temp_free_i32(addr);

        break;

    case 6:

        /* load/store word immediate offset */

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        addr = load_reg(s, rn);

        val = (insn >> 4) & 0x7c;

        tcg_gen_addi_i32(addr, addr, val);

        if (insn & (1 << 11)) {

            /* load */

            tmp = tcg_temp_new_i32();

            gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));

            store_reg(s, rd, tmp);

        } else {

            /* store */

            tmp = load_reg(s, rd);

            gen_aa32_st32(s, tmp, addr, get_mem_index(s));

            tcg_temp_free_i32(tmp);

        }

        tcg_temp_free_i32(addr);

        break;

    case 7:

        /* load/store byte immediate offset */

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        addr = load_reg(s, rn);

        val = (insn >> 6) & 0x1f;

        tcg_gen_addi_i32(addr, addr, val);

        if (insn & (1 << 11)) {

            /* load */

            tmp = tcg_temp_new_i32();

            gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);

            store_reg(s, rd, tmp);

        } else {

            /* store */

            tmp = load_reg(s, rd);

            gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);

            tcg_temp_free_i32(tmp);

        }

        tcg_temp_free_i32(addr);

        break;

    case 8:

        /* load/store halfword immediate offset */

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        addr = load_reg(s, rn);

        val = (insn >> 5) & 0x3e;

        tcg_gen_addi_i32(addr, addr, val);

        if (insn & (1 << 11)) {

            /* load */

            tmp = tcg_temp_new_i32();

            gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);

            store_reg(s, rd, tmp);

        } else {

            /* store */

            tmp = load_reg(s, rd);

            gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);

            tcg_temp_free_i32(tmp);

        }

        tcg_temp_free_i32(addr);

        break;

    case 9:

        /* load/store from stack */

        rd = (insn >> 8) & 7;

        addr = load_reg(s, 13);

        val = (insn & 0xff) * 4;

        tcg_gen_addi_i32(addr, addr, val);

        if (insn & (1 << 11)) {

            /* load */

            tmp = tcg_temp_new_i32();

            gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);

            store_reg(s, rd, tmp);

        } else {

            /* store */

            tmp = load_reg(s, rd);

            gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);

            tcg_temp_free_i32(tmp);

        }

        tcg_temp_free_i32(addr);

        break;

    case 10:

        /* add to high reg */

        rd = (insn >> 8) & 7;

        if (insn & (1 << 11)) {

            /* SP */

            tmp = load_reg(s, 13);

        } else {

            /* PC. bit 1 is ignored.  */

            tmp = tcg_temp_new_i32();

            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);

        }

        val = (insn & 0xff) * 4;

        tcg_gen_addi_i32(tmp, tmp, val);

        store_reg(s, rd, tmp);

        break;

    case 11:

        /* misc */

        op = (insn >> 8) & 0xf;

        switch (op) {

        case 0:

            /* adjust stack pointer */

            tmp = load_reg(s, 13);

            val = (insn & 0x7f) * 4;

            if (insn & (1 << 7))

                val = -(int32_t)val;

            tcg_gen_addi_i32(tmp, tmp, val);

            store_reg(s, 13, tmp);

            break;

        case 2: /* sign/zero extend.  */

            ARCH(6);

            rd = insn & 7;

            rm = (insn >> 3) & 7;

            tmp = load_reg(s, rm);

            switch ((insn >> 6) & 3) {

            case 0: gen_sxth(tmp); break;

            case 1: gen_sxtb(tmp); break;

            case 2: gen_uxth(tmp); break;

            case 3: gen_uxtb(tmp); break;

            }

            store_reg(s, rd, tmp);

            break;

        case 4: case 5: case 0xc: case 0xd:

            /* push/pop */

            addr = load_reg(s, 13);

            if (insn & (1 << 8))

                offset = 4;

            else

                offset = 0;

            for (i = 0; i < 8; i++) {

                if (insn & (1 << i))

                    offset += 4;

            }

            if ((insn & (1 << 11)) == 0) {

                tcg_gen_addi_i32(addr, addr, -offset);

            }

            for (i = 0; i < 8; i++) {

                if (insn & (1 << i)) {

                    if (insn & (1 << 11)) {

                        /* pop */

                        tmp = tcg_temp_new_i32();

                        gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));

                        store_reg(s, i, tmp);

                    } else {

                        /* push */

                        tmp = load_reg(s, i);

                        gen_aa32_st32(s, tmp, addr, get_mem_index(s));

                        tcg_temp_free_i32(tmp);

                    }

                    /* advance to the next address.  */

                    tcg_gen_addi_i32(addr, addr, 4);

                }

            }

            TCGV_UNUSED_I32(tmp);

            if (insn & (1 << 8)) {

                if (insn & (1 << 11)) {

                    /* pop pc */

                    tmp = tcg_temp_new_i32();

                    gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));

                    /* don't set the pc until the rest of the instruction

                       has completed */

                } else {

                    /* push lr */

                    tmp = load_reg(s, 14);

                    gen_aa32_st32(s, tmp, addr, get_mem_index(s));

                    tcg_temp_free_i32(tmp);

                }

                tcg_gen_addi_i32(addr, addr, 4);

            }

            if ((insn & (1 << 11)) == 0) {

                tcg_gen_addi_i32(addr, addr, -offset);

            }

            /* write back the new stack pointer */

            store_reg(s, 13, addr);

            /* set the new PC value */

            if ((insn & 0x0900) == 0x0900) {

                store_reg_from_load(s, 15, tmp);

            }

            break;

        case 1: case 3: case 9: case 11: /* czb */

            rm = insn & 7;

            tmp = load_reg(s, rm);

            s->condlabel = gen_new_label();

            s->condjmp = 1;

            if (insn & (1 << 11))

                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);

            else

                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);

            tcg_temp_free_i32(tmp);

            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;

            val = (uint32_t)s->pc + 2;

            val += offset;

            gen_jmp(s, val);

            break;

        case 15: /* IT, nop-hint.  */

            if ((insn & 0xf) == 0) {

                gen_nop_hint(s, (insn >> 4) & 0xf);

                break;

            }

            /* If Then.  */

            s->condexec_cond = (insn >> 4) & 0xe;

            s->condexec_mask = insn & 0x1f;

            /* No actual code generated for this insn, just setup state.  */

            break;

        case 0xe: /* bkpt */

        {

            int imm8 = extract32(insn, 0, 8);

            ARCH(5);

            gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),

                               default_exception_el(s));

            break;

        }

        case 0xa: /* rev, and hlt */

        {

            int op1 = extract32(insn, 6, 2);

            if (op1 == 2) {

                /* HLT */

                int imm6 = extract32(insn, 0, 6);

                gen_hlt(s, imm6);

                break;

            }

            /* Otherwise this is rev */

            ARCH(6);

            rn = (insn >> 3) & 0x7;

            rd = insn & 0x7;

            tmp = load_reg(s, rn);

            switch (op1) {

            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;

            case 1: gen_rev16(tmp); break;

            case 3: gen_revsh(tmp); break;

            default:

                g_assert_not_reached();

            }

            store_reg(s, rd, tmp);

            break;

        }

        case 6:

            switch ((insn >> 5) & 7) {

            case 2:

                /* setend */

                ARCH(6);

                if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {

                    gen_helper_setend(cpu_env);

                    s->is_jmp = DISAS_UPDATE;

                }

                break;

            case 3:

                /* cps */

                ARCH(6);

                if (IS_USER(s)) {

                    break;

                }

                if (arm_dc_feature(s, ARM_FEATURE_M)) {

                    tmp = tcg_const_i32((insn & (1 << 4)) != 0);

                    /* FAULTMASK */

                    if (insn & 1) {

                        addr = tcg_const_i32(19);

                        gen_helper_v7m_msr(cpu_env, addr, tmp);

                        tcg_temp_free_i32(addr);

                    }

                    /* PRIMASK */

                    if (insn & 2) {

                        addr = tcg_const_i32(16);

                        gen_helper_v7m_msr(cpu_env, addr, tmp);

                        tcg_temp_free_i32(addr);

                    }

                    tcg_temp_free_i32(tmp);

                    gen_lookup_tb(s);

                } else {

                    if (insn & (1 << 4)) {

                        shift = CPSR_A | CPSR_I | CPSR_F;

                    } else {

                        shift = 0;

                    }

                    gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);

                }

                break;

            default:

                goto undef;

            }

            break;

        default:

            goto undef;

        }

        break;

    case 12:

    {

        /* load/store multiple */

        TCGv_i32 loaded_var;

        TCGV_UNUSED_I32(loaded_var);

        rn = (insn >> 8) & 0x7;

        addr = load_reg(s, rn);

        for (i = 0; i < 8; i++) {

            if (insn & (1 << i)) {

                if (insn & (1 << 11)) {

                    /* load */

                    tmp = tcg_temp_new_i32();

                    gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));

                    if (i == rn) {

                        loaded_var = tmp;

                    } else {

                        store_reg(s, i, tmp);

                    }

                } else {

                    /* store */

                    tmp = load_reg(s, i);

                    gen_aa32_st32(s, tmp, addr, get_mem_index(s));

                    tcg_temp_free_i32(tmp);

                }

                /* advance to the next address */

                tcg_gen_addi_i32(addr, addr, 4);

            }

        }

        if ((insn & (1 << rn)) == 0) {

            /* base reg not in list: base register writeback */

            store_reg(s, rn, addr);

        } else {

            /* base reg in list: if load, complete it now */

            if (insn & (1 << 11)) {

                store_reg(s, rn, loaded_var);

            }

            tcg_temp_free_i32(addr);

        }

        break;

    }

    case 13:

        /* conditional branch or swi */

        cond = (insn >> 8) & 0xf;

        if (cond == 0xe)

            goto undef;

        if (cond == 0xf) {

            /* swi */

            gen_set_pc_im(s, s->pc);

            s->svc_imm = extract32(insn, 0, 8);

            s->is_jmp = DISAS_SWI;

            break;

        }

        /* generate a conditional jump to next instruction */

        s->condlabel = gen_new_label();

        arm_gen_test_cc(cond ^ 1, s->condlabel);

        s->condjmp = 1;

        /* jump to the offset */

        val = (uint32_t)s->pc + 2;

        offset = ((int32_t)insn << 24) >> 24;

        val += offset << 1;

        gen_jmp(s, val);

        break;

    case 14:

        if (insn & (1 << 11)) {

            if (disas_thumb2_insn(env, s, insn))

              goto undef32;

            break;

        }

        /* unconditional branch */

        val = (uint32_t)s->pc;

        offset = ((int32_t)insn << 21) >> 21;

        val += (offset << 1) + 2;

        gen_jmp(s, val);

        break;

    case 15:

        if (disas_thumb2_insn(env, s, insn))

            goto undef32;

        break;

    }

    return;

undef32:

    gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),

                       default_exception_el(s));

    return;

illegal_op:

undef:

    gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),

                       default_exception_el(s));

}


static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
                      Error **errp)
{
    IscsiLun *iscsilun = bs->opaque;
    struct iscsi_context *iscsi = NULL;
    struct iscsi_url *iscsi_url = NULL;
    struct scsi_task *task = NULL;
    struct scsi_inquiry_standard *inq = NULL;
    struct scsi_inquiry_supported_pages *inq_vpd;
    char *initiator_name = NULL;
    QemuOpts *opts;
    Error *local_err = NULL;
    const char *filename;
    int i, ret;
    if ((BDRV_SECTOR_SIZE % 512) != 0) {
        error_setg(errp, "iSCSI: Invalid BDRV_SECTOR_SIZE. "
                   "BDRV_SECTOR_SIZE(%lld) is not a multiple "
                   "of 512", BDRV_SECTOR_SIZE);
        return -EINVAL;
    opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
    qemu_opts_absorb_qdict(opts, options, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        ret = -EINVAL;
    filename = qemu_opt_get(opts, "filename");
    iscsi_url = iscsi_parse_full_url(iscsi, filename);
    if (iscsi_url == NULL) {
        error_setg(errp, "Failed to parse URL : %s", filename);
        ret = -EINVAL;
    memset(iscsilun, 0, sizeof(IscsiLun));
    initiator_name = parse_initiator_name(iscsi_url->target);
    iscsi = iscsi_create_context(initiator_name);
    if (iscsi == NULL) {
        error_setg(errp, "iSCSI: Failed to create iSCSI context.");
        ret = -ENOMEM;
    if (iscsi_set_targetname(iscsi, iscsi_url->target)) {
        error_setg(errp, "iSCSI: Failed to set target name.");
        ret = -EINVAL;
    if (iscsi_url->user != NULL) {
        ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,
                                              iscsi_url->passwd);
        if (ret != 0) {
            error_setg(errp, "Failed to set initiator username and password");
            ret = -EINVAL;
    /* check if we got CHAP username/password via the options */
    parse_chap(iscsi, iscsi_url->target, &local_err);
    if (local_err != NULL) {
        error_propagate(errp, local_err);
        ret = -EINVAL;
    if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) {
        error_setg(errp, "iSCSI: Failed to set session type to normal.");
        ret = -EINVAL;
    iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
    /* check if we got HEADER_DIGEST via the options */
    parse_header_digest(iscsi, iscsi_url->target, &local_err);
    if (local_err != NULL) {
        error_propagate(errp, local_err);
        ret = -EINVAL;
    if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
        error_setg(errp, "iSCSI: Failed to connect to LUN : %s",
            iscsi_get_error(iscsi));
        ret = -EINVAL;
    iscsilun->iscsi = iscsi;
    iscsilun->aio_context = bdrv_get_aio_context(bs);
    iscsilun->lun   = iscsi_url->lun;
    iscsilun->has_write_same = true;
    task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 0, 0,
                            (void **) &inq, errp);
    if (task == NULL) {
        ret = -EINVAL;
    iscsilun->type = inq->periperal_device_type;
    scsi_free_scsi_task(task);
    task = NULL;
    iscsi_readcapacity_sync(iscsilun, &local_err);
    if (local_err != NULL) {
        error_propagate(errp, local_err);
        ret = -EINVAL;
    bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun);
    bs->request_alignment = iscsilun->block_size;
    /* We don't have any emulation for devices other than disks and CD-ROMs, so
     * this must be sg ioctl compatible. We force it to be sg, otherwise qemu
     * will try to read from the device to guess the image format.
     */
    if (iscsilun->type != TYPE_DISK && iscsilun->type != TYPE_ROM) {
        bs->sg = 1;
    task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
                            SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES,
                            (void **) &inq_vpd, errp);
    if (task == NULL) {
        ret = -EINVAL;
    for (i = 0; i < inq_vpd->num_pages; i++) {
        struct scsi_task *inq_task;
        struct scsi_inquiry_logical_block_provisioning *inq_lbp;
        struct scsi_inquiry_block_limits *inq_bl;
        switch (inq_vpd->pages[i]) {
        case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING:
            inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
                                        SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING,
                                        (void **) &inq_lbp, errp);
            if (inq_task == NULL) {
                ret = -EINVAL;
            memcpy(&iscsilun->lbp, inq_lbp,
                   sizeof(struct scsi_inquiry_logical_block_provisioning));
            scsi_free_scsi_task(inq_task);
            break;
        case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS:
            inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
                                    SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS,
                                    (void **) &inq_bl, errp);
            if (inq_task == NULL) {
                ret = -EINVAL;
            memcpy(&iscsilun->bl, inq_bl,
                   sizeof(struct scsi_inquiry_block_limits));
            scsi_free_scsi_task(inq_task);
            break;
        default:
            break;
    scsi_free_scsi_task(task);
    task = NULL;
    iscsi_attach_aio_context(bs, iscsilun->aio_context);
    /* Guess the internal cluster (page) size of the iscsi target by the means
     * of opt_unmap_gran. Transfer the unmap granularity only if it has a
     * reasonable size */
    if (iscsilun->bl.opt_unmap_gran * iscsilun->block_size >= 4 * 1024 &&
        iscsilun->bl.opt_unmap_gran * iscsilun->block_size <= 16 * 1024 * 1024) {
        iscsilun->cluster_sectors = (iscsilun->bl.opt_unmap_gran *
                                     iscsilun->block_size) >> BDRV_SECTOR_BITS;
        if (iscsilun->lbprz && !(bs->open_flags & BDRV_O_NOCACHE)) {
            iscsilun->allocationmap = iscsi_allocationmap_init(iscsilun);
            if (iscsilun->allocationmap == NULL) {
                ret = -ENOMEM;
out:
    qemu_opts_del(opts);
    g_free(initiator_name);
    if (iscsi_url != NULL) {
        iscsi_destroy_url(iscsi_url);
    if (task != NULL) {
        scsi_free_scsi_task(task);
    if (ret) {
        if (iscsi != NULL) {
            iscsi_destroy_context(iscsi);
        memset(iscsilun, 0, sizeof(IscsiLun));
    return ret;


static inline void FUNC(idctSparseCol_extrashift)(int16_t *col)

#else

static inline void FUNC(idctSparseColPut)(pixel *dest, int line_size,

                                          int16_t *col)

{

    int a0, a1, a2, a3, b0, b1, b2, b3;

    IDCT_COLS;

    dest[0] = av_clip_pixel((a0 + b0) >> COL_SHIFT);

    dest += line_size;

    dest[0] = av_clip_pixel((a1 + b1) >> COL_SHIFT);

    dest += line_size;

    dest[0] = av_clip_pixel((a2 + b2) >> COL_SHIFT);

    dest += line_size;

    dest[0] = av_clip_pixel((a3 + b3) >> COL_SHIFT);

    dest += line_size;

    dest[0] = av_clip_pixel((a3 - b3) >> COL_SHIFT);

    dest += line_size;

    dest[0] = av_clip_pixel((a2 - b2) >> COL_SHIFT);

    dest += line_size;

    dest[0] = av_clip_pixel((a1 - b1) >> COL_SHIFT);

    dest += line_size;

    dest[0] = av_clip_pixel((a0 - b0) >> COL_SHIFT);

}

static inline void FUNC(idctSparseColAdd)(pixel *dest, int line_size,

                                          int16_t *col)

{

    int a0, a1, a2, a3, b0, b1, b2, b3;

    IDCT_COLS;

    dest[0] = av_clip_pixel(dest[0] + ((a0 + b0) >> COL_SHIFT));

    dest += line_size;

    dest[0] = av_clip_pixel(dest[0] + ((a1 + b1) >> COL_SHIFT));

    dest += line_size;

    dest[0] = av_clip_pixel(dest[0] + ((a2 + b2) >> COL_SHIFT));

    dest += line_size;

    dest[0] = av_clip_pixel(dest[0] + ((a3 + b3) >> COL_SHIFT));

    dest += line_size;

    dest[0] = av_clip_pixel(dest[0] + ((a3 - b3) >> COL_SHIFT));

    dest += line_size;

    dest[0] = av_clip_pixel(dest[0] + ((a2 - b2) >> COL_SHIFT));

    dest += line_size;

    dest[0] = av_clip_pixel(dest[0] + ((a1 - b1) >> COL_SHIFT));

    dest += line_size;

    dest[0] = av_clip_pixel(dest[0] + ((a0 - b0) >> COL_SHIFT));

}

static inline void FUNC(idctSparseCol)(int16_t *col)

#endif

{

    int a0, a1, a2, a3, b0, b1, b2, b3;

    IDCT_COLS;

    col[0 ] = ((a0 + b0) >> COL_SHIFT);

    col[8 ] = ((a1 + b1) >> COL_SHIFT);

    col[16] = ((a2 + b2) >> COL_SHIFT);

    col[24] = ((a3 + b3) >> COL_SHIFT);

    col[32] = ((a3 - b3) >> COL_SHIFT);

    col[40] = ((a2 - b2) >> COL_SHIFT);

    col[48] = ((a1 - b1) >> COL_SHIFT);

    col[56] = ((a0 - b0) >> COL_SHIFT);

}


static void restore_median(uint8_t *src, int step, int stride,

                           int width, int height, int slices, int rmode)

{

    int i, j, slice;

    int A, B, C;

    uint8_t *bsrc;

    int slice_start, slice_height;

    const int cmask = ~rmode;

    for (slice = 0; slice < slices; slice++) {

        slice_start  = ((slice * height) / slices) & cmask;

        slice_height = ((((slice + 1) * height) / slices) & cmask) -

                       slice_start;

        bsrc = src + slice_start * stride;

        // first line - left neighbour prediction

        bsrc[0] += 0x80;

        A = bsrc[0];

        for (i = step; i < width * step; i += step) {

            bsrc[i] += A;

            A        = bsrc[i];

        }

        bsrc += stride;

        if (slice_height == 1)

        // second line - first element has top prediction, the rest uses median

        C        = bsrc[-stride];

        bsrc[0] += C;

        A        = bsrc[0];

        for (i = step; i < width * step; i += step) {

            B        = bsrc[i - stride];

            bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));

            C        = B;

            A        = bsrc[i];

        }

        bsrc += stride;

        // the rest of lines use continuous median prediction

        for (j = 2; j < slice_height; j++) {

            for (i = 0; i < width * step; i += step) {

                B        = bsrc[i - stride];

                bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));

                C        = B;

                A        = bsrc[i];

            }

            bsrc += stride;

        }

    }

}


static int decode_seq_header(AVSContext *h) {

    MpegEncContext *s = &h->s;

    int frame_rate_code;

    h->profile =         get_bits(&s->gb,8);

    h->level =           get_bits(&s->gb,8);

    skip_bits1(&s->gb); //progressive sequence

    s->width =           get_bits(&s->gb,14);

    s->height =          get_bits(&s->gb,14);

    skip_bits(&s->gb,2); //chroma format

    skip_bits(&s->gb,3); //sample_precision

    h->aspect_ratio =    get_bits(&s->gb,4);

    frame_rate_code =    get_bits(&s->gb,4);

    skip_bits(&s->gb,18);//bit_rate_lower

    skip_bits1(&s->gb);  //marker_bit

    skip_bits(&s->gb,12);//bit_rate_upper

    s->low_delay =       get_bits1(&s->gb);

    h->mb_width  = (s->width  + 15) >> 4;

    h->mb_height = (s->height + 15) >> 4;

    h->s.avctx->time_base.den = avpriv_frame_rate_tab[frame_rate_code].num;

    h->s.avctx->time_base.num = avpriv_frame_rate_tab[frame_rate_code].den;

    h->s.avctx->width  = s->width;

    h->s.avctx->height = s->height;

    if(!h->top_qp)

        ff_cavs_init_top_lines(h);

    return 0;

}


int ff_mpeg_er_init(MpegEncContext *s)

{

    ERContext *er = &s->er;

    int mb_array_size = s->mb_height * s->mb_stride;

    int i;

    er->avctx       = s->avctx;

    er->mb_index2xy = s->mb_index2xy;

    er->mb_num      = s->mb_num;

    er->mb_width    = s->mb_width;

    er->mb_height   = s->mb_height;

    er->mb_stride   = s->mb_stride;

    er->b8_stride   = s->b8_stride;

    er->er_temp_buffer     = av_malloc(s->mb_height * s->mb_stride);

    er->error_status_table = av_mallocz(mb_array_size);

    if (!er->er_temp_buffer || !er->error_status_table)

        goto fail;

    er->mbskip_table  = s->mbskip_table;

    er->mbintra_table = s->mbintra_table;

    for (i = 0; i < FF_ARRAY_ELEMS(s->dc_val); i++)

        er->dc_val[i] = s->dc_val[i];

    er->decode_mb = mpeg_er_decode_mb;

    er->opaque    = s;

    return 0;

fail:

    av_freep(&er->er_temp_buffer);

    av_freep(&er->error_status_table);

    return AVERROR(ENOMEM);

}


static target_ulong remove_hpte(CPUPPCState *env, target_ulong ptex,

                                target_ulong avpn,

                                target_ulong flags,

                                target_ulong *vp, target_ulong *rp)

{

    uint8_t *hpte;

    target_ulong v, r, rb;

    if ((ptex * HASH_PTE_SIZE_64) & ~env->htab_mask) {

        return REMOVE_PARM;

    }

    hpte = env->external_htab + (ptex * HASH_PTE_SIZE_64);

    while (!lock_hpte(hpte, HPTE_V_HVLOCK)) {

        /* We have no real concurrency in qemu soft-emulation, so we

         * will never actually have a contested lock */

        assert(0);

    }

    v = ldq_p(hpte);

    r = ldq_p(hpte + (HASH_PTE_SIZE_64/2));

    if ((v & HPTE_V_VALID) == 0 ||

        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn) ||

        ((flags & H_ANDCOND) && (v & avpn) != 0)) {

        stq_p(hpte, v & ~HPTE_V_HVLOCK);

        assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));

        return REMOVE_NOT_FOUND;

    }

    *vp = v & ~HPTE_V_HVLOCK;

    *rp = r;

    stq_p(hpte, 0);

    rb = compute_tlbie_rb(v, r, ptex);

    ppc_tlb_invalidate_one(env, rb);

    assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));

    return REMOVE_SUCCESS;

}


SerialState *serial_init(int base, qemu_irq irq, int baudbase,

                         CharDriverState *chr)

{

    SerialState *s;

    s = qemu_mallocz(sizeof(SerialState));

    if (!s)

        return NULL;

    s->irq = irq;

    s->baudbase = baudbase;

    s->tx_timer = qemu_new_timer(vm_clock, serial_tx_done, s);

    if (!s->tx_timer)

        return NULL;

    qemu_register_reset(serial_reset, s);

    serial_reset(s);

    register_savevm("serial", base, 2, serial_save, serial_load, s);

    register_ioport_write(base, 8, 1, serial_ioport_write, s);

    register_ioport_read(base, 8, 1, serial_ioport_read, s);

    s->chr = chr;

    qemu_chr_add_handlers(chr, serial_can_receive1, serial_receive1,

                          serial_event, s);

    return s;

}


static void kvmclock_class_init(ObjectClass *klass, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = kvmclock_realize;

    dc->vmsd = &kvmclock_vmsd;

    dc->props = kvmclock_properties;

}


int vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContext *gb)

{

    int i;

    av_log(avctx, AV_LOG_DEBUG, "Entry point: %08X\n", show_bits_long(gb, 32));

    v->broken_link = get_bits1(gb);

    v->closed_entry = get_bits1(gb);

    v->panscanflag = get_bits1(gb);

    v->refdist_flag = get_bits1(gb);

    v->s.loop_filter = get_bits1(gb);

    v->fastuvmc = get_bits1(gb);

    v->extended_mv = get_bits1(gb);

    v->dquant = get_bits(gb, 2);

    v->vstransform = get_bits1(gb);

    v->overlap = get_bits1(gb);

    v->quantizer_mode = get_bits(gb, 2);

    if(v->hrd_param_flag){

        for(i = 0; i < v->hrd_num_leaky_buckets; i++) {

            skip_bits(gb, 8); //hrd_full[n]

        }

    }

    if(get_bits1(gb)){

        avctx->coded_width = (get_bits(gb, 12)+1)<<1;

        avctx->coded_height = (get_bits(gb, 12)+1)<<1;

    }

    if(v->extended_mv)

        v->extended_dmv = get_bits1(gb);

    if((v->range_mapy_flag = get_bits1(gb))) {

        av_log(avctx, AV_LOG_ERROR, "Luma scaling is not supported, expect wrong picture\n");

        v->range_mapy = get_bits(gb, 3);

    }

    if((v->range_mapuv_flag = get_bits1(gb))) {

        av_log(avctx, AV_LOG_ERROR, "Chroma scaling is not supported, expect wrong picture\n");

        v->range_mapuv = get_bits(gb, 3);

    }

    av_log(avctx, AV_LOG_DEBUG, "Entry point info:\n"

        "BrokenLink=%i, ClosedEntry=%i, PanscanFlag=%i\n"

        "RefDist=%i, Postproc=%i, FastUVMC=%i, ExtMV=%i\n"

        "DQuant=%i, VSTransform=%i, Overlap=%i, Qmode=%i\n",

        v->broken_link, v->closed_entry, v->panscanflag, v->refdist_flag, v->s.loop_filter,

        v->fastuvmc, v->extended_mv, v->dquant, v->vstransform, v->overlap, v->quantizer_mode);

    return 0;

}


static inline void RENAME(bgr24ToUV_half)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, int width, uint32_t *unused)

{

    int i;

    for (i=0; i<width; i++) {

        int b= src1[6*i + 0] + src1[6*i + 3];

        int g= src1[6*i + 1] + src1[6*i + 4];

        int r= src1[6*i + 2] + src1[6*i + 5];

        dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);

        dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);

    }

    assert(src1 == src2);

}


static int64_t guest_file_handle_add(FILE *fh, Error **errp)

{

    GuestFileHandle *gfh;

    int64_t handle;

    handle = ga_get_fd_handle(ga_state, errp);

    if (handle < 0) {

        return -1;

    }

    gfh = g_malloc0(sizeof(GuestFileHandle));

    gfh->id = handle;

    gfh->fh = fh;

    QTAILQ_INSERT_TAIL(&guest_file_state.filehandles, gfh, next);

    return handle;

}


static inline void cpu_handle_interrupt(CPUState *cpu,

                                        TranslationBlock **last_tb)

{

    CPUClass *cc = CPU_GET_CLASS(cpu);

    int interrupt_request = cpu->interrupt_request;

    if (unlikely(interrupt_request)) {

        if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) {

            /* Mask out external interrupts for this step. */

            interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;

        }

        if (interrupt_request & CPU_INTERRUPT_DEBUG) {

            cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG;

            cpu->exception_index = EXCP_DEBUG;

            cpu_loop_exit(cpu);

        }

        if (replay_mode == REPLAY_MODE_PLAY && !replay_has_interrupt()) {

            /* Do nothing */

        } else if (interrupt_request & CPU_INTERRUPT_HALT) {

            replay_interrupt();

            cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;

            cpu->halted = 1;

            cpu->exception_index = EXCP_HLT;

            cpu_loop_exit(cpu);

        }

#if defined(TARGET_I386)

        else if (interrupt_request & CPU_INTERRUPT_INIT) {

            X86CPU *x86_cpu = X86_CPU(cpu);

            CPUArchState *env = &x86_cpu->env;

            replay_interrupt();

            cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0);

            do_cpu_init(x86_cpu);

            cpu->exception_index = EXCP_HALTED;

            cpu_loop_exit(cpu);

        }

#else

        else if (interrupt_request & CPU_INTERRUPT_RESET) {

            replay_interrupt();

            cpu_reset(cpu);

            cpu_loop_exit(cpu);

        }

#endif

        /* The target hook has 3 exit conditions:

           False when the interrupt isn't processed,

           True when it is, and we should restart on a new TB,

           and via longjmp via cpu_loop_exit.  */

        else {

            replay_interrupt();

            if (cc->cpu_exec_interrupt(cpu, interrupt_request)) {

                *last_tb = NULL;

            }

            /* The target hook may have updated the 'cpu->interrupt_request';

             * reload the 'interrupt_request' value */

            interrupt_request = cpu->interrupt_request;

        }

        if (interrupt_request & CPU_INTERRUPT_EXITTB) {

            cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB;

            /* ensure that no TB jump will be modified as

               the program flow was changed */

            *last_tb = NULL;

        }

    }

    if (unlikely(atomic_read(&cpu->exit_request) || replay_has_interrupt())) {

        atomic_set(&cpu->exit_request, 0);

        cpu->exception_index = EXCP_INTERRUPT;

        cpu_loop_exit(cpu);

    }

}


static void test_redirector_tx(void)

{

    int backend_sock[2], recv_sock;

    char *cmdline;

    uint32_t ret = 0, len = 0;

    char send_buf[] = "Hello!!";

    char sock_path0[] = "filter-redirector0.XXXXXX";

    char sock_path1[] = "filter-redirector1.XXXXXX";

    char *recv_buf;

    uint32_t size = sizeof(send_buf);

    size = htonl(size);

    ret = socketpair(PF_UNIX, SOCK_STREAM, 0, backend_sock);

    g_assert_cmpint(ret, !=, -1);

    ret = mkstemp(sock_path0);

    g_assert_cmpint(ret, !=, -1);

    ret = mkstemp(sock_path1);

    g_assert_cmpint(ret, !=, -1);

    cmdline = g_strdup_printf("-netdev socket,id=qtest-bn0,fd=%d "

                "-device rtl8139,netdev=qtest-bn0,id=qtest-e0 "

                "-chardev socket,id=redirector0,path=%s,server,nowait "

                "-chardev socket,id=redirector1,path=%s,server,nowait "

                "-chardev socket,id=redirector2,path=%s,nowait "

                "-object filter-redirector,id=qtest-f0,netdev=qtest-bn0,"

                "queue=tx,outdev=redirector0 "

                "-object filter-redirector,id=qtest-f1,netdev=qtest-bn0,"

                "queue=tx,indev=redirector2 "

                "-object filter-redirector,id=qtest-f2,netdev=qtest-bn0,"

                "queue=tx,outdev=redirector1 "

                , backend_sock[1], sock_path0, sock_path1, sock_path0);

    qtest_start(cmdline);

    g_free(cmdline);

    recv_sock = unix_connect(sock_path1, NULL);

    g_assert_cmpint(recv_sock, !=, -1);

    /* send a qmp command to guarantee that 'connected' is setting to true. */

    qmp_discard_response("{ 'execute' : 'query-status'}");

    struct iovec iov[] = {

        {

            .iov_base = &size,

            .iov_len = sizeof(size),

        }, {

            .iov_base = send_buf,

            .iov_len = sizeof(send_buf),

        },

    };

    ret = iov_send(backend_sock[0], iov, 2, 0, sizeof(size) + sizeof(send_buf));

    g_assert_cmpint(ret, ==, sizeof(send_buf) + sizeof(size));

    close(backend_sock[0]);

    ret = qemu_recv(recv_sock, &len, sizeof(len), 0);

    g_assert_cmpint(ret, ==, sizeof(len));

    len = ntohl(len);

    g_assert_cmpint(len, ==, sizeof(send_buf));

    recv_buf = g_malloc(len);

    ret = qemu_recv(recv_sock, recv_buf, len, 0);

    g_assert_cmpstr(recv_buf, ==, send_buf);

    g_free(recv_buf);

    close(recv_sock);

    unlink(sock_path0);

    unlink(sock_path1);

    qtest_end();

}


int acpi_table_add(const char *t)

{

    static const char *dfl_id = "QEMUQEMU";

    char buf[1024], *p, *f;

    struct acpi_table_header acpi_hdr;

    unsigned long val;

    uint32_t length;

    struct acpi_table_header *acpi_hdr_p;

    size_t off;

    memset(&acpi_hdr, 0, sizeof(acpi_hdr));

    if (get_param_value(buf, sizeof(buf), "sig", t)) {

        strncpy(acpi_hdr.signature, buf, 4);

    } else {

        strncpy(acpi_hdr.signature, dfl_id, 4);

    }

    if (get_param_value(buf, sizeof(buf), "rev", t)) {

        val = strtoul(buf, &p, 10);

        if (val > 255 || *p != '\0')

            goto out;

    } else {

        val = 1;

    }

    acpi_hdr.revision = (int8_t)val;

    if (get_param_value(buf, sizeof(buf), "oem_id", t)) {

        strncpy(acpi_hdr.oem_id, buf, 6);

    } else {

        strncpy(acpi_hdr.oem_id, dfl_id, 6);

    }

    if (get_param_value(buf, sizeof(buf), "oem_table_id", t)) {

        strncpy(acpi_hdr.oem_table_id, buf, 8);

    } else {

        strncpy(acpi_hdr.oem_table_id, dfl_id, 8);

    }

    if (get_param_value(buf, sizeof(buf), "oem_rev", t)) {

        val = strtol(buf, &p, 10);

        if(*p != '\0')

            goto out;

    } else {

        val = 1;

    }

    acpi_hdr.oem_revision = cpu_to_le32(val);

    if (get_param_value(buf, sizeof(buf), "asl_compiler_id", t)) {

        strncpy(acpi_hdr.asl_compiler_id, buf, 4);

    } else {

        strncpy(acpi_hdr.asl_compiler_id, dfl_id, 4);

    }

    if (get_param_value(buf, sizeof(buf), "asl_compiler_rev", t)) {

        val = strtol(buf, &p, 10);

        if(*p != '\0')

            goto out;

    } else {

        val = 1;

    }

    acpi_hdr.asl_compiler_revision = cpu_to_le32(val);

    if (!get_param_value(buf, sizeof(buf), "data", t)) {

         buf[0] = '\0';

    }

    length = sizeof(acpi_hdr);

    f = buf;

    while (buf[0]) {

        struct stat s;

        char *n = strchr(f, ':');

        if (n)

            *n = '\0';

        if(stat(f, &s) < 0) {

            fprintf(stderr, "Can't stat file '%s': %s\n", f, strerror(errno));

            goto out;

        }

        length += s.st_size;

        if (!n)

            break;

        *n = ':';

        f = n + 1;

    }

    if (!acpi_tables) {

        acpi_tables_len = sizeof(uint16_t);

        acpi_tables = qemu_mallocz(acpi_tables_len);

    }

    acpi_tables = qemu_realloc(acpi_tables,

                               acpi_tables_len + sizeof(uint16_t) + length);

    p = acpi_tables + acpi_tables_len;

    acpi_tables_len += sizeof(uint16_t) + length;

    *(uint16_t*)p = cpu_to_le32(length);

    p += sizeof(uint16_t);

    memcpy(p, &acpi_hdr, sizeof(acpi_hdr));

    off = sizeof(acpi_hdr);

    f = buf;

    while (buf[0]) {

        struct stat s;

        int fd;

        char *n = strchr(f, ':');

        if (n)

            *n = '\0';

        fd = open(f, O_RDONLY);

        if(fd < 0)

            goto out;

        if(fstat(fd, &s) < 0) {

            close(fd);

            goto out;

        }

        /* off < length is necessary because file size can be changed

           under our foot */

        while(s.st_size && off < length) {

            int r;

            r = read(fd, p + off, s.st_size);

            if (r > 0) {

                off += r;

                s.st_size -= r;

            } else if ((r < 0 && errno != EINTR) || r == 0) {

                close(fd);

                goto out;

            }

        }

        close(fd);

        if (!n)

            break;

        f = n + 1;

    }

    if (off < length) {

        /* don't pass random value in process to guest */

        memset(p + off, 0, length - off);

    }

    acpi_hdr_p = (struct acpi_table_header*)p;

    acpi_hdr_p->length = cpu_to_le32(length);

    acpi_hdr_p->checksum = acpi_checksum((uint8_t*)p, length);

    /* increase number of tables */

    (*(uint16_t*)acpi_tables) =

	    cpu_to_le32(le32_to_cpu(*(uint16_t*)acpi_tables) + 1);

    return 0;

out:

    if (acpi_tables) {

        qemu_free(acpi_tables);

        acpi_tables = NULL;

    }

    return -1;

}


static void armv7m_nvic_class_init(ObjectClass *klass, void *data)

{

    NVICClass *nc = NVIC_CLASS(klass);

    DeviceClass *dc = DEVICE_CLASS(klass);

    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);

    nc->parent_reset = dc->reset;

    nc->parent_init = sdc->init;

    sdc->init = armv7m_nvic_init;

    dc->vmsd  = &vmstate_nvic;

    dc->reset = armv7m_nvic_reset;

    dc->props = armv7m_nvic_properties;

}


static int ehci_qh_do_overlay(EHCIQueue *q)

{

    int i;

    int dtoggle;

    int ping;

    int eps;

    int reload;

    // remember values in fields to preserve in qh after overlay

    dtoggle = q->qh.token & QTD_TOKEN_DTOGGLE;

    ping    = q->qh.token & QTD_TOKEN_PING;

    q->qh.current_qtd = q->qtdaddr;

    q->qh.next_qtd    = q->qtd.next;

    q->qh.altnext_qtd = q->qtd.altnext;

    q->qh.token       = q->qtd.token;

    eps = get_field(q->qh.epchar, QH_EPCHAR_EPS);

    if (eps == EHCI_QH_EPS_HIGH) {

        q->qh.token &= ~QTD_TOKEN_PING;

        q->qh.token |= ping;

    }

    reload = get_field(q->qh.epchar, QH_EPCHAR_RL);

    set_field(&q->qh.altnext_qtd, reload, QH_ALTNEXT_NAKCNT);

    for (i = 0; i < 5; i++) {

        q->qh.bufptr[i] = q->qtd.bufptr[i];

    }

    if (!(q->qh.epchar & QH_EPCHAR_DTC)) {

        // preserve QH DT bit

        q->qh.token &= ~QTD_TOKEN_DTOGGLE;

        q->qh.token |= dtoggle;

    }

    q->qh.bufptr[1] &= ~BUFPTR_CPROGMASK_MASK;

    q->qh.bufptr[2] &= ~BUFPTR_FRAMETAG_MASK;

    put_dwords(NLPTR_GET(q->qhaddr), (uint32_t *) &q->qh, sizeof(EHCIqh) >> 2);

    return 0;

}


static uint32_t intel_hda_mmio_readw(void *opaque, target_phys_addr_t addr)

{

    IntelHDAState *d = opaque;

    const IntelHDAReg *reg = intel_hda_reg_find(d, addr);

    return intel_hda_reg_read(d, reg, 0xffff);

}


static void rtas_ibm_read_pci_config(sPAPREnvironment *spapr,

                                     uint32_t token, uint32_t nargs,

                                     target_ulong args,

                                     uint32_t nret, target_ulong rets)

{

    uint64_t buid;

    uint32_t size, addr;

    if ((nargs != 4) || (nret != 2)) {

        rtas_st(rets, 0, -1);

        return;

    }

    buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);

    size = rtas_ld(args, 3);

    addr = rtas_ld(args, 0);

    finish_read_pci_config(spapr, buid, addr, size, rets);

}


static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)

{

    Object *pci_host;

    QObject *o;

    pci_host = acpi_get_i386_pci_host();

    g_assert(pci_host);

    o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_BASE, NULL);

    if (!o) {

        return false;

    }

    mcfg->mcfg_base = qnum_get_int(qobject_to_qnum(o));

    qobject_decref(o);

    o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL);

    assert(o);

    mcfg->mcfg_size = qnum_get_int(qobject_to_qnum(o));

    qobject_decref(o);

    return true;

}


static void unassigned_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)

{

#ifdef DEBUG_UNASSIGNED

    printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);

#endif

#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)

    do_unassigned_access(addr, 1, 0, 0, 4);

#endif

}


void sparc64_get_context(CPUSPARCState *env)

{

    abi_ulong ucp_addr;

    struct target_ucontext *ucp;

    target_mc_gregset_t *grp;

    target_mcontext_t *mcp;

    abi_ulong fp, i7, w_addr;

    int err;

    unsigned int i;

    target_sigset_t target_set;

    sigset_t set;

    ucp_addr = env->regwptr[UREG_I0];

    if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))

        goto do_sigsegv;

    mcp = &ucp->tuc_mcontext;

    grp = &mcp->mc_gregs;

    /* Skip over the trap instruction, first. */

    env->pc = env->npc;

    env->npc += 4;

    err = 0;

    sigprocmask(0, NULL, &set);

    host_to_target_sigset_internal(&target_set, &set);

    if (TARGET_NSIG_WORDS == 1) {

        err |= __put_user(target_set.sig[0],

                          (abi_ulong *)&ucp->tuc_sigmask);

    } else {

        abi_ulong *src, *dst;

        src = target_set.sig;

        dst = ucp->tuc_sigmask.sig;

        for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {

            err |= __put_user(*src, dst);

        }

        if (err)

            goto do_sigsegv;

    }

    /* XXX: tstate must be saved properly */

    //    err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));

    err |= __put_user(env->pc, &((*grp)[MC_PC]));

    err |= __put_user(env->npc, &((*grp)[MC_NPC]));

    err |= __put_user(env->y, &((*grp)[MC_Y]));

    err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));

    err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));

    err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));

    err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));

    err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));

    err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));

    err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));

    err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));

    err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));

    err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));

    err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));

    err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));

    err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));

    err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));

    err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));

    w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];

    fp = i7 = 0;

    if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),

                 abi_ulong) != 0)

        goto do_sigsegv;

    if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),

                 abi_ulong) != 0)

        goto do_sigsegv;

    err |= __put_user(fp, &(mcp->mc_fp));

    err |= __put_user(i7, &(mcp->mc_i7));

    {

        uint32_t *dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;

        for (i = 0; i < 64; i++, dst++) {

            if (i & 1) {

                err |= __put_user(env->fpr[i/2].l.lower, dst);

            } else {

                err |= __put_user(env->fpr[i/2].l.upper, dst);

            }

        }

    }

    err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));

    err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));

    err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));

    if (err)

        goto do_sigsegv;

    unlock_user_struct(ucp, ucp_addr, 1);

    return;

 do_sigsegv:

    unlock_user_struct(ucp, ucp_addr, 1);

    force_sig(TARGET_SIGSEGV);

}


static int proxy_utimensat(FsContext *s, V9fsPath *fs_path,

                           const struct timespec *buf)

{

    int retval;

    retval = v9fs_request(s->private, T_UTIME, NULL, "sqqqq",

                          fs_path,

                          buf[0].tv_sec, buf[0].tv_nsec,

                          buf[1].tv_sec, buf[1].tv_nsec);

    if (retval < 0) {

        errno = -retval;

    }

    return retval;

}


static int subviewer_decode_frame(AVCodecContext *avctx,

                                  void *data, int *got_sub_ptr, AVPacket *avpkt)

{

    char c;

    AVSubtitle *sub = data;

    const char *ptr = avpkt->data;

    AVBPrint buf;

    /* To be removed later */

    if (sscanf(ptr, "%*u:%*u:%*u.%*u,%*u:%*u:%*u.%*u%c", &c) == 1) {

        av_log(avctx, AV_LOG_ERROR, "AVPacket is not clean (contains timing "

               "information). You need to upgrade your libavformat or "

               "sanitize your packet.\n");

        return AVERROR_INVALIDDATA;

    }

    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);

    // note: no need to rescale pts & duration since they are in the same

    // timebase as ASS (1/100)

    if (ptr && avpkt->size > 0 && !subviewer_event_to_ass(&buf, ptr))

        ff_ass_add_rect(sub, buf.str, avpkt->pts, avpkt->duration, 0);

    *got_sub_ptr = sub->num_rects > 0;

    av_bprint_finalize(&buf, NULL);

    return avpkt->size;

}


void ff_mpeg4_pred_ac(MpegEncContext *s, int16_t *block, int n, int dir)

{

    int i;

    int16_t *ac_val, *ac_val1;

    int8_t *const qscale_table = s->current_picture.qscale_table;

    /* find prediction */

    ac_val  = s->ac_val[0][0] + s->block_index[n] * 16;

    ac_val1 = ac_val;

    if (s->ac_pred) {

        if (dir == 0) {

            const int xy = s->mb_x - 1 + s->mb_y * s->mb_stride;

            /* left prediction */

            ac_val -= 16;

            if (s->mb_x == 0 || s->qscale == qscale_table[xy] ||

                n == 1 || n == 3) {

                /* same qscale */

                for (i = 1; i < 8; i++)

                    block[s->idsp.idct_permutation[i << 3]] += ac_val[i];

            } else {

                /* different qscale, we must rescale */

                for (i = 1; i < 8; i++)

                    block[s->idsp.idct_permutation[i << 3]] += ROUNDED_DIV(ac_val[i] * qscale_table[xy], s->qscale);

            }

        } else {

            const int xy = s->mb_x + s->mb_y * s->mb_stride - s->mb_stride;

            /* top prediction */

            ac_val -= 16 * s->block_wrap[n];

            if (s->mb_y == 0 || s->qscale == qscale_table[xy] ||

                n == 2 || n == 3) {

                /* same qscale */

                for (i = 1; i < 8; i++)

                    block[s->idsp.idct_permutation[i]] += ac_val[i + 8];

            } else {

                /* different qscale, we must rescale */

                for (i = 1; i < 8; i++)

                    block[s->idsp.idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8] * qscale_table[xy], s->qscale);

            }

        }

    }

    /* left copy */

    for (i = 1; i < 8; i++)

        ac_val1[i] = block[s->idsp.idct_permutation[i << 3]];

    /* top copy */

    for (i = 1; i < 8; i++)

        ac_val1[8 + i] = block[s->idsp.idct_permutation[i]];

}


static int csrhci_write(struct CharDriverState *chr,

                const uint8_t *buf, int len)

{

    struct csrhci_s *s = (struct csrhci_s *) chr->opaque;

    int plen = s->in_len;

    if (!s->enable)

        return 0;

    s->in_len += len;

    memcpy(s->inpkt + plen, buf, len);

    while (1) {

        if (s->in_len >= 2 && plen < 2)

            s->in_hdr = csrhci_header_len(s->inpkt) + 1;

        if (s->in_len >= s->in_hdr && plen < s->in_hdr)

            s->in_data = csrhci_data_len(s->inpkt) + s->in_hdr;

        if (s->in_len >= s->in_data) {

            csrhci_in_packet(s, s->inpkt);

            memmove(s->inpkt, s->inpkt + s->in_len, s->in_len - s->in_data);

            s->in_len -= s->in_data;

            s->in_hdr = INT_MAX;

            s->in_data = INT_MAX;

            plen = 0;

        } else

            break;

    }

    return len;

}


static int standard_decode_picture_header(VC9Context *v)

{

    int status = 0;

    if (v->finterpflag) v->interpfrm = get_bits(&v->gb, 1);

    skip_bits(&v->gb, 2); //framecnt unused

    if (v->rangered) v->rangeredfrm = get_bits(&v->gb, 1);

    v->pict_type = get_bits(&v->gb, 1);

    if (v->avctx->max_b_frames && !v->pict_type)

    {

        if (get_bits(&v->gb, 1)) v->pict_type = I_TYPE;

        else v->pict_type = P_TYPE;

    }

    else v->pict_type++; //P_TYPE

    switch (v->pict_type)

    {

    case I_TYPE: status = decode_i_picture_header(v); break;

    case BI_TYPE: status = decode_b_picture_header(v); break;

    case P_TYPE: status = decode_p_picture_header(v); break;

    case B_TYPE: status = decode_b_picture_header(v); break;

    }

    if (status == FRAME_SKIPED)

    {

      av_log(v, AV_LOG_INFO, "Skipping frame...\n");

      return status;

    }

    /* AC/DC Syntax */

    v->transacfrm = get_bits(&v->gb, 1);

    if (v->transacfrm) v->transacfrm += get_bits(&v->gb, 1);

    if (v->pict_type == I_TYPE || v->pict_type == BI_TYPE)

    {

        v->transacfrm2 = get_bits(&v->gb, 1);

        if (v->transacfrm2) v->transacfrm2 += get_bits(&v->gb, 1);

    }

    v->transacdctab = get_bits(&v->gb, 1);

    return 0;

}


static void do_program_interrupt(CPUS390XState *env)

{

    uint64_t mask, addr;

    LowCore *lowcore;

    hwaddr len = TARGET_PAGE_SIZE;

    int ilen = env->int_pgm_ilen;

    switch (ilen) {

    case ILEN_LATER:

        ilen = get_ilen(cpu_ldub_code(env, env->psw.addr));

        break;

    case ILEN_LATER_INC:

        ilen = get_ilen(cpu_ldub_code(env, env->psw.addr));

        env->psw.addr += ilen;

        break;

    default:

        assert(ilen == 2 || ilen == 4 || ilen == 6);

    }

    qemu_log_mask(CPU_LOG_INT, "%s: code=0x%x ilen=%d\n",

                  __func__, env->int_pgm_code, ilen);

    lowcore = cpu_physical_memory_map(env->psa, &len, 1);

    lowcore->pgm_ilen = cpu_to_be16(ilen);

    lowcore->pgm_code = cpu_to_be16(env->int_pgm_code);

    lowcore->program_old_psw.mask = cpu_to_be64(get_psw_mask(env));

    lowcore->program_old_psw.addr = cpu_to_be64(env->psw.addr);

    mask = be64_to_cpu(lowcore->program_new_psw.mask);

    addr = be64_to_cpu(lowcore->program_new_psw.addr);

    cpu_physical_memory_unmap(lowcore, len, 1, len);

    DPRINTF("%s: %x %x %" PRIx64 " %" PRIx64 "\n", __func__,

            env->int_pgm_code, ilen, env->psw.mask,

            env->psw.addr);

    load_psw(env, mask, addr);

}


int get_physical_address(CPUState * env, target_ulong * physical,

			 int *prot, target_ulong address,

			 int rw, int access_type)

{

    /* P1, P2 and P4 areas do not use translation */

    if ((address >= 0x80000000 && address < 0xc0000000) ||

	address >= 0xe0000000) {

	if (!(env->sr & SR_MD)

	    && (address < 0xe0000000 || address > 0xe4000000)) {

	    /* Unauthorized access in user mode (only store queues are available) */

	    fprintf(stderr, "Unauthorized access\n");

	    return (rw & PAGE_WRITE) ? MMU_DTLB_MISS_WRITE :

		MMU_DTLB_MISS_READ;

	}

	/* Mask upper 3 bits */

	*physical = address & 0x1FFFFFFF;

	*prot = PAGE_READ | PAGE_WRITE;

	return MMU_OK;

    }

    /* If MMU is disabled, return the corresponding physical page */

    if (!env->mmucr & MMUCR_AT) {

	*physical = address & 0x1FFFFFFF;

	*prot = PAGE_READ | PAGE_WRITE;

	return MMU_OK;

    }

    /* We need to resort to the MMU */

    return get_mmu_address(env, physical, prot, address, rw, access_type);

}


static int multiwrite_f(BlockBackend *blk, int argc, char **argv)

{

    struct timeval t1, t2;

    int Cflag = 0, qflag = 0;

    int c, cnt;

    char **buf;

    int64_t offset, first_offset = 0;

    /* Some compilers get confused and warn if this is not initialized.  */

    int total = 0;

    int nr_iov;

    int nr_reqs;

    int pattern = 0xcd;

    QEMUIOVector *qiovs;

    int i;

    BlockRequest *reqs;

    while ((c = getopt(argc, argv, "CqP:")) != EOF) {

        switch (c) {

        case 'C':

            Cflag = 1;

            break;

        case 'q':

            qflag = 1;

            break;

        case 'P':

            pattern = parse_pattern(optarg);

            if (pattern < 0) {

                return 0;

            }

            break;

        default:

            return qemuio_command_usage(&writev_cmd);

        }

    }

    if (optind > argc - 2) {

        return qemuio_command_usage(&writev_cmd);

    }

    nr_reqs = 1;

    for (i = optind; i < argc; i++) {

        if (!strcmp(argv[i], ";")) {

            nr_reqs++;

        }

    }

    reqs = g_new0(BlockRequest, nr_reqs);

    buf = g_new0(char *, nr_reqs);

    qiovs = g_new(QEMUIOVector, nr_reqs);

    for (i = 0; i < nr_reqs && optind < argc; i++) {

        int j;

        /* Read the offset of the request */

        offset = cvtnum(argv[optind]);

        if (offset < 0) {

            printf("non-numeric offset argument -- %s\n", argv[optind]);

            goto out;

        }

        optind++;

        if (offset & 0x1ff) {

            printf("offset %lld is not sector aligned\n",

                   (long long)offset);

            goto out;

        }

        if (i == 0) {

            first_offset = offset;

        }

        /* Read lengths for qiov entries */

        for (j = optind; j < argc; j++) {

            if (!strcmp(argv[j], ";")) {

                break;

            }

        }

        nr_iov = j - optind;

        /* Build request */

        buf[i] = create_iovec(blk, &qiovs[i], &argv[optind], nr_iov, pattern);

        if (buf[i] == NULL) {

            goto out;

        }

        reqs[i].qiov = &qiovs[i];

        reqs[i].sector = offset >> 9;

        reqs[i].nb_sectors = reqs[i].qiov->size >> 9;

        optind = j + 1;

        pattern++;

    }

    /* If there were empty requests at the end, ignore them */

    nr_reqs = i;

    gettimeofday(&t1, NULL);

    cnt = do_aio_multiwrite(blk, reqs, nr_reqs, &total);

    gettimeofday(&t2, NULL);

    if (cnt < 0) {

        printf("aio_multiwrite failed: %s\n", strerror(-cnt));

        goto out;

    }

    if (qflag) {

        goto out;

    }

    /* Finally, report back -- -C gives a parsable format */

    t2 = tsub(t2, t1);

    print_report("wrote", &t2, first_offset, total, total, cnt, Cflag);

out:

    for (i = 0; i < nr_reqs; i++) {

        qemu_io_free(buf[i]);

        if (reqs[i].qiov != NULL) {

            qemu_iovec_destroy(&qiovs[i]);

        }

    }

    g_free(buf);

    g_free(reqs);

    g_free(qiovs);

    return 0;

}


static void rtsp_cmd_setup(HTTPContext *c, const char *url,

                           RTSPHeader *h)

{

    FFStream *stream;

    int stream_index, port;

    char buf[1024];

    char path1[1024];

    const char *path;

    HTTPContext *rtp_c;

    RTSPTransportField *th;

    struct sockaddr_in dest_addr;

    RTSPActionServerSetup setup;

    /* find which url is asked */

    url_split(NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);

    path = path1;

    if (*path == '/')

        path++;

    /* now check each stream */

    for(stream = first_stream; stream != NULL; stream = stream->next) {

        if (!stream->is_feed && stream->fmt == &rtp_mux) {

            /* accept aggregate filenames only if single stream */

            if (!strcmp(path, stream->filename)) {

                if (stream->nb_streams != 1) {

                    rtsp_reply_error(c, RTSP_STATUS_AGGREGATE);

                    return;

                }

                stream_index = 0;

                goto found;

            }

            for(stream_index = 0; stream_index < stream->nb_streams;

                stream_index++) {

                snprintf(buf, sizeof(buf), "%s/streamid=%d",

                         stream->filename, stream_index);

                if (!strcmp(path, buf))

                    goto found;

            }

        }

    }

    /* no stream found */

    rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */

    return;

 found:

    /* generate session id if needed */

    if (h->session_id[0] == '\0') {

        snprintf(h->session_id, sizeof(h->session_id),

                 "%08x%08x", (int)random(), (int)random());

    }

    /* find rtp session, and create it if none found */

    rtp_c = find_rtp_session(h->session_id);

    if (!rtp_c) {

        /* always prefer UDP */

        th = find_transport(h, RTSP_PROTOCOL_RTP_UDP);

        if (!th) {

            th = find_transport(h, RTSP_PROTOCOL_RTP_TCP);

            if (!th) {

                rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);

                return;

            }

        }

        rtp_c = rtp_new_connection(&c->from_addr, stream, h->session_id,

                                   th->protocol);

        if (!rtp_c) {

            rtsp_reply_error(c, RTSP_STATUS_BANDWIDTH);

            return;

        }

        /* open input stream */

        if (open_input_stream(rtp_c, "") < 0) {

            rtsp_reply_error(c, RTSP_STATUS_INTERNAL);

            return;

        }

    }

    /* test if stream is OK (test needed because several SETUP needs

       to be done for a given file) */

    if (rtp_c->stream != stream) {

        rtsp_reply_error(c, RTSP_STATUS_SERVICE);

        return;

    }

    /* test if stream is already set up */

    if (rtp_c->rtp_ctx[stream_index]) {

        rtsp_reply_error(c, RTSP_STATUS_STATE);

        return;

    }

    /* check transport */

    th = find_transport(h, rtp_c->rtp_protocol);

    if (!th || (th->protocol == RTSP_PROTOCOL_RTP_UDP &&

                th->client_port_min <= 0)) {

        rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);

        return;

    }

    /* setup default options */

    setup.transport_option[0] = '\0';

    dest_addr = rtp_c->from_addr;

    dest_addr.sin_port = htons(th->client_port_min);

    /* add transport option if needed */

    if (ff_rtsp_callback) {

        setup.ipaddr = ntohl(dest_addr.sin_addr.s_addr);

        if (ff_rtsp_callback(RTSP_ACTION_SERVER_SETUP, rtp_c->session_id,

                             (char *)&setup, sizeof(setup),

                             stream->rtsp_option) < 0) {

            rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);

            return;

        }

        dest_addr.sin_addr.s_addr = htonl(setup.ipaddr);

    }

    /* setup stream */

    if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, c) < 0) {

        rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);

        return;

    }

    /* now everything is OK, so we can send the connection parameters */

    rtsp_reply_header(c, RTSP_STATUS_OK);

    /* session ID */

    url_fprintf(c->pb, "Session: %s\r\n", rtp_c->session_id);

    switch(rtp_c->rtp_protocol) {

    case RTSP_PROTOCOL_RTP_UDP:

        port = rtp_get_local_port(rtp_c->rtp_handles[stream_index]);

        url_fprintf(c->pb, "Transport: RTP/AVP/UDP;unicast;"

                    "client_port=%d-%d;server_port=%d-%d",

                    th->client_port_min, th->client_port_min + 1,

                    port, port + 1);

        break;

    case RTSP_PROTOCOL_RTP_TCP:

        url_fprintf(c->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d",

                    stream_index * 2, stream_index * 2 + 1);

        break;

    default:

        break;

    }

    if (setup.transport_option[0] != '\0') {

        url_fprintf(c->pb, ";%s", setup.transport_option);

    }

    url_fprintf(c->pb, "\r\n");

    url_fprintf(c->pb, "\r\n");

}


static int show_format(WriterContext *w, AVFormatContext *fmt_ctx)

{

    char val_str[128];

    int64_t size = fmt_ctx->pb ? avio_size(fmt_ctx->pb) : -1;

    int ret = 0;

    writer_print_section_header(w, SECTION_ID_FORMAT);

    print_str("filename",         fmt_ctx->filename);

    print_int("nb_streams",       fmt_ctx->nb_streams);

    print_int("nb_programs",      fmt_ctx->nb_programs);

    print_str("format_name",      fmt_ctx->iformat->name);

    if (!do_bitexact) {

        if (fmt_ctx->iformat->long_name) print_str    ("format_long_name", fmt_ctx->iformat->long_name);

        else                             print_str_opt("format_long_name", "unknown");

    }

    print_time("start_time",      fmt_ctx->start_time, &AV_TIME_BASE_Q);

    print_time("duration",        fmt_ctx->duration,   &AV_TIME_BASE_Q);

    if (size >= 0) print_val    ("size", size, unit_byte_str);

    else           print_str_opt("size", "N/A");

    if (fmt_ctx->bit_rate > 0) print_val    ("bit_rate", fmt_ctx->bit_rate, unit_bit_per_second_str);

    else                       print_str_opt("bit_rate", "N/A");

    print_int("probe_score", av_format_get_probe_score(fmt_ctx));

    ret = show_tags(w, fmt_ctx->metadata, SECTION_ID_FORMAT_TAGS);

    writer_print_section_footer(w);

    fflush(stdout);

    return ret;

}


static void n8x0_init(ram_addr_t ram_size, const char *boot_device,

                const char *kernel_filename,

                const char *kernel_cmdline, const char *initrd_filename,

                const char *cpu_model, struct arm_boot_info *binfo, int model)

{

    struct n800_s *s = (struct n800_s *) qemu_mallocz(sizeof(*s));

    int sdram_size = binfo->ram_size;

    int onenandram_size = 0x00010000;

    DisplayState *ds;

    if (ram_size < sdram_size + onenandram_size + OMAP242X_SRAM_SIZE) {

        fprintf(stderr, "This architecture uses %i bytes of memory\n",

                        sdram_size + onenandram_size + OMAP242X_SRAM_SIZE);

        exit(1);

    }

    s->cpu = omap2420_mpu_init(sdram_size, cpu_model);

    /* Setup peripherals

     *

     * Believed external peripherals layout in the N810:

     * (spi bus 1)

     *   tsc2005

     *   lcd_mipid

     * (spi bus 2)

     *   Conexant cx3110x (WLAN)

     *   optional: pc2400m (WiMAX)

     * (i2c bus 0)

     *   TLV320AIC33 (audio codec)

     *   TCM825x (camera by Toshiba)

     *   lp5521 (clever LEDs)

     *   tsl2563 (light sensor, hwmon, model 7, rev. 0)

     *   lm8323 (keypad, manf 00, rev 04)

     * (i2c bus 1)

     *   tmp105 (temperature sensor, hwmon)

     *   menelaus (pm)

     * (somewhere on i2c - maybe N800-only)

     *   tea5761 (FM tuner)

     * (serial 0)

     *   GPS

     * (some serial port)

     *   csr41814 (Bluetooth)

     */

    n8x0_gpio_setup(s);

    n8x0_nand_setup(s);

    n8x0_i2c_setup(s);

    if (model == 800)

        n800_tsc_kbd_setup(s);

    else if (model == 810) {

        n810_tsc_setup(s);

        n810_kbd_setup(s);

    }

    n8x0_spi_setup(s);

    n8x0_dss_setup(s);

    n8x0_cbus_setup(s);

    n8x0_uart_setup(s);

    if (usb_enabled)

        n8x0_usb_setup(s);

    /* Setup initial (reset) machine state */

    /* Start at the OneNAND bootloader.  */

    s->cpu->env->regs[15] = 0;

    if (kernel_filename) {

        /* Or at the linux loader.  */

        binfo->kernel_filename = kernel_filename;

        binfo->kernel_cmdline = kernel_cmdline;

        binfo->initrd_filename = initrd_filename;

        arm_load_kernel(s->cpu->env, binfo);

        qemu_register_reset(n8x0_boot_init, s);

        n8x0_boot_init(s);

    }

    if (option_rom[0] && (boot_device[0] == 'n' || !kernel_filename)) {

        int rom_size;

        uint8_t nolo_tags[0x10000];

        /* No, wait, better start at the ROM.  */

        s->cpu->env->regs[15] = OMAP2_Q2_BASE + 0x400000;

        /* This is intended for loading the `secondary.bin' program from

         * Nokia images (the NOLO bootloader).  The entry point seems

         * to be at OMAP2_Q2_BASE + 0x400000.

         *

         * The `2nd.bin' files contain some kind of earlier boot code and

         * for them the entry point needs to be set to OMAP2_SRAM_BASE.

         *

         * The code above is for loading the `zImage' file from Nokia

         * images.  */

        rom_size = load_image_targphys(option_rom[0],

                                       OMAP2_Q2_BASE + 0x400000,

                                       sdram_size - 0x400000);

        printf("%i bytes of image loaded\n", rom_size);

        n800_setup_nolo_tags(nolo_tags);

        cpu_physical_memory_write(OMAP2_SRAM_BASE, nolo_tags, 0x10000);

    }

    /* FIXME: We shouldn't really be doing this here.  The LCD controller

       will set the size once configured, so this just sets an initial

       size until the guest activates the display.  */

    ds = get_displaystate();

    ds->surface = qemu_resize_displaysurface(ds, 800, 480);

    dpy_resize(ds);

}


void replay_fetch_data_kind(void)

{

    if (replay_file) {

        if (!replay_has_unread_data) {

            replay_data_kind = replay_get_byte();

            if (replay_data_kind == EVENT_INSTRUCTION) {

                replay_state.instructions_count = replay_get_dword();

            }

            replay_check_error();

            replay_has_unread_data = 1;

            if (replay_data_kind >= EVENT_COUNT) {

                error_report("Replay: unknown event kind %d", replay_data_kind);

                exit(1);

            }

        }

    }

}


static void DMA_run (void)

{

    struct dma_cont *d;

    int icont, ichan;

    int rearm = 0;

    static int running = 0;

    if (running) {

        rearm = 1;

        goto out;

    } else {

        running = 1;

    }

    d = dma_controllers;

    for (icont = 0; icont < 2; icont++, d++) {

        for (ichan = 0; ichan < 4; ichan++) {

            int mask;

            mask = 1 << ichan;

            if ((0 == (d->mask & mask)) && (0 != (d->status & (mask << 4)))) {

                channel_run (icont, ichan);

                rearm = 1;

            }

        }

    }

    running = 0;

out:

    if (rearm)

        qemu_bh_schedule_idle(dma_bh);

}


int bdrv_img_create(const char *filename, const char *fmt,

                    const char *base_filename, const char *base_fmt,

                    char *options, uint64_t img_size, int flags)

{

    QEMUOptionParameter *param = NULL, *create_options = NULL;

    QEMUOptionParameter *backing_fmt;

    BlockDriverState *bs = NULL;

    BlockDriver *drv, *proto_drv;

    int ret = 0;

    /* Find driver and parse its options */

    drv = bdrv_find_format(fmt);

    if (!drv) {

        error_report("Unknown file format '%s'", fmt);

        ret = -1;

        goto out;

    }

    proto_drv = bdrv_find_protocol(filename);

    if (!proto_drv) {

        error_report("Unknown protocol '%s'", filename);

        ret = -1;

        goto out;

    }

    create_options = append_option_parameters(create_options,

                                              drv->create_options);

    create_options = append_option_parameters(create_options,

                                              proto_drv->create_options);

    /* Create parameter list with default values */

    param = parse_option_parameters("", create_options, param);

    set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size);

    /* Parse -o options */

    if (options) {

        param = parse_option_parameters(options, create_options, param);

        if (param == NULL) {

            error_report("Invalid options for file format '%s'.", fmt);

            ret = -1;

            goto out;

        }

    }

    if (base_filename) {

        if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE,

                                 base_filename)) {

            error_report("Backing file not supported for file format '%s'",

                         fmt);

            ret = -1;

            goto out;

        }

    }

    if (base_fmt) {

        if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {

            error_report("Backing file format not supported for file "

                         "format '%s'", fmt);

            ret = -1;

            goto out;

        }

    }

    backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT);

    if (backing_fmt && backing_fmt->value.s) {

        if (!bdrv_find_format(backing_fmt->value.s)) {

            error_report("Unknown backing file format '%s'",

                         backing_fmt->value.s);

            ret = -1;

            goto out;

        }

    }

    // The size for the image must always be specified, with one exception:

    // If we are using a backing file, we can obtain the size from there

    if (get_option_parameter(param, BLOCK_OPT_SIZE)->value.n == -1) {

        QEMUOptionParameter *backing_file =

            get_option_parameter(param, BLOCK_OPT_BACKING_FILE);

        if (backing_file && backing_file->value.s) {

            uint64_t size;

            const char *fmt = NULL;

            char buf[32];

            if (backing_fmt && backing_fmt->value.s) {

                fmt = backing_fmt->value.s;

            }

            bs = bdrv_new("");

            ret = bdrv_open(bs, backing_file->value.s, flags, drv);

            if (ret < 0) {

                error_report("Could not open '%s'", filename);

                ret = -1;

                goto out;

            }

            bdrv_get_geometry(bs, &size);

            size *= 512;

            snprintf(buf, sizeof(buf), "%" PRId64, size);

            set_option_parameter(param, BLOCK_OPT_SIZE, buf);

        } else {

            error_report("Image creation needs a size parameter");

            ret = -1;

            goto out;

        }

    }

    printf("Formatting '%s', fmt=%s ", filename, fmt);

    print_option_parameters(param);

    puts("");

    ret = bdrv_create(drv, filename, param);

    if (ret < 0) {

        if (ret == -ENOTSUP) {

            error_report("Formatting or formatting option not supported for "

                         "file format '%s'", fmt);

        } else if (ret == -EFBIG) {

            error_report("The image size is too large for file format '%s'",

                         fmt);

        } else {

            error_report("%s: error while creating %s: %s", filename, fmt,

                         strerror(-ret));

        }

    }

out:

    free_option_parameters(create_options);

    free_option_parameters(param);

    if (bs) {

        bdrv_delete(bs);

    }

    if (ret) {

        return 1;

    }

    return 0;

}


static inline void reset_bit(uint32_t *field, int bit)

{

    field[bit >> 5] &= ~(1 << (bit & 0x1F));

}


void bdrv_aio_cancel_async(BlockAIOCB *acb)

{

    if (acb->aiocb_info->cancel_async) {

        acb->aiocb_info->cancel_async(acb);

    }

}


Visitor *qapi_dealloc_get_visitor(QapiDeallocVisitor *v)

{

    return &v->visitor;

}


int av_asrc_buffer_add_audio_buffer_ref(AVFilterContext *ctx,

                                        AVFilterBufferRef *samplesref,

                                        int av_unused flags)

{

    BufferSourceContext *abuffer = ctx->priv;

    AVFilterLink *link;

    int ret, logged = 0;

    if (av_fifo_space(abuffer->fifo) < sizeof(samplesref)) {

        av_log(ctx, AV_LOG_ERROR,

               "Buffering limit reached. Please consume some available frames "

               "before adding new ones.\n");

        return AVERROR(EINVAL);

    }

    // Normalize input

    link = ctx->outputs[0];

    if (samplesref->audio->sample_rate != link->sample_rate) {

        log_input_change(ctx, link, samplesref);

        logged = 1;

        abuffer->sample_rate = samplesref->audio->sample_rate;

        if (!abuffer->aresample) {

            ret = insert_filter(abuffer, link, &abuffer->aresample, "aresample");

            if (ret < 0) return ret;

        } else {

            link = abuffer->aresample->outputs[0];

            if (samplesref->audio->sample_rate == link->sample_rate)

                remove_filter(&abuffer->aresample);

            else

                if ((ret = reconfigure_filter(abuffer, abuffer->aresample)) < 0)

                    return ret;

        }

    }

    link = ctx->outputs[0];

    if (samplesref->format                != link->format         ||

        samplesref->audio->channel_layout != link->channel_layout ||

        samplesref->audio->planar         != link->planar) {

        if (!logged) log_input_change(ctx, link, samplesref);

        abuffer->sample_format  = samplesref->format;

        abuffer->channel_layout = samplesref->audio->channel_layout;

        abuffer->packing_format = samplesref->audio->planar;

        if (!abuffer->aconvert) {

            ret = insert_filter(abuffer, link, &abuffer->aconvert, "aconvert");

            if (ret < 0) return ret;

        } else {

            link = abuffer->aconvert->outputs[0];

            if (samplesref->format                == link->format         &&

                samplesref->audio->channel_layout == link->channel_layout &&

                samplesref->audio->planar         == link->planar

               )

                remove_filter(&abuffer->aconvert);

            else

                if ((ret = reconfigure_filter(abuffer, abuffer->aconvert)) < 0)

                    return ret;

        }

    }

    if (sizeof(samplesref) != av_fifo_generic_write(abuffer->fifo, &samplesref,

                                                    sizeof(samplesref), NULL)) {

        av_log(ctx, AV_LOG_ERROR, "Error while writing to FIFO\n");

        return AVERROR(EINVAL);

    }

    return 0;

}


static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout)

{

    struct v4l2_plane planes[VIDEO_MAX_PLANES];

    struct v4l2_buffer buf = { 0 };

    V4L2Buffer* avbuf = NULL;

    struct pollfd pfd = {

        .events =  POLLIN | POLLRDNORM | POLLPRI | POLLOUT | POLLWRNORM, /* default blocking capture */

        .fd = ctx_to_m2mctx(ctx)->fd,

    };

    int ret;

    if (V4L2_TYPE_IS_OUTPUT(ctx->type))

        pfd.events =  POLLOUT | POLLWRNORM;

    for (;;) {

        ret = poll(&pfd, 1, timeout);

        if (ret > 0)

            break;

        if (errno == EINTR)

            continue;

        /* timeout is being used to indicate last valid bufer when draining */

        if (ctx_to_m2mctx(ctx)->draining)

            ctx->done = 1;

        return NULL;

    }

    /* 0. handle errors */

    if (pfd.revents & POLLERR) {

        av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name);

        return NULL;

    }

    /* 1. handle resolution changes */

    if (pfd.revents & POLLPRI) {

        ret = v4l2_handle_event(ctx);

        if (ret < 0) {

            /* if re-init failed, abort */

            ctx->done = EINVAL;

            return NULL;

        }

        if (ret) {

            /* if re-init was successful drop the buffer (if there was one)

             * since we had to reconfigure capture (unmap all buffers)

             */

            return NULL;

        }

    }

    /* 2. dequeue the buffer */

    if (pfd.revents & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM)) {

        if (!V4L2_TYPE_IS_OUTPUT(ctx->type)) {

            /* there is a capture buffer ready */

            if (pfd.revents & (POLLIN | POLLRDNORM))

                goto dequeue;

            /* the driver is ready to accept more input; instead of waiting for the capture

             * buffer to complete we return NULL so input can proceed (we are single threaded)

             */

            if (pfd.revents & (POLLOUT | POLLWRNORM))

                return NULL;

        }

dequeue:

        memset(&buf, 0, sizeof(buf));

        buf.memory = V4L2_MEMORY_MMAP;

        buf.type = ctx->type;

        if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {

            memset(planes, 0, sizeof(planes));

            buf.length = VIDEO_MAX_PLANES;

            buf.m.planes = planes;

        }

        ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DQBUF, &buf);

        if (ret) {

            if (errno != EAGAIN) {

                ctx->done = errno;

                if (errno != EPIPE)

                    av_log(logger(ctx), AV_LOG_DEBUG, "%s VIDIOC_DQBUF, errno (%s)\n",

                        ctx->name, av_err2str(AVERROR(errno)));

            }

        } else {

            avbuf = &ctx->buffers[buf.index];

            avbuf->status = V4L2BUF_AVAILABLE;

            avbuf->buf = buf;

            if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {

                memcpy(avbuf->planes, planes, sizeof(planes));

                avbuf->buf.m.planes = avbuf->planes;

            }

        }

    }

    return avbuf;

}