static void disas_arm_insn(CPUState * env, DisasContext *s)

{

    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;

    insn = ldl_code(s->pc);

    s->pc += 4;

    cond = insn >> 28;

    if (cond == 0xf){

        /* Unconditional instructions.  */

        if ((insn & 0x0d70f000) == 0x0550f000)

            return; /* PLD */

        else if ((insn & 0x0e000000) == 0x0a000000) {

            /* branch link and change to thumb (blx <offset>) */

            int32_t offset;

            val = (uint32_t)s->pc;

            gen_op_movl_T0_im(val);

            gen_movl_reg_T0(s, 14);

            /* Sign-extend the 24-bit offset */

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

            /* offset * 4 + bit24 * 2 + (thumb bit) */

            val += (offset << 2) | ((insn >> 23) & 2) | 1;

            /* pipeline offset */

            val += 4;

            gen_op_movl_T0_im(val);

            gen_bx(s);

            return;

        } else if ((insn & 0x0fe00000) == 0x0c400000) {

            /* Coprocessor double register transfer.  */

        } else if ((insn & 0x0f000010) == 0x0e000010) {

            /* Additional coprocessor register transfer.  */

        } else if ((insn & 0x0ff10010) == 0x01000000) {

            /* cps (privileged) */

        } else if ((insn & 0x0ffffdff) == 0x01010000) {

            /* setend */

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

                /* BE8 mode not implemented.  */

                goto illegal_op;

            }

            return;

        }

        goto illegal_op;

    }

    if (cond != 0xe) {

        /* if not always execute, we generate a conditional jump to

           next instruction */

        s->condlabel = gen_new_label();

        gen_test_cc[cond ^ 1](s->condlabel);

        s->condjmp = 1;

        //gen_test_cc[cond ^ 1]((long)s->tb, (long)s->pc);

        //s->is_jmp = DISAS_JUMP_NEXT;

    }

    if ((insn & 0x0f900000) == 0x03000000) {

        if ((insn & 0x0fb0f000) != 0x0320f000)

            goto illegal_op;

        /* CPSR = immediate */

        val = insn & 0xff;

        shift = ((insn >> 8) & 0xf) * 2;

        if (shift)

            val = (val >> shift) | (val << (32 - shift));

        gen_op_movl_T0_im(val);

        i = ((insn & (1 << 22)) != 0);

        if (gen_set_psr_T0(s, msr_mask(s, (insn >> 16) & 0xf, i), i))

            goto illegal_op;

    } else if ((insn & 0x0f900000) == 0x01000000

               && (insn & 0x00000090) != 0x00000090) {

        /* miscellaneous instructions */

        op1 = (insn >> 21) & 3;

        sh = (insn >> 4) & 0xf;

        rm = insn & 0xf;

        switch (sh) {

        case 0x0: /* move program status register */

            if (op1 & 1) {

                /* PSR = reg */

                gen_movl_T0_reg(s, rm);

                i = ((op1 & 2) != 0);

                if (gen_set_psr_T0(s, msr_mask(s, (insn >> 16) & 0xf, i), i))

                    goto illegal_op;

            } else {

                /* reg = PSR */

                rd = (insn >> 12) & 0xf;

                if (op1 & 2) {

                    if (IS_USER(s))

                        goto illegal_op;

                    gen_op_movl_T0_spsr();

                } else {

                    gen_op_movl_T0_cpsr();

                }

                gen_movl_reg_T0(s, rd);

            }

            break;

        case 0x1:

            if (op1 == 1) {

                /* branch/exchange thumb (bx).  */

                gen_movl_T0_reg(s, rm);

                gen_bx(s);

            } else if (op1 == 3) {

                /* clz */

                rd = (insn >> 12) & 0xf;

                gen_movl_T0_reg(s, rm);

                gen_op_clz_T0();

                gen_movl_reg_T0(s, rd);

            } else {

                goto illegal_op;

            }

            break;

        case 0x2:

            if (op1 == 1) {

                ARCH(5J); /* bxj */

                /* Trivial implementation equivalent to bx.  */

                gen_movl_T0_reg(s, rm);

                gen_bx(s);

            } else {

                goto illegal_op;

            }

            break;

        case 0x3:

            if (op1 != 1)

              goto illegal_op;

            /* branch link/exchange thumb (blx) */

            val = (uint32_t)s->pc;

            gen_op_movl_T0_im(val);

            gen_movl_reg_T0(s, 14);

            gen_movl_T0_reg(s, rm);

            gen_bx(s);

            break;

        case 0x5: /* saturating add/subtract */

            rd = (insn >> 12) & 0xf;

            rn = (insn >> 16) & 0xf;

            gen_movl_T0_reg(s, rm);

            gen_movl_T1_reg(s, rn);

            if (op1 & 2)

                gen_op_double_T1_saturate();

            if (op1 & 1)

                gen_op_subl_T0_T1_saturate();

            else

                gen_op_addl_T0_T1_saturate();

            gen_movl_reg_T0(s, rd);

            break;

        case 7: /* bkpt */

            gen_op_movl_T0_im((long)s->pc - 4);

            gen_op_movl_reg_TN[0][15]();

            gen_op_bkpt();

            s->is_jmp = DISAS_JUMP;

            break;

        case 0x8: /* signed multiply */

        case 0xa:

        case 0xc:

        case 0xe:

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

            rn = (insn >> 12) & 0xf;

            rd = (insn >> 16) & 0xf;

            if (op1 == 1) {

                /* (32 * 16) >> 16 */

                gen_movl_T0_reg(s, rm);

                gen_movl_T1_reg(s, rs);

                if (sh & 4)

                    gen_op_sarl_T1_im(16);

                else

                    gen_op_sxth_T1();

                gen_op_imulw_T0_T1();

                if ((sh & 2) == 0) {

                    gen_movl_T1_reg(s, rn);

                    gen_op_addl_T0_T1_setq();

                }

                gen_movl_reg_T0(s, rd);

            } else {

                /* 16 * 16 */

                gen_movl_T0_reg(s, rm);

                gen_movl_T1_reg(s, rs);

                gen_mulxy(sh & 2, sh & 4);

                if (op1 == 2) {

                    gen_op_signbit_T1_T0();

                    gen_op_addq_T0_T1(rn, rd);

                    gen_movl_reg_T0(s, rn);

                    gen_movl_reg_T1(s, rd);

                } else {

                    if (op1 == 0) {

                        gen_movl_T1_reg(s, rn);

                        gen_op_addl_T0_T1_setq();

                    }

                    gen_movl_reg_T0(s, rd);

                }

            }

            break;

        default:

            goto illegal_op;

        }

    } else if (((insn & 0x0e000000) == 0 &&

                (insn & 0x00000090) != 0x90) ||

               ((insn & 0x0e000000) == (1 << 25))) {

        int set_cc, logic_cc, shiftop;

        op1 = (insn >> 21) & 0xf;

        set_cc = (insn >> 20) & 1;

        logic_cc = table_logic_cc[op1] & set_cc;

        /* data processing instruction */

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

            /* immediate operand */

            val = insn & 0xff;

            shift = ((insn >> 8) & 0xf) * 2;

            if (shift)

                val = (val >> shift) | (val << (32 - shift));

            gen_op_movl_T1_im(val);

            if (logic_cc && shift)

                gen_op_mov_CF_T1();

        } else {

            /* register */

            rm = (insn) & 0xf;

            gen_movl_T1_reg(s, rm);

            shiftop = (insn >> 5) & 3;

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

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

                if (shift != 0) {

                    if (logic_cc) {

                        gen_shift_T1_im_cc[shiftop](shift);

                    } else {

                        gen_shift_T1_im[shiftop](shift);

                    }

                } else if (shiftop != 0) {

                    if (logic_cc) {

                        gen_shift_T1_0_cc[shiftop]();

                    } else {

                        gen_shift_T1_0[shiftop]();

                    }

                }

            } else {

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

                gen_movl_T0_reg(s, rs);

                if (logic_cc) {

                    gen_shift_T1_T0_cc[shiftop]();

                } else {

                    gen_shift_T1_T0[shiftop]();

                }

            }

        }

        if (op1 != 0x0f && op1 != 0x0d) {

            rn = (insn >> 16) & 0xf;

            gen_movl_T0_reg(s, rn);

        }

        rd = (insn >> 12) & 0xf;

        switch(op1) {

        case 0x00:

            gen_op_andl_T0_T1();

            gen_movl_reg_T0(s, rd);

            if (logic_cc)

                gen_op_logic_T0_cc();

            break;

        case 0x01:

            gen_op_xorl_T0_T1();

            gen_movl_reg_T0(s, rd);

            if (logic_cc)

                gen_op_logic_T0_cc();

            break;

        case 0x02:

            if (set_cc && rd == 15) {

                /* SUBS r15, ... is used for exception return.  */

                if (IS_USER(s))

                    goto illegal_op;

                gen_op_subl_T0_T1_cc();

                gen_exception_return(s);

            } else {

                if (set_cc)

                    gen_op_subl_T0_T1_cc();

                else

                    gen_op_subl_T0_T1();

                gen_movl_reg_T0(s, rd);

            }

            break;

        case 0x03:

            if (set_cc)

                gen_op_rsbl_T0_T1_cc();

            else

                gen_op_rsbl_T0_T1();

            gen_movl_reg_T0(s, rd);

            break;

        case 0x04:

            if (set_cc)

                gen_op_addl_T0_T1_cc();

            else

                gen_op_addl_T0_T1();

            gen_movl_reg_T0(s, rd);

            break;

        case 0x05:

            if (set_cc)

                gen_op_adcl_T0_T1_cc();

            else

                gen_op_adcl_T0_T1();

            gen_movl_reg_T0(s, rd);

            break;

        case 0x06:

            if (set_cc)

                gen_op_sbcl_T0_T1_cc();

            else

                gen_op_sbcl_T0_T1();

            gen_movl_reg_T0(s, rd);

            break;

        case 0x07:

            if (set_cc)

                gen_op_rscl_T0_T1_cc();

            else

                gen_op_rscl_T0_T1();

            gen_movl_reg_T0(s, rd);

            break;

        case 0x08:

            if (set_cc) {

                gen_op_andl_T0_T1();

                gen_op_logic_T0_cc();

            }

            break;

        case 0x09:

            if (set_cc) {

                gen_op_xorl_T0_T1();

                gen_op_logic_T0_cc();

            }

            break;

        case 0x0a:

            if (set_cc) {

                gen_op_subl_T0_T1_cc();

            }

            break;

        case 0x0b:

            if (set_cc) {

                gen_op_addl_T0_T1_cc();

            }

            break;

        case 0x0c:

            gen_op_orl_T0_T1();

            gen_movl_reg_T0(s, rd);

            if (logic_cc)

                gen_op_logic_T0_cc();

            break;

        case 0x0d:

            if (logic_cc && rd == 15) {

                /* MOVS r15, ... is used for exception return.  */

                if (IS_USER(s))

                    goto illegal_op;

                gen_op_movl_T0_T1();

                gen_exception_return(s);

            } else {

                gen_movl_reg_T1(s, rd);

                if (logic_cc)

                    gen_op_logic_T1_cc();

            }

            break;

        case 0x0e:

            gen_op_bicl_T0_T1();

            gen_movl_reg_T0(s, rd);

            if (logic_cc)

                gen_op_logic_T0_cc();

            break;

        default:

        case 0x0f:

            gen_op_notl_T1();

            gen_movl_reg_T1(s, rd);

            if (logic_cc)

                gen_op_logic_T1_cc();

            break;

        }

    } else {

        /* other instructions */

        op1 = (insn >> 24) & 0xf;

        switch(op1) {

        case 0x0:

        case 0x1:

            /* multiplies, extra load/stores */

            sh = (insn >> 5) & 3;

            if (sh == 0) {

                if (op1 == 0x0) {

                    rd = (insn >> 16) & 0xf;

                    rn = (insn >> 12) & 0xf;

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

                    rm = (insn) & 0xf;

                    if (((insn >> 22) & 3) == 0) {

                        /* 32 bit mul */

                        gen_movl_T0_reg(s, rs);

                        gen_movl_T1_reg(s, rm);

                        gen_op_mul_T0_T1();

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

                            gen_movl_T1_reg(s, rn);

                            gen_op_addl_T0_T1();

                        }

                        if (insn & (1 << 20))

                            gen_op_logic_T0_cc();

                        gen_movl_reg_T0(s, rd);

                    } else {

                        /* 64 bit mul */

                        gen_movl_T0_reg(s, rs);

                        gen_movl_T1_reg(s, rm);

                        if (insn & (1 << 22))

                            gen_op_imull_T0_T1();

                        else

                            gen_op_mull_T0_T1();

                        if (insn & (1 << 21)) /* mult accumulate */

                            gen_op_addq_T0_T1(rn, rd);

                        if (!(insn & (1 << 23))) { /* double accumulate */

                            ARCH(6);

                            gen_op_addq_lo_T0_T1(rn);

                            gen_op_addq_lo_T0_T1(rd);

                        }

                        if (insn & (1 << 20))

                            gen_op_logicq_cc();

                        gen_movl_reg_T0(s, rn);

                        gen_movl_reg_T1(s, rd);

                    }

                } else {

                    rn = (insn >> 16) & 0xf;

                    rd = (insn >> 12) & 0xf;

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

                        /* load/store exclusive */

                        goto illegal_op;

                    } else {

                        /* SWP instruction */

                        rm = (insn) & 0xf;

                        gen_movl_T0_reg(s, rm);

                        gen_movl_T1_reg(s, rn);

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

                            gen_ldst(swpb, s);

                        } else {

                            gen_ldst(swpl, s);

                        }

                        gen_movl_reg_T0(s, rd);

                    }

                }

            } else {

                int address_offset;

                /* Misc load/store */

                rn = (insn >> 16) & 0xf;

                rd = (insn >> 12) & 0xf;

                gen_movl_T1_reg(s, rn);

                if (insn & (1 << 24))

                    gen_add_datah_offset(s, insn, 0);

                address_offset = 0;

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

                    /* load */

                    switch(sh) {

                    case 1:

                        gen_ldst(lduw, s);

                        break;

                    case 2:

                        gen_ldst(ldsb, s);

                        break;

                    default:

                    case 3:

                        gen_ldst(ldsw, s);

                        break;

                    }

                    gen_movl_reg_T0(s, rd);

                } else if (sh & 2) {

                    /* doubleword */

                    if (sh & 1) {

                        /* store */

                        gen_movl_T0_reg(s, rd);

                        gen_ldst(stl, s);

                        gen_op_addl_T1_im(4);

                        gen_movl_T0_reg(s, rd + 1);

                        gen_ldst(stl, s);

                    } else {

                        /* load */

                        gen_ldst(ldl, s);

                        gen_movl_reg_T0(s, rd);

                        gen_op_addl_T1_im(4);

                        gen_ldst(ldl, s);

                        gen_movl_reg_T0(s, rd + 1);

                    }

                    address_offset = -4;

                } else {

                    /* store */

                    gen_movl_T0_reg(s, rd);

                    gen_ldst(stw, s);

                }

                if (!(insn & (1 << 24))) {

                    gen_add_datah_offset(s, insn, address_offset);

                    gen_movl_reg_T1(s, rn);

                } else if (insn & (1 << 21)) {

                    if (address_offset)

                        gen_op_addl_T1_im(address_offset);

                    gen_movl_reg_T1(s, rn);

                }

            }

            break;

        case 0x4:

        case 0x5:

        case 0x6:

        case 0x7:

            /* Check for undefined extension instructions

             * per the ARM Bible IE:

             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx

             */

            sh = (0xf << 20) | (0xf << 4);

            if (op1 == 0x7 && ((insn & sh) == sh))

            {

                goto illegal_op;

            }

            /* load/store byte/word */

            rn = (insn >> 16) & 0xf;

            rd = (insn >> 12) & 0xf;

            gen_movl_T1_reg(s, rn);

            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);

            if (insn & (1 << 24))

                gen_add_data_offset(s, insn);

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

                /* load */

#if defined(CONFIG_USER_ONLY)

                if (insn & (1 << 22))

                    gen_op_ldub_raw();

                else

                    gen_op_ldl_raw();

#else

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

                    if (i)

                        gen_op_ldub_user();

                    else

                        gen_op_ldub_kernel();

                } else {

                    if (i)

                        gen_op_ldl_user();

                    else

                        gen_op_ldl_kernel();

                }

#endif

                if (rd == 15)

                    gen_bx(s);

                else

                    gen_movl_reg_T0(s, rd);

            } else {

                /* store */

                gen_movl_T0_reg(s, rd);

#if defined(CONFIG_USER_ONLY)

                if (insn & (1 << 22))

                    gen_op_stb_raw();

                else

                    gen_op_stl_raw();

#else

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

                    if (i)

                        gen_op_stb_user();

                    else

                        gen_op_stb_kernel();

                } else {

                    if (i)

                        gen_op_stl_user();

                    else

                        gen_op_stl_kernel();

                }

#endif

            }

            if (!(insn & (1 << 24))) {

                gen_add_data_offset(s, insn);

                gen_movl_reg_T1(s, rn);

            } else if (insn & (1 << 21))

                gen_movl_reg_T1(s, rn); {

            }

            break;

        case 0x08:

        case 0x09:

            {

                int j, n, user, loaded_base;

                /* load/store multiple words */

                /* XXX: store correct base if write back */

                user = 0;

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

                    if (IS_USER(s))

                        goto illegal_op; /* only usable in supervisor mode */

                    if ((insn & (1 << 15)) == 0)

                        user = 1;

                }

                rn = (insn >> 16) & 0xf;

                gen_movl_T1_reg(s, rn);

                /* compute total size */

                loaded_base = 0;

                n = 0;

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

                    if (insn & (1 << i))

                        n++;

                }

                /* XXX: test invalid n == 0 case ? */

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

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

                        /* pre increment */

                        gen_op_addl_T1_im(4);

                    } else {

                        /* post increment */

                    }

                } else {

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

                        /* pre decrement */

                        gen_op_addl_T1_im(-(n * 4));

                    } else {

                        /* post decrement */

                        if (n != 1)

                            gen_op_addl_T1_im(-((n - 1) * 4));

                    }

                }

                j = 0;

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

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

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

                            /* load */

                            gen_ldst(ldl, s);

                            if (i == 15) {

                                gen_bx(s);

                            } else if (user) {

                                gen_op_movl_user_T0(i);

                            } else if (i == rn) {

                                gen_op_movl_T2_T0();

                                loaded_base = 1;

                            } else {

                                gen_movl_reg_T0(s, i);

                            }

                        } else {

                            /* store */

                            if (i == 15) {

                                /* special case: r15 = PC + 12 */

                                val = (long)s->pc + 8;

                                gen_op_movl_TN_im[0](val);

                            } else if (user) {

                                gen_op_movl_T0_user(i);

                            } else {

                                gen_movl_T0_reg(s, i);

                            }

                            gen_ldst(stl, s);

                        }

                        j++;

                        /* no need to add after the last transfer */

                        if (j != n)

                            gen_op_addl_T1_im(4);

                    }

                }

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

                    /* write back */

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

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

                            /* pre increment */

                        } else {

                            /* post increment */

                            gen_op_addl_T1_im(4);

                        }

                    } else {

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

                            /* pre decrement */

                            if (n != 1)

                                gen_op_addl_T1_im(-((n - 1) * 4));

                        } else {

                            /* post decrement */

                            gen_op_addl_T1_im(-(n * 4));

                        }

                    }

                    gen_movl_reg_T1(s, rn);

                }

                if (loaded_base) {

                    gen_op_movl_T0_T2();

                    gen_movl_reg_T0(s, rn);

                }

                if ((insn & (1 << 22)) && !user) {

                    /* Restore CPSR from SPSR.  */

                    gen_op_movl_T0_spsr();

                    gen_op_movl_cpsr_T0(0xffffffff);

                    s->is_jmp = DISAS_UPDATE;

                }

            }

            break;

        case 0xa:

        case 0xb:

            {

                int32_t offset;

                /* branch (and link) */

                val = (int32_t)s->pc;

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

                    gen_op_movl_T0_im(val);

                    gen_op_movl_reg_TN[0][14]();

                }

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

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

                gen_jmp(s, val);

            }

            break;

        case 0xc:

        case 0xd:

        case 0xe:

            /* Coprocessor.  */

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

            switch (op1) {

            case 10:

            case 11:

                if (disas_vfp_insn (env, s, insn))

                    goto illegal_op;

                break;

            case 15:

                if (disas_cp15_insn (s, insn))

                    goto illegal_op;

                break;

            default:

                /* unknown coprocessor.  */

                goto illegal_op;

            }

            break;

        case 0xf:

            /* swi */

            gen_op_movl_T0_im((long)s->pc);

            gen_op_movl_reg_TN[0][15]();

            gen_op_swi();

            s->is_jmp = DISAS_JUMP;

            break;

        default:

        illegal_op:

            gen_op_movl_T0_im((long)s->pc - 4);

            gen_op_movl_reg_TN[0][15]();

            gen_op_undef_insn();

            s->is_jmp = DISAS_JUMP;

            break;

        }

    }

}


static void print_block_info(Monitor *mon, BlockInfo *info,

                             BlockDeviceInfo *inserted, bool verbose)

{

    ImageInfo *image_info;

    assert(!info || !info->has_inserted || info->inserted == inserted);

    if (info) {

        monitor_printf(mon, "%s", info->device);

        if (inserted && inserted->has_node_name) {

            monitor_printf(mon, " (%s)", inserted->node_name);

        }

    } else {

        assert(inserted);

        monitor_printf(mon, "%s",

                       inserted->has_node_name

                       ? inserted->node_name

                       : "<anonymous>");

    }

    if (inserted) {

        monitor_printf(mon, ": %s (%s%s%s)\n",

                       inserted->file,

                       inserted->drv,

                       inserted->ro ? ", read-only" : "",

                       inserted->encrypted ? ", encrypted" : "");

    } else {

        monitor_printf(mon, ": [not inserted]\n");

    }

    if (info) {

        if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) {

            monitor_printf(mon, "    I/O status:       %s\n",

                           BlockDeviceIoStatus_lookup[info->io_status]);

        }

        if (info->removable) {

            monitor_printf(mon, "    Removable device: %slocked, tray %s\n",

                           info->locked ? "" : "not ",

                           info->tray_open ? "open" : "closed");

        }

    }

    if (!inserted) {

        return;

    }

    monitor_printf(mon, "    Cache mode:       %s%s%s\n",

                   inserted->cache->writeback ? "writeback" : "writethrough",

                   inserted->cache->direct ? ", direct" : "",

                   inserted->cache->no_flush ? ", ignore flushes" : "");

    if (inserted->has_backing_file) {

        monitor_printf(mon,

                       "    Backing file:     %s "

                       "(chain depth: %" PRId64 ")\n",

                       inserted->backing_file,

                       inserted->backing_file_depth);

    }

    if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) {

        monitor_printf(mon, "    Detect zeroes:    %s\n",

                       BlockdevDetectZeroesOptions_lookup[inserted->detect_zeroes]);

    }

    if (inserted->bps  || inserted->bps_rd  || inserted->bps_wr  ||

        inserted->iops || inserted->iops_rd || inserted->iops_wr)

    {

        monitor_printf(mon, "    I/O throttling:   bps=%" PRId64

                        " bps_rd=%" PRId64  " bps_wr=%" PRId64

                        " bps_max=%" PRId64

                        " bps_rd_max=%" PRId64

                        " bps_wr_max=%" PRId64

                        " iops=%" PRId64 " iops_rd=%" PRId64

                        " iops_wr=%" PRId64

                        " iops_max=%" PRId64

                        " iops_rd_max=%" PRId64

                        " iops_wr_max=%" PRId64

                        " iops_size=%" PRId64 "\n",

                        inserted->bps,

                        inserted->bps_rd,

                        inserted->bps_wr,

                        inserted->bps_max,

                        inserted->bps_rd_max,

                        inserted->bps_wr_max,

                        inserted->iops,

                        inserted->iops_rd,

                        inserted->iops_wr,

                        inserted->iops_max,

                        inserted->iops_rd_max,

                        inserted->iops_wr_max,

                        inserted->iops_size);

    }

    /* TODO: inserted->image should never be null */

    if (verbose && inserted->image) {

        monitor_printf(mon, "\nImages:\n");

        image_info = inserted->image;

        while (1) {

                bdrv_image_info_dump((fprintf_function)monitor_printf,

                                     mon, image_info);

            if (image_info->has_backing_image) {

                image_info = image_info->backing_image;

            } else {

                break;

            }

        }

    }

}


int qemu_bh_poll(void)

{

    QEMUBH *bh, **pbh;

    int ret;

    ret = 0;

    for(;;) {

        pbh = &first_bh;

        bh = *pbh;

        if (!bh)

            break;

        ret = 1;

        *pbh = bh->next;

        bh->scheduled = 0;

        bh->cb(bh->opaque);

    }

    return ret;

}


static int qemu_rdma_write(QEMUFile *f, RDMAContext *rdma,

                           uint64_t block_offset, uint64_t offset,

                           uint64_t len)

{

    uint64_t current_addr = block_offset + offset;

    uint64_t index = rdma->current_index;

    uint64_t chunk = rdma->current_chunk;

    int ret;

    /* If we cannot merge it, we flush the current buffer first. */

    if (!qemu_rdma_buffer_mergable(rdma, current_addr, len)) {

        ret = qemu_rdma_write_flush(f, rdma);

        if (ret) {

            return ret;

        }

        rdma->current_length = 0;

        rdma->current_addr = current_addr;

        ret = qemu_rdma_search_ram_block(rdma, block_offset,

                                         offset, len, &index, &chunk);

        if (ret) {

            fprintf(stderr, "ram block search failed\n");

            return ret;

        }

        rdma->current_index = index;

        rdma->current_chunk = chunk;

    }

    /* merge it */

    rdma->current_length += len;

    /* flush it if buffer is too large */

    if (rdma->current_length >= RDMA_MERGE_MAX) {

        return qemu_rdma_write_flush(f, rdma);

    }

    return 0;

}


static int svq1_decode_block_non_intra(GetBitContext *bitbuf, uint8_t *pixels,

                                       int pitch)

{

    uint32_t bit_cache;

    uint8_t *list[63];

    uint32_t *dst;

    const uint32_t *codebook;

    int entries[6];

    int i, j, m, n;

    int mean, stages;

    int x, y, width, height, level;

    uint32_t n1, n2, n3, n4;

    /* initialize list for breadth first processing of vectors */

    list[0] = pixels;

    /* recursively process vector */

    for (i = 0, m = 1, n = 1, level = 5; i < n; i++) {

        SVQ1_PROCESS_VECTOR();

        /* destination address and vector size */

        dst    = (uint32_t *)list[i];

        width  = 1 << ((4 + level) / 2);

        height = 1 << ((3 + level) / 2);

        /* get number of stages (-1 skips vector, 0 for mean only) */

        stages = get_vlc2(bitbuf, svq1_inter_multistage[level].table, 3, 2) - 1;

        if (stages == -1)

            continue;           /* skip vector */

        if ((stages > 0) && (level >= 4)) {

            av_dlog(NULL,

                    "Error (svq1_decode_block_non_intra): invalid vector: stages=%i level=%i\n",

                    stages, level);

            return AVERROR_INVALIDDATA;  /* invalid vector */

        }

        mean = get_vlc2(bitbuf, svq1_inter_mean.table, 9, 3) - 256;

        SVQ1_CALC_CODEBOOK_ENTRIES(ff_svq1_inter_codebooks);

        for (y = 0; y < height; y++) {

            for (x = 0; x < width / 4; x++, codebook++) {

                n3 = dst[x];

                /* add mean value to vector */

                n1 = n4 + ((n3 & 0xFF00FF00) >> 8);

                n2 = n4 +  (n3 & 0x00FF00FF);

                SVQ1_ADD_CODEBOOK()

                /* store result */

                dst[x] = n1 << 8 | n2;

            }

            dst += pitch / 4;

        }

    }

    return 0;

}


static int ac3_decode_frame(AVCodecContext * avctx, void *data,

                            int *got_frame_ptr, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    AC3DecodeContext *s = avctx->priv_data;

    int blk, ch, err, ret;

    const uint8_t *channel_map;

    const float *output[AC3_MAX_CHANNELS];

    /* copy input buffer to decoder context to avoid reading past the end

       of the buffer, which can be caused by a damaged input stream. */

    if (buf_size >= 2 && AV_RB16(buf) == 0x770B) {

        // seems to be byte-swapped AC-3

        int cnt = FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE) >> 1;

        s->dsp.bswap16_buf((uint16_t *)s->input_buffer, (const uint16_t *)buf, cnt);

    } else

        memcpy(s->input_buffer, buf, FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE));

    buf = s->input_buffer;

    /* initialize the GetBitContext with the start of valid AC-3 Frame */

    init_get_bits(&s->gbc, buf, buf_size * 8);

    /* parse the syncinfo */

    err = parse_frame_header(s);

    if (err) {

        switch (err) {

        case AAC_AC3_PARSE_ERROR_SYNC:

            av_log(avctx, AV_LOG_ERROR, "frame sync error\n");

            return -1;

        case AAC_AC3_PARSE_ERROR_BSID:

            av_log(avctx, AV_LOG_ERROR, "invalid bitstream id\n");

            break;

        case AAC_AC3_PARSE_ERROR_SAMPLE_RATE:

            av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n");

            break;

        case AAC_AC3_PARSE_ERROR_FRAME_SIZE:

            av_log(avctx, AV_LOG_ERROR, "invalid frame size\n");

            break;

        case AAC_AC3_PARSE_ERROR_FRAME_TYPE:

            /* skip frame if CRC is ok. otherwise use error concealment. */

            /* TODO: add support for substreams and dependent frames */

            if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT || s->substreamid) {

                av_log(avctx, AV_LOG_ERROR, "unsupported frame type : "

                       "skipping frame\n");

                *got_frame_ptr = 0;

                return s->frame_size;

            } else {

                av_log(avctx, AV_LOG_ERROR, "invalid frame type\n");

            }

            break;

        default:

            av_log(avctx, AV_LOG_ERROR, "invalid header\n");

            break;

        }

    } else {

        /* check that reported frame size fits in input buffer */

        if (s->frame_size > buf_size) {

            av_log(avctx, AV_LOG_ERROR, "incomplete frame\n");

            err = AAC_AC3_PARSE_ERROR_FRAME_SIZE;

        } else if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL)) {

            /* check for crc mismatch */

            if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2],

                       s->frame_size - 2)) {

                av_log(avctx, AV_LOG_ERROR, "frame CRC mismatch\n");

                err = AAC_AC3_PARSE_ERROR_CRC;

            }

        }

    }

    /* if frame is ok, set audio parameters */

    if (!err) {

        avctx->sample_rate = s->sample_rate;

        avctx->bit_rate    = s->bit_rate;

        /* channel config */

        s->out_channels = s->channels;

        s->output_mode  = s->channel_mode;

        if (s->lfe_on)

            s->output_mode |= AC3_OUTPUT_LFEON;

        if (avctx->request_channels > 0 && avctx->request_channels <= 2 &&

                avctx->request_channels < s->channels) {

            s->out_channels = avctx->request_channels;

            s->output_mode  = avctx->request_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO;

            s->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode];

        }

        avctx->channels       = s->out_channels;

        avctx->channel_layout = s->channel_layout;

        s->loro_center_mix_level   = gain_levels[s->  center_mix_level];

        s->loro_surround_mix_level = gain_levels[s->surround_mix_level];

        s->ltrt_center_mix_level   = LEVEL_MINUS_3DB;

        s->ltrt_surround_mix_level = LEVEL_MINUS_3DB;

        /* set downmixing coefficients if needed */

        if (s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) &&

                s->fbw_channels == s->out_channels)) {

            set_downmix_coeffs(s);

        }

    } else if (!s->out_channels) {

        s->out_channels = avctx->channels;

        if (s->out_channels < s->channels)

            s->output_mode  = s->out_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO;

    }

    if (avctx->channels != s->out_channels) {

        av_log(avctx, AV_LOG_ERROR, "channel number mismatching on damaged frame\n");

        return AVERROR_INVALIDDATA;

    }

    /* set audio service type based on bitstream mode for AC-3 */

    avctx->audio_service_type = s->bitstream_mode;

    if (s->bitstream_mode == 0x7 && s->channels > 1)

        avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;

    /* get output buffer */

    avctx->channels = s->out_channels;

    s->frame.nb_samples = s->num_blocks * 256;

    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {

        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");

        return ret;

    }

    /* decode the audio blocks */

    channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on];

    for (ch = 0; ch < AC3_MAX_CHANNELS; ch++) {

        output[ch] = s->output[ch];

        s->outptr[ch] = s->output[ch];

    }

    for (ch = 0; ch < s->channels; ch++) {

        if (ch < s->out_channels)

            s->outptr[channel_map[ch]] = (float *)s->frame.data[ch];

    }

    for (blk = 0; blk < s->num_blocks; blk++) {

        if (!err && decode_audio_block(s, blk)) {

            av_log(avctx, AV_LOG_ERROR, "error decoding the audio block\n");

            err = 1;

        }

        if (err)

            for (ch = 0; ch < s->out_channels; ch++)

                memcpy(((float*)s->frame.data[ch]) + AC3_BLOCK_SIZE*blk, output[ch], 1024);

        for (ch = 0; ch < s->out_channels; ch++) {

            output[ch] = s->outptr[channel_map[ch]];

            if (!ch || channel_map[ch])

                s->outptr[channel_map[ch]] += AC3_BLOCK_SIZE;

        }

    }

    s->frame.decode_error_flags = err ? FF_DECODE_ERROR_INVALID_BITSTREAM : 0;

    /* keep last block for error concealment in next frame */

    for (ch = 0; ch < s->out_channels; ch++)

        memcpy(s->output[ch], output[ch], 1024);

    *got_frame_ptr   = 1;

    *(AVFrame *)data = s->frame;

    return FFMIN(buf_size, s->frame_size);

}


static void decode_postinit(H264Context *h, int setup_finished)

{

    H264Picture *out = h->cur_pic_ptr;

    H264Picture *cur = h->cur_pic_ptr;

    int i, pics, out_of_order, out_idx;

    int invalid = 0, cnt = 0;

    h->cur_pic_ptr->f->pict_type = h->pict_type;

    if (h->next_output_pic)

        return;

    if (cur->field_poc[0] == INT_MAX || cur->field_poc[1] == INT_MAX) {

        /* FIXME: if we have two PAFF fields in one packet, we can't start

         * the next thread here. If we have one field per packet, we can.

         * The check in decode_nal_units() is not good enough to find this

         * yet, so we assume the worst for now. */

        // if (setup_finished)

        //    ff_thread_finish_setup(h->avctx);

        return;

    }

    cur->f->interlaced_frame = 0;

    cur->f->repeat_pict      = 0;

    /* Signal interlacing information externally. */

    /* Prioritize picture timing SEI information over used

     * decoding process if it exists. */

    if (h->sps.pic_struct_present_flag) {

        switch (h->sei_pic_struct) {

        case SEI_PIC_STRUCT_FRAME:

            break;

        case SEI_PIC_STRUCT_TOP_FIELD:

        case SEI_PIC_STRUCT_BOTTOM_FIELD:

            cur->f->interlaced_frame = 1;

            break;

        case SEI_PIC_STRUCT_TOP_BOTTOM:

        case SEI_PIC_STRUCT_BOTTOM_TOP:

            if (FIELD_OR_MBAFF_PICTURE(h))

                cur->f->interlaced_frame = 1;

            else

                // try to flag soft telecine progressive

                cur->f->interlaced_frame = h->prev_interlaced_frame;

            break;

        case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:

        case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:

            /* Signal the possibility of telecined film externally

             * (pic_struct 5,6). From these hints, let the applications

             * decide if they apply deinterlacing. */

            cur->f->repeat_pict = 1;

            break;

        case SEI_PIC_STRUCT_FRAME_DOUBLING:

            cur->f->repeat_pict = 2;

            break;

        case SEI_PIC_STRUCT_FRAME_TRIPLING:

            cur->f->repeat_pict = 4;

            break;

        }

        if ((h->sei_ct_type & 3) &&

            h->sei_pic_struct <= SEI_PIC_STRUCT_BOTTOM_TOP)

            cur->f->interlaced_frame = (h->sei_ct_type & (1 << 1)) != 0;

    } else {

        /* Derive interlacing flag from used decoding process. */

        cur->f->interlaced_frame = FIELD_OR_MBAFF_PICTURE(h);

    }

    h->prev_interlaced_frame = cur->f->interlaced_frame;

    if (cur->field_poc[0] != cur->field_poc[1]) {

        /* Derive top_field_first from field pocs. */

        cur->f->top_field_first = cur->field_poc[0] < cur->field_poc[1];

    } else {

        if (cur->f->interlaced_frame || h->sps.pic_struct_present_flag) {

            /* Use picture timing SEI information. Even if it is a

             * information of a past frame, better than nothing. */

            if (h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM ||

                h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM_TOP)

                cur->f->top_field_first = 1;

            else

                cur->f->top_field_first = 0;

        } else {

            /* Most likely progressive */

            cur->f->top_field_first = 0;

        }

    }

    if (h->sei_frame_packing_present &&

        h->frame_packing_arrangement_type >= 0 &&

        h->frame_packing_arrangement_type <= 6 &&

        h->content_interpretation_type > 0 &&

        h->content_interpretation_type < 3) {

        AVStereo3D *stereo = av_stereo3d_create_side_data(cur->f);

        if (!stereo)

            return;

        switch (h->frame_packing_arrangement_type) {

        case 0:

            stereo->type = AV_STEREO3D_CHECKERBOARD;

            break;

        case 1:

            stereo->type = AV_STEREO3D_COLUMNS;

            break;

        case 2:

            stereo->type = AV_STEREO3D_LINES;

            break;

        case 3:

            if (h->quincunx_subsampling)

                stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;

            else

                stereo->type = AV_STEREO3D_SIDEBYSIDE;

            break;

        case 4:

            stereo->type = AV_STEREO3D_TOPBOTTOM;

            break;

        case 5:

            stereo->type = AV_STEREO3D_FRAMESEQUENCE;

            break;

        case 6:

            stereo->type = AV_STEREO3D_2D;

            break;

        }

        if (h->content_interpretation_type == 2)

            stereo->flags = AV_STEREO3D_FLAG_INVERT;

    }

    if (h->sei_display_orientation_present &&

        (h->sei_anticlockwise_rotation || h->sei_hflip || h->sei_vflip)) {

        double angle = h->sei_anticlockwise_rotation * 360 / (double) (1 << 16);

        AVFrameSideData *rotation = av_frame_new_side_data(cur->f,

                                                           AV_FRAME_DATA_DISPLAYMATRIX,

                                                           sizeof(int32_t) * 9);

        if (!rotation)

            return;

        av_display_rotation_set((int32_t *)rotation->data, angle);

        av_display_matrix_flip((int32_t *)rotation->data,

                               h->sei_hflip, h->sei_vflip);

    }

    // FIXME do something with unavailable reference frames

    /* Sort B-frames into display order */

    if (h->sps.bitstream_restriction_flag &&

        h->avctx->has_b_frames < h->sps.num_reorder_frames) {

        h->avctx->has_b_frames = h->sps.num_reorder_frames;

        h->low_delay           = 0;

    }

    if (h->avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT &&

        !h->sps.bitstream_restriction_flag) {

        h->avctx->has_b_frames = MAX_DELAYED_PIC_COUNT - 1;

        h->low_delay           = 0;

    }

    pics = 0;

    while (h->delayed_pic[pics])

        pics++;

    assert(pics <= MAX_DELAYED_PIC_COUNT);

    h->delayed_pic[pics++] = cur;

    if (cur->reference == 0)

        cur->reference = DELAYED_PIC_REF;

    /* Frame reordering. This code takes pictures from coding order and sorts

     * them by their incremental POC value into display order. It supports POC

     * gaps, MMCO reset codes and random resets.

     * A "display group" can start either with a IDR frame (f.key_frame = 1),

     * and/or can be closed down with a MMCO reset code. In sequences where

     * there is no delay, we can't detect that (since the frame was already

     * output to the user), so we also set h->mmco_reset to detect the MMCO

     * reset code.

     * FIXME: if we detect insufficient delays (as per h->avctx->has_b_frames),

     * we increase the delay between input and output. All frames affected by

     * the lag (e.g. those that should have been output before another frame

     * that we already returned to the user) will be dropped. This is a bug

     * that we will fix later. */

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

        cnt     += out->poc < h->last_pocs[i];

        invalid += out->poc == INT_MIN;

    }

    if (!h->mmco_reset && !cur->f->key_frame &&

        cnt + invalid == MAX_DELAYED_PIC_COUNT && cnt > 0) {

        h->mmco_reset = 2;

        if (pics > 1)

            h->delayed_pic[pics - 2]->mmco_reset = 2;

    }

    if (h->mmco_reset || cur->f->key_frame) {

        for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)

            h->last_pocs[i] = INT_MIN;

        cnt     = 0;

        invalid = MAX_DELAYED_PIC_COUNT;

    }

    out     = h->delayed_pic[0];

    out_idx = 0;

    for (i = 1; i < MAX_DELAYED_PIC_COUNT &&

                h->delayed_pic[i] &&

                !h->delayed_pic[i - 1]->mmco_reset &&

                !h->delayed_pic[i]->f->key_frame;

         i++)

        if (h->delayed_pic[i]->poc < out->poc) {

            out     = h->delayed_pic[i];

            out_idx = i;

        }

    if (h->avctx->has_b_frames == 0 &&

        (h->delayed_pic[0]->f->key_frame || h->mmco_reset))

        h->next_outputed_poc = INT_MIN;

    out_of_order = !out->f->key_frame && !h->mmco_reset &&

                   (out->poc < h->next_outputed_poc);

    if (h->sps.bitstream_restriction_flag &&

        h->avctx->has_b_frames >= h->sps.num_reorder_frames) {

    } else if (out_of_order && pics - 1 == h->avctx->has_b_frames &&

               h->avctx->has_b_frames < MAX_DELAYED_PIC_COUNT) {

        if (invalid + cnt < MAX_DELAYED_PIC_COUNT) {

            h->avctx->has_b_frames = FFMAX(h->avctx->has_b_frames, cnt);

        }

        h->low_delay = 0;

    } else if (h->low_delay &&

               ((h->next_outputed_poc != INT_MIN &&

                 out->poc > h->next_outputed_poc + 2) ||

                cur->f->pict_type == AV_PICTURE_TYPE_B)) {

        h->low_delay = 0;

        h->avctx->has_b_frames++;

    }

    if (pics > h->avctx->has_b_frames) {

        out->reference &= ~DELAYED_PIC_REF;

        // for frame threading, the owner must be the second field's thread or

        // else the first thread can release the picture and reuse it unsafely

        for (i = out_idx; h->delayed_pic[i]; i++)

            h->delayed_pic[i] = h->delayed_pic[i + 1];

    }

    memmove(h->last_pocs, &h->last_pocs[1],

            sizeof(*h->last_pocs) * (MAX_DELAYED_PIC_COUNT - 1));

    h->last_pocs[MAX_DELAYED_PIC_COUNT - 1] = cur->poc;

    if (!out_of_order && pics > h->avctx->has_b_frames) {

        h->next_output_pic = out;

        if (out->mmco_reset) {

            if (out_idx > 0) {

                h->next_outputed_poc                    = out->poc;

                h->delayed_pic[out_idx - 1]->mmco_reset = out->mmco_reset;

            } else {

                h->next_outputed_poc = INT_MIN;

            }

        } else {

            if (out_idx == 0 && pics > 1 && h->delayed_pic[0]->f->key_frame) {

                h->next_outputed_poc = INT_MIN;

            } else {

                h->next_outputed_poc = out->poc;

            }

        }

        h->mmco_reset = 0;

    } else {

        av_log(h->avctx, AV_LOG_DEBUG, "no picture\n");

    }

    if (h->next_output_pic) {

        if (h->next_output_pic->recovered) {

            // We have reached an recovery point and all frames after it in

            // display order are "recovered".

            h->frame_recovered |= FRAME_RECOVERED_SEI;

        }

        h->next_output_pic->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_SEI);

    }

    if (setup_finished && !h->avctx->hwaccel)

        ff_thread_finish_setup(h->avctx);

}


static int str_read_packet(AVFormatContext *s,

                           AVPacket *ret_pkt)

{

    AVIOContext *pb = s->pb;

    StrDemuxContext *str = s->priv_data;

    unsigned char sector[RAW_CD_SECTOR_SIZE];

    int channel;

    AVPacket *pkt;

    AVStream *st;

    while (1) {

        if (avio_read(pb, sector, RAW_CD_SECTOR_SIZE) != RAW_CD_SECTOR_SIZE)

            return AVERROR(EIO);

        channel = sector[0x11];

        if (channel >= 32)

            return AVERROR_INVALIDDATA;

        switch (sector[0x12] & CDXA_TYPE_MASK) {

        case CDXA_TYPE_DATA:

        case CDXA_TYPE_VIDEO:

            {

                int current_sector = AV_RL16(&sector[0x1C]);

                int sector_count   = AV_RL16(&sector[0x1E]);

                int frame_size = AV_RL32(&sector[0x24]);

                if(!(   frame_size>=0

                     && current_sector < sector_count

                     && sector_count*VIDEO_DATA_CHUNK_SIZE >=frame_size)){

                    av_log(s, AV_LOG_ERROR, "Invalid parameters %d %d %d\n", current_sector, sector_count, frame_size);

                    break;

                }

                if(str->channels[channel].video_stream_index < 0){

                    /* allocate a new AVStream */

                    st = avformat_new_stream(s, NULL);

                    if (!st)

                        return AVERROR(ENOMEM);

                    avpriv_set_pts_info(st, 64, 1, 15);

                    str->channels[channel].video_stream_index = st->index;

                    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

                    st->codec->codec_id   = AV_CODEC_ID_MDEC;

                    st->codec->codec_tag  = 0;  /* no fourcc */

                    st->codec->width      = AV_RL16(&sector[0x28]);

                    st->codec->height     = AV_RL16(&sector[0x2A]);

                }

                /* if this is the first sector of the frame, allocate a pkt */

                pkt = &str->channels[channel].tmp_pkt;

                if(pkt->size != sector_count*VIDEO_DATA_CHUNK_SIZE){

                    if(pkt->data)

                        av_log(s, AV_LOG_ERROR, "missmatching sector_count\n");

                    av_free_packet(pkt);

                    if (av_new_packet(pkt, sector_count*VIDEO_DATA_CHUNK_SIZE))

                        return AVERROR(EIO);

                    pkt->pos= avio_tell(pb) - RAW_CD_SECTOR_SIZE;

                    pkt->stream_index =

                        str->channels[channel].video_stream_index;

                }

                memcpy(pkt->data + current_sector*VIDEO_DATA_CHUNK_SIZE,

                       sector + VIDEO_DATA_HEADER_SIZE,

                       VIDEO_DATA_CHUNK_SIZE);

                if (current_sector == sector_count-1) {

                    pkt->size= frame_size;

                    *ret_pkt = *pkt;

                    pkt->data= NULL;

                    pkt->size= -1;

                    pkt->buf = NULL;

#if FF_API_DESTRUCT_PACKET

FF_DISABLE_DEPRECATION_WARNINGS

                    pkt->destruct = NULL;

FF_ENABLE_DEPRECATION_WARNINGS

#endif

                    return 0;

                }

            }

            break;

        case CDXA_TYPE_AUDIO:

            if(str->channels[channel].audio_stream_index < 0){

                int fmt = sector[0x13];

                /* allocate a new AVStream */

                st = avformat_new_stream(s, NULL);

                if (!st)

                    return AVERROR(ENOMEM);

                str->channels[channel].audio_stream_index = st->index;

                st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;

                st->codec->codec_id    = AV_CODEC_ID_ADPCM_XA;

                st->codec->codec_tag   = 0;  /* no fourcc */

                if (fmt & 1) {

                    st->codec->channels       = 2;

                    st->codec->channel_layout = AV_CH_LAYOUT_STEREO;

                } else {

                    st->codec->channels       = 1;

                    st->codec->channel_layout = AV_CH_LAYOUT_MONO;

                }

                st->codec->sample_rate = (fmt&4)?18900:37800;

            //    st->codec->bit_rate = 0; //FIXME;

                st->codec->block_align = 128;

                avpriv_set_pts_info(st, 64, 18 * 224 / st->codec->channels,

                                    st->codec->sample_rate);

                st->start_time = 0;

            }

            pkt = ret_pkt;

            if (av_new_packet(pkt, 2304))

                return AVERROR(EIO);

            memcpy(pkt->data,sector+24,2304);

            pkt->stream_index =

                str->channels[channel].audio_stream_index;

            pkt->duration = 1;

            return 0;

        default:

            av_log(s, AV_LOG_WARNING, "Unknown sector type %02X\n", sector[0x12]);

            /* drop the sector and move on */

            break;

        }

        if (url_feof(pb))

            return AVERROR(EIO);

    }

}


char *object_property_print(Object *obj, const char *name, bool human,

                            Error **errp)

{

    StringOutputVisitor *mo;

    char *string;

    mo = string_output_visitor_new(human);

    object_property_get(obj, string_output_get_visitor(mo), name, errp);

    string = string_output_get_string(mo);

    string_output_visitor_cleanup(mo);

    return string;

}


static void virtio_gpu_resource_create_2d(VirtIOGPU *g,

                                          struct virtio_gpu_ctrl_command *cmd)

{

    pixman_format_code_t pformat;

    struct virtio_gpu_simple_resource *res;

    struct virtio_gpu_resource_create_2d c2d;

    VIRTIO_GPU_FILL_CMD(c2d);

    trace_virtio_gpu_cmd_res_create_2d(c2d.resource_id, c2d.format,

                                       c2d.width, c2d.height);

    if (c2d.resource_id == 0) {

        qemu_log_mask(LOG_GUEST_ERROR, "%s: resource id 0 is not allowed\n",

                      __func__);

        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;

        return;

    }

    res = virtio_gpu_find_resource(g, c2d.resource_id);

    if (res) {

        qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n",

                      __func__, c2d.resource_id);

        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;

        return;

    }

    res = g_new0(struct virtio_gpu_simple_resource, 1);

    res->width = c2d.width;

    res->height = c2d.height;

    res->format = c2d.format;

    res->resource_id = c2d.resource_id;

    pformat = get_pixman_format(c2d.format);

    if (!pformat) {

        qemu_log_mask(LOG_GUEST_ERROR,

                      "%s: host couldn't handle guest format %d\n",

                      __func__, c2d.format);

        g_free(res);

        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;

        return;

    }

    res->image = pixman_image_create_bits(pformat,

                                          c2d.width,

                                          c2d.height,

                                          NULL, 0);

    if (!res->image) {

        qemu_log_mask(LOG_GUEST_ERROR,

                      "%s: resource creation failed %d %d %d\n",

                      __func__, c2d.resource_id, c2d.width, c2d.height);

        g_free(res);

        cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;

        return;

    }

    QTAILQ_INSERT_HEAD(&g->reslist, res, next);

}


int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,

    int nb_clusters)

{

    BDRVQcowState *s = bs->opaque;

    uint64_t cluster_index;

    uint64_t old_free_cluster_index;

    uint64_t i;

    int refcount, ret;

    assert(nb_clusters >= 0);

    if (nb_clusters == 0) {

        return 0;

    }

    /* Check how many clusters there are free */

    cluster_index = offset >> s->cluster_bits;

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

        refcount = get_refcount(bs, cluster_index++);

        if (refcount < 0) {

            return refcount;

        } else if (refcount != 0) {

            break;

        }

    }

    /* And then allocate them */

    old_free_cluster_index = s->free_cluster_index;

    s->free_cluster_index = cluster_index + i;

    ret = update_refcount(bs, offset, i << s->cluster_bits, 1,

                          QCOW2_DISCARD_NEVER);

    if (ret < 0) {

        return ret;

    }

    s->free_cluster_index = old_free_cluster_index;

    return i;

}


static int decode_chunks(AVCodecContext *avctx,
                         AVFrame *picture, int *got_output,
                         const uint8_t *buf, int buf_size)
{
    Mpeg1Context *s = avctx->priv_data;
    MpegEncContext *s2 = &s->mpeg_enc_ctx;
    const uint8_t *buf_ptr = buf;
    const uint8_t *buf_end = buf + buf_size;
    int ret, input_size;
    int last_code = 0, skip_frame = 0;
    int picture_start_code_seen = 0;
    for (;;) {
        /* find next start code */
        uint32_t start_code = -1;
        buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &start_code);
        if (start_code > 0x1ff) {
            if (!skip_frame) {
                if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) &&
                    !avctx->hwaccel) {
                    int i;
                    av_assert0(avctx->thread_count > 1);
                    avctx->execute(avctx, slice_decode_thread,  &s2->thread_context[0], NULL, s->slice_count, sizeof(void*));
                    for (i = 0; i < s->slice_count; i++)
                        s2->er.error_count += s2->thread_context[i]->er.error_count;
                ret = slice_end(avctx, picture);
                if (ret < 0)
                    return ret;
                else if (ret) {
                    if (s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice
                        *got_output = 1;
            s2->pict_type = 0;
            return FFMAX(0, buf_ptr - buf - s2->parse_context.last_index);
        input_size = buf_end - buf_ptr;
        if (avctx->debug & FF_DEBUG_STARTCODE) {
            av_log(avctx, AV_LOG_DEBUG, "%3X at %td left %d\n", start_code, buf_ptr-buf, input_size);
        /* prepare data for next start code */
        switch (start_code) {
        case SEQ_START_CODE:
            if (last_code == 0) {
                mpeg1_decode_sequence(avctx, buf_ptr, input_size);
                if(buf != avctx->extradata)
                    s->sync=1;
            } else {
                av_log(avctx, AV_LOG_ERROR, "ignoring SEQ_START_CODE after %X\n", last_code);
                if (avctx->err_recognition & AV_EF_EXPLODE)
            break;
        case PICTURE_START_CODE:
            if (picture_start_code_seen && s2->picture_structure == PICT_FRAME) {
               /* If it's a frame picture, there can't be more than one picture header.
                  Yet, it does happen and we need to handle it. */
               av_log(avctx, AV_LOG_WARNING, "ignoring extra picture following a frame-picture\n");
               break;
            picture_start_code_seen = 1;
            if (s2->width <= 0 || s2->height <= 0) {
                av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions %dx%d.\n",
                       s2->width, s2->height);
            if(s->tmpgexs){
                s2->intra_dc_precision= 3;
                s2->intra_matrix[0]= 1;
            if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) &&
                !avctx->hwaccel && s->slice_count) {
                int i;
                avctx->execute(avctx, slice_decode_thread,
                               s2->thread_context, NULL,
                               s->slice_count, sizeof(void*));
                for (i = 0; i < s->slice_count; i++)
                    s2->er.error_count += s2->thread_context[i]->er.error_count;
                s->slice_count = 0;
            if (last_code == 0 || last_code == SLICE_MIN_START_CODE) {
                ret = mpeg_decode_postinit(avctx);
                if (ret < 0) {
                    av_log(avctx, AV_LOG_ERROR, "mpeg_decode_postinit() failure\n");
                    return ret;
                /* we have a complete image: we try to decompress it */
                if (mpeg1_decode_picture(avctx, buf_ptr, input_size) < 0)
                    s2->pict_type = 0;
                s2->first_slice = 1;
                last_code = PICTURE_START_CODE;
            } else {
                av_log(avctx, AV_LOG_ERROR, "ignoring pic after %X\n", last_code);
                if (avctx->err_recognition & AV_EF_EXPLODE)
            break;
        case EXT_START_CODE:
            init_get_bits(&s2->gb, buf_ptr, input_size*8);
            switch (get_bits(&s2->gb, 4)) {
            case 0x1:
                if (last_code == 0) {
                mpeg_decode_sequence_extension(s);
                } else {
                    av_log(avctx, AV_LOG_ERROR, "ignoring seq ext after %X\n", last_code);
                    if (avctx->err_recognition & AV_EF_EXPLODE)
                break;
            case 0x2:
                mpeg_decode_sequence_display_extension(s);
                break;
            case 0x3:
                mpeg_decode_quant_matrix_extension(s2);
                break;
            case 0x7:
                mpeg_decode_picture_display_extension(s);
                break;
            case 0x8:
                if (last_code == PICTURE_START_CODE) {
                    mpeg_decode_picture_coding_extension(s);
                } else {
                    av_log(avctx, AV_LOG_ERROR, "ignoring pic cod ext after %X\n", last_code);
                    if (avctx->err_recognition & AV_EF_EXPLODE)
                break;
            break;
        case USER_START_CODE:
            mpeg_decode_user_data(avctx, buf_ptr, input_size);
            break;
        case GOP_START_CODE:
            if (last_code == 0) {
                s2->first_field=0;
                mpeg_decode_gop(avctx, buf_ptr, input_size);
                s->sync=1;
            } else {
                av_log(avctx, AV_LOG_ERROR, "ignoring GOP_START_CODE after %X\n", last_code);
                if (avctx->err_recognition & AV_EF_EXPLODE)
            break;
        default:
            if (start_code >= SLICE_MIN_START_CODE &&
                start_code <= SLICE_MAX_START_CODE && last_code == PICTURE_START_CODE) {
                if (s2->progressive_sequence && !s2->progressive_frame) {
                    s2->progressive_frame = 1;
                    av_log(s2->avctx, AV_LOG_ERROR, "interlaced frame in progressive sequence, ignoring\n");
                if (s2->picture_structure == 0 || (s2->progressive_frame && s2->picture_structure != PICT_FRAME)) {
                    av_log(s2->avctx, AV_LOG_ERROR, "picture_structure %d invalid, ignoring\n", s2->picture_structure);
                    s2->picture_structure = PICT_FRAME;
                if (s2->progressive_sequence && !s2->frame_pred_frame_dct) {
                    av_log(s2->avctx, AV_LOG_WARNING, "invalid frame_pred_frame_dct\n");
                if (s2->picture_structure == PICT_FRAME) {
                    s2->first_field = 0;
                    s2->v_edge_pos  = 16 * s2->mb_height;
                } else {
                    s2->first_field ^= 1;
                    s2->v_edge_pos   = 8 * s2->mb_height;
                    memset(s2->mbskip_table, 0, s2->mb_stride * s2->mb_height);
            if (start_code >= SLICE_MIN_START_CODE &&
                start_code <= SLICE_MAX_START_CODE && last_code != 0) {
                const int field_pic = s2->picture_structure != PICT_FRAME;
                int mb_y = start_code - SLICE_MIN_START_CODE;
                last_code = SLICE_MIN_START_CODE;
                if(s2->codec_id != AV_CODEC_ID_MPEG1VIDEO && s2->mb_height > 2800/16)
                    mb_y += (*buf_ptr&0xE0)<<2;
                mb_y <<= field_pic;
                if (s2->picture_structure == PICT_BOTTOM_FIELD)
                    mb_y++;
                if (mb_y >= s2->mb_height) {
                    av_log(s2->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s2->mb_height);
                    return -1;
                if (s2->last_picture_ptr == NULL) {
                /* Skip B-frames if we do not have reference frames and gop is not closed */
                    if (s2->pict_type == AV_PICTURE_TYPE_B) {
                        if (!s2->closed_gop) {
                            skip_frame = 1;
                            break;
                if (s2->pict_type == AV_PICTURE_TYPE_I || (s2->flags2 & CODEC_FLAG2_SHOW_ALL))
                    s->sync=1;
                if (s2->next_picture_ptr == NULL) {
                /* Skip P-frames if we do not have a reference frame or we have an invalid header. */
                    if (s2->pict_type == AV_PICTURE_TYPE_P && !s->sync) {
                        skip_frame = 1;
                        break;
                if ((avctx->skip_frame >= AVDISCARD_NONREF && s2->pict_type == AV_PICTURE_TYPE_B) ||
                    (avctx->skip_frame >= AVDISCARD_NONKEY && s2->pict_type != AV_PICTURE_TYPE_I) ||
                     avctx->skip_frame >= AVDISCARD_ALL) {
                    skip_frame = 1;
                    break;
                if (!s->mpeg_enc_ctx_allocated)
                    break;
                if (s2->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
                    if (mb_y < avctx->skip_top || mb_y >= s2->mb_height - avctx->skip_bottom)
                        break;
                if (!s2->pict_type) {
                    av_log(avctx, AV_LOG_ERROR, "Missing picture start code\n");
                    if (avctx->err_recognition & AV_EF_EXPLODE)
                    break;
                if (s2->first_slice) {
                    skip_frame = 0;
                    s2->first_slice = 0;
                    if (mpeg_field_start(s2, buf, buf_size) < 0)
                        return -1;
                if (!s2->current_picture_ptr) {
                    av_log(avctx, AV_LOG_ERROR, "current_picture not initialized\n");
                if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) &&
                    !avctx->hwaccel) {
                    int threshold = (s2->mb_height * s->slice_count +
                                     s2->slice_context_count / 2) /
                                    s2->slice_context_count;
                    av_assert0(avctx->thread_count > 1);
                    if (threshold <= mb_y) {
                        MpegEncContext *thread_context = s2->thread_context[s->slice_count];
                        thread_context->start_mb_y = mb_y;
                        thread_context->end_mb_y   = s2->mb_height;
                        if (s->slice_count) {
                            s2->thread_context[s->slice_count-1]->end_mb_y = mb_y;
                            ret = ff_update_duplicate_context(thread_context,
                                                              s2);
                            if (ret < 0)
                                return ret;
                        init_get_bits(&thread_context->gb, buf_ptr, input_size*8);
                        s->slice_count++;
                    buf_ptr += 2; // FIXME add minimum number of bytes per slice
                } else {
                    ret = mpeg_decode_slice(s2, mb_y, &buf_ptr, input_size);
                    emms_c();
                    if (ret < 0) {
                        if (avctx->err_recognition & AV_EF_EXPLODE)
                            return ret;
                        if (s2->resync_mb_x >= 0 && s2->resync_mb_y >= 0)
                            ff_er_add_slice(&s2->er, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x, s2->mb_y, ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR);
                    } else {
                        ff_er_add_slice(&s2->er, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x-1, s2->mb_y, ER_AC_END | ER_DC_END | ER_MV_END);
            break;


static int get_video_frame(VideoState *is, AVFrame *frame)

{

    int got_picture;

    if ((got_picture = decoder_decode_frame(&is->viddec, frame)) < 0)

        return -1;

    if (got_picture) {

        double dpts = NAN;

        if (frame->pts != AV_NOPTS_VALUE)

            dpts = av_q2d(is->video_st->time_base) * frame->pts;

        frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);

        if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {

            if (frame->pts != AV_NOPTS_VALUE) {

                double diff = dpts - get_master_clock(is);

                if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&

                    diff - is->frame_last_filter_delay < 0 &&

                    is->viddec.pkt_serial == is->vidclk.serial &&

                    is->videoq.nb_packets) {

                    is->frame_drops_early++;

                    av_frame_unref(frame);

                    got_picture = 0;

                }

            }

        }

    }

    return got_picture;

}


START_TEST(escaped_string)

{

    int i;

    struct {

        const char *encoded;

        const char *decoded;

        int skip;

    } test_cases[] = {

        { "\"\\\"\"", "\"" },

        { "\"hello world \\\"embedded string\\\"\"",

          "hello world \"embedded string\"" },

        { "\"hello world\\nwith new line\"", "hello world\nwith new line" },

        { "\"single byte utf-8 \\u0020\"", "single byte utf-8  ", .skip = 1 },

        { "\"double byte utf-8 \\u00A2\"", "double byte utf-8 \xc2\xa2" },

        { "\"triple byte utf-8 \\u20AC\"", "triple byte utf-8 \xe2\x82\xac" },

        {}

    };

    for (i = 0; test_cases[i].encoded; i++) {

        QObject *obj;

        QString *str;

        obj = qobject_from_json(test_cases[i].encoded);

        fail_unless(obj != NULL);

        fail_unless(qobject_type(obj) == QTYPE_QSTRING);

        str = qobject_to_qstring(obj);

        fail_unless(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);

        if (test_cases[i].skip == 0) {

            str = qobject_to_json(obj);

            fail_unless(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);

            qobject_decref(obj);

        }

        QDECREF(str);

    }

}


static void pc_dimm_unplug_request(HotplugHandler *hotplug_dev,

                                   DeviceState *dev, Error **errp)

{

    HotplugHandlerClass *hhc;

    Error *local_err = NULL;

    PCMachineState *pcms = PC_MACHINE(hotplug_dev);

    if (!pcms->acpi_dev) {

        error_setg(&local_err,

                   "memory hotplug is not enabled: missing acpi device");

        goto out;

    }

    if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {

        error_setg(&local_err,

                   "nvdimm device hot unplug is not supported yet.");

        goto out;

    }

    hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);

    hhc->unplug_request(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);

out:

    error_propagate(errp, local_err);

}


SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, int unit)

{

    const char *driver;

    DeviceState *dev;

    driver = bdrv_is_sg(bdrv) ? "scsi-generic" : "scsi-disk";

    dev = qdev_create(&bus->qbus, driver);

    qdev_prop_set_uint32(dev, "scsi-id", unit);

    if (qdev_prop_set_drive(dev, "drive", bdrv) < 0) {

        qdev_free(dev);

        return NULL;

    }

    if (qdev_init(dev) < 0)

        return NULL;

    return DO_UPCAST(SCSIDevice, qdev, dev);

}


NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,

                          uint32_t nbdflags, void (*close)(NBDExport *),

                          Error **errp)

{

    NBDExport *exp = g_malloc0(sizeof(NBDExport));

    exp->refcount = 1;

    QTAILQ_INIT(&exp->clients);

    exp->blk = blk;

    exp->dev_offset = dev_offset;

    exp->nbdflags = nbdflags;

    exp->size = size < 0 ? blk_getlength(blk) : size;

    if (exp->size < 0) {

        error_setg_errno(errp, -exp->size,

                         "Failed to determine the NBD export's length");

        goto fail;

    }

    exp->size -= exp->size % BDRV_SECTOR_SIZE;

    exp->close = close;

    exp->ctx = blk_get_aio_context(blk);

    blk_ref(blk);

    blk_add_aio_context_notifier(blk, blk_aio_attached, blk_aio_detach, exp);

    exp->eject_notifier.notify = nbd_eject_notifier;

    blk_add_remove_bs_notifier(blk, &exp->eject_notifier);

    /*

     * NBD exports are used for non-shared storage migration.  Make sure

     * that BDRV_O_INACTIVE is cleared and the image is ready for write

     * access since the export could be available before migration handover.

     */

    aio_context_acquire(exp->ctx);

    blk_invalidate_cache(blk, NULL);

    aio_context_release(exp->ctx);

    return exp;

fail:

    g_free(exp);

    return NULL;

}


static int bdrv_qed_open(BlockDriverState *bs, int flags)

{

    BDRVQEDState *s = bs->opaque;

    QEDHeader le_header;

    int64_t file_size;

    int ret;

    s->bs = bs;

    QSIMPLEQ_INIT(&s->allocating_write_reqs);

    ret = bdrv_pread(bs->file, 0, &le_header, sizeof(le_header));

    if (ret < 0) {

        return ret;

    }

    qed_header_le_to_cpu(&le_header, &s->header);

    if (s->header.magic != QED_MAGIC) {

        return -EINVAL;

    }

    if (s->header.features & ~QED_FEATURE_MASK) {

        /* image uses unsupported feature bits */

        char buf[64];

        snprintf(buf, sizeof(buf), "%" PRIx64,

            s->header.features & ~QED_FEATURE_MASK);

        qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,

            bs->device_name, "QED", buf);

        return -ENOTSUP;

    }

    if (!qed_is_cluster_size_valid(s->header.cluster_size)) {

        return -EINVAL;

    }

    /* Round down file size to the last cluster */

    file_size = bdrv_getlength(bs->file);

    if (file_size < 0) {

        return file_size;

    }

    s->file_size = qed_start_of_cluster(s, file_size);

    if (!qed_is_table_size_valid(s->header.table_size)) {

        return -EINVAL;

    }

    if (!qed_is_image_size_valid(s->header.image_size,

                                 s->header.cluster_size,

                                 s->header.table_size)) {

        return -EINVAL;

    }

    if (!qed_check_table_offset(s, s->header.l1_table_offset)) {

        return -EINVAL;

    }

    s->table_nelems = (s->header.cluster_size * s->header.table_size) /

                      sizeof(uint64_t);

    s->l2_shift = ffs(s->header.cluster_size) - 1;

    s->l2_mask = s->table_nelems - 1;

    s->l1_shift = s->l2_shift + ffs(s->table_nelems) - 1;

    if ((s->header.features & QED_F_BACKING_FILE)) {

        if ((uint64_t)s->header.backing_filename_offset +

            s->header.backing_filename_size >

            s->header.cluster_size * s->header.header_size) {

            return -EINVAL;

        }

        ret = qed_read_string(bs->file, s->header.backing_filename_offset,

                              s->header.backing_filename_size, bs->backing_file,

                              sizeof(bs->backing_file));

        if (ret < 0) {

            return ret;

        }

        if (s->header.features & QED_F_BACKING_FORMAT_NO_PROBE) {

            pstrcpy(bs->backing_format, sizeof(bs->backing_format), "raw");

        }

    }

    /* Reset unknown autoclear feature bits.  This is a backwards

     * compatibility mechanism that allows images to be opened by older

     * programs, which "knock out" unknown feature bits.  When an image is

     * opened by a newer program again it can detect that the autoclear

     * feature is no longer valid.

     */

    if ((s->header.autoclear_features & ~QED_AUTOCLEAR_FEATURE_MASK) != 0 &&

        !bdrv_is_read_only(bs->file) && !(flags & BDRV_O_INCOMING)) {

        s->header.autoclear_features &= QED_AUTOCLEAR_FEATURE_MASK;

        ret = qed_write_header_sync(s);

        if (ret) {

            return ret;

        }

        /* From here on only known autoclear feature bits are valid */

        bdrv_flush(bs->file);

    }

    s->l1_table = qed_alloc_table(s);

    qed_init_l2_cache(&s->l2_cache);

    ret = qed_read_l1_table_sync(s);

    if (ret) {

        goto out;

    }

    /* If image was not closed cleanly, check consistency */

    if (s->header.features & QED_F_NEED_CHECK) {

        /* Read-only images cannot be fixed.  There is no risk of corruption

         * since write operations are not possible.  Therefore, allow

         * potentially inconsistent images to be opened read-only.  This can

         * aid data recovery from an otherwise inconsistent image.

         */

        if (!bdrv_is_read_only(bs->file) &&

            !(flags & BDRV_O_INCOMING)) {

            BdrvCheckResult result = {0};

            ret = qed_check(s, &result, true);

            if (ret) {

                goto out;

            }

        }

    }

    s->need_check_timer = qemu_new_timer_ns(vm_clock,

                                            qed_need_check_timer_cb, s);

out:

    if (ret) {

        qed_free_l2_cache(&s->l2_cache);

        qemu_vfree(s->l1_table);

    }

    return ret;

}


static void test_io_channel_unix(bool async)

{

    SocketAddress *listen_addr = g_new0(SocketAddress, 1);

    SocketAddress *connect_addr = g_new0(SocketAddress, 1);

#define TEST_SOCKET "test-io-channel-socket.sock"

    listen_addr->type = SOCKET_ADDRESS_KIND_UNIX;

    listen_addr->u.q_unix = g_new0(UnixSocketAddress, 1);

    listen_addr->u.q_unix->path = g_strdup(TEST_SOCKET);

    connect_addr->type = SOCKET_ADDRESS_KIND_UNIX;

    connect_addr->u.q_unix = g_new0(UnixSocketAddress, 1);

    connect_addr->u.q_unix->path = g_strdup(TEST_SOCKET);

    test_io_channel(async, listen_addr, connect_addr, true);

    qapi_free_SocketAddress(listen_addr);

    qapi_free_SocketAddress(connect_addr);

    unlink(TEST_SOCKET);

}


static void test_visitor_in_native_list_bool(TestInputVisitorData *data,

                                            const void *unused)

{

    UserDefNativeListUnion *cvalue = NULL;

    boolList *elem = NULL;

    Visitor *v;

    GString *gstr_list = g_string_new("");

    GString *gstr_union = g_string_new("");

    int i;

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

        g_string_append_printf(gstr_list, "%s",

                               (i % 3 == 0) ? "true" : "false");

        if (i != 31) {

            g_string_append(gstr_list, ", ");

        }

    }

    g_string_append_printf(gstr_union,  "{ 'type': 'boolean', 'data': [ %s ] }",

                           gstr_list->str);

    v = visitor_input_test_init_raw(data,  gstr_union->str);

    visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);

    g_assert(cvalue != NULL);

    g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);

    for (i = 0, elem = cvalue->u.boolean.data; elem; elem = elem->next, i++) {

        g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);

    }

    g_string_free(gstr_union, true);

    g_string_free(gstr_list, true);

    qapi_free_UserDefNativeListUnion(cvalue);

}


static void init_quantized_coeffs_elem0 (int8_t *quantized_coeffs, GetBitContext *gb, int length)

{

    int i, k, run, level, diff;

    if (BITS_LEFT(length,gb) < 16)

        return;

    level = qdm2_get_vlc(gb, &vlc_tab_level, 0, 2);

    quantized_coeffs[0] = level;

    for (i = 0; i < 7; ) {

        if (BITS_LEFT(length,gb) < 16)

            break;

        run = qdm2_get_vlc(gb, &vlc_tab_run, 0, 1) + 1;

        if (BITS_LEFT(length,gb) < 16)

            break;

        diff = qdm2_get_se_vlc(&vlc_tab_diff, gb, 2);

        for (k = 1; k <= run; k++)

            quantized_coeffs[i + k] = (level + ((k * diff) / run));

        level += diff;

        i += run;

    }

}


QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,

                          QEMUTimerCB *cb, void *opaque)

{

    return g_malloc(1);

}


static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)

{

    /* FMOV: gpr to or from float, double, or top half of quad fp reg,

     * without conversion.

     */

    if (itof) {

        TCGv_i64 tcg_rn = cpu_reg(s, rn);

        switch (type) {

        case 0:

        {

            /* 32 bit */

            TCGv_i64 tmp = tcg_temp_new_i64();

            tcg_gen_ext32u_i64(tmp, tcg_rn);

            tcg_gen_st_i64(tmp, cpu_env, fp_reg_offset(rd, MO_64));

            tcg_gen_movi_i64(tmp, 0);

            tcg_gen_st_i64(tmp, cpu_env, fp_reg_hi_offset(rd));

            tcg_temp_free_i64(tmp);

            break;

        }

        case 1:

        {

            /* 64 bit */

            TCGv_i64 tmp = tcg_const_i64(0);

            tcg_gen_st_i64(tcg_rn, cpu_env, fp_reg_offset(rd, MO_64));

            tcg_gen_st_i64(tmp, cpu_env, fp_reg_hi_offset(rd));

            tcg_temp_free_i64(tmp);

            break;

        }

        case 2:

            /* 64 bit to top half. */

            tcg_gen_st_i64(tcg_rn, cpu_env, fp_reg_hi_offset(rd));

            break;

        }

    } else {

        TCGv_i64 tcg_rd = cpu_reg(s, rd);

        switch (type) {

        case 0:

            /* 32 bit */

            tcg_gen_ld32u_i64(tcg_rd, cpu_env, fp_reg_offset(rn, MO_32));

            break;

        case 1:

            /* 64 bit */

            tcg_gen_ld_i64(tcg_rd, cpu_env, fp_reg_offset(rn, MO_64));

            break;

        case 2:

            /* 64 bits from top half */

            tcg_gen_ld_i64(tcg_rd, cpu_env, fp_reg_hi_offset(rn));

            break;

        }

    }

}


static void coroutine_fn bdrv_discard_co_entry(void *opaque)

{

    DiscardCo *rwco = opaque;

    rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, rwco->nb_sectors);

}


static uint64_t escc_mem_read(void *opaque, target_phys_addr_t addr,

                              unsigned size)

{

    SerialState *serial = opaque;

    ChannelState *s;

    uint32_t saddr;

    uint32_t ret;

    int channel;

    saddr = (addr >> serial->it_shift) & 1;

    channel = (addr >> (serial->it_shift + 1)) & 1;

    s = &serial->chn[channel];

    switch (saddr) {

    case SERIAL_CTRL:

        trace_escc_mem_readb_ctrl(CHN_C(s), s->reg, s->rregs[s->reg]);

        ret = s->rregs[s->reg];

        s->reg = 0;

        return ret;

    case SERIAL_DATA:

        s->rregs[R_STATUS] &= ~STATUS_RXAV;

        clr_rxint(s);

        if (s->type == kbd || s->type == mouse)

            ret = get_queue(s);

        else

            ret = s->rx;

        trace_escc_mem_readb_data(CHN_C(s), ret);

        if (s->chr)

            qemu_chr_accept_input(s->chr);

        return ret;

    default:

        break;

    }

    return 0;

}


static int proxy_parse_opts(QemuOpts *opts, struct FsDriverEntry *fs)

{

    const char *socket = qemu_opt_get(opts, "socket");

    const char *sock_fd = qemu_opt_get(opts, "sock_fd");

    if (!socket && !sock_fd) {

        fprintf(stderr, "socket and sock_fd none of the option specified\n");

        return -1;

    }

    if (socket && sock_fd) {

        fprintf(stderr, "Both socket and sock_fd options specified\n");

        return -1;

    }

    if (socket) {

        fs->path = g_strdup(socket);

        fs->export_flags = V9FS_PROXY_SOCK_NAME;

    } else {

        fs->path = g_strdup(sock_fd);

        fs->export_flags = V9FS_PROXY_SOCK_FD;

    }

    return 0;

}


static void bdrv_co_io_em_complete(void *opaque, int ret)

{

    CoroutineIOCompletion *co = opaque;

    co->ret = ret;

    qemu_coroutine_enter(co->coroutine, NULL);

}


START_TEST(qobject_to_qdict_test)

{

    fail_unless(qobject_to_qdict(QOBJECT(tests_dict)) == tests_dict);

}


static int mmu_translate_pte(CPUS390XState *env, target_ulong vaddr,

                             uint64_t asc, uint64_t asce,

                             target_ulong *raddr, int *flags, int rw)

{

    if (asce & _PAGE_INVALID) {

        DPRINTF("%s: PTE=0x%" PRIx64 " invalid\n", __func__, asce);

        trigger_page_fault(env, vaddr, PGM_PAGE_TRANS, asc, rw);

        return -1;

    }

    if (asce & _PAGE_RO) {

        *flags &= ~PAGE_WRITE;

    }

    *raddr = asce & _ASCE_ORIGIN;

    PTE_DPRINTF("%s: PTE=0x%" PRIx64 "\n", __func__, asce);

    return 0;

}


static uint64_t qvirtio_scsi_alloc(QVirtIOSCSI *vs, size_t alloc_size,

                                   const void *data)

{

    uint64_t addr;

    addr = guest_alloc(vs->alloc, alloc_size);

    if (data) {

        memwrite(addr, data, alloc_size);

    }

    return addr;

}


guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,

                            GIOFunc func, void *user_data)

{

    GSource *src;

    guint tag;

    if (s->chr_add_watch == NULL) {

        return -ENOSYS;

    }

    src = s->chr_add_watch(s, cond);

    g_source_set_callback(src, (GSourceFunc)func, user_data, NULL);

    tag = g_source_attach(src, NULL);

    g_source_unref(src);

    return tag;

}


static void notdirty_mem_write(void *opaque, target_phys_addr_t ram_addr,

                               uint64_t val, unsigned size)

{

    int dirty_flags;

    dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);

    if (!(dirty_flags & CODE_DIRTY_FLAG)) {

#if !defined(CONFIG_USER_ONLY)

        tb_invalidate_phys_page_fast(ram_addr, size);

        dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);

#endif

    }

    switch (size) {

    case 1:

        stb_p(qemu_get_ram_ptr(ram_addr), val);

        break;

    case 2:

        stw_p(qemu_get_ram_ptr(ram_addr), val);

        break;

    case 4:

        stl_p(qemu_get_ram_ptr(ram_addr), val);

        break;

    default:

        abort();

    }

    dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);

    cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags);

    /* we remove the notdirty callback only if the code has been

       flushed */

    if (dirty_flags == 0xff)

        tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr);

}


static void v9fs_xattrwalk(void *opaque)

{

    int64_t size;

    V9fsString name;

    ssize_t err = 0;

    size_t offset = 7;

    int32_t fid, newfid;

    V9fsFidState *file_fidp;

    V9fsFidState *xattr_fidp = NULL;

    V9fsPDU *pdu = opaque;

    V9fsState *s = pdu->s;

    pdu_unmarshal(pdu, offset, "dds", &fid, &newfid, &name);

    trace_v9fs_xattrwalk(pdu->tag, pdu->id, fid, newfid, name.data);

    file_fidp = get_fid(pdu, fid);

    if (file_fidp == NULL) {

        err = -ENOENT;

        goto out_nofid;

    }

    xattr_fidp = alloc_fid(s, newfid);

    if (xattr_fidp == NULL) {

        err = -EINVAL;

        goto out;

    }

    v9fs_path_copy(&xattr_fidp->path, &file_fidp->path);

    if (name.data[0] == 0) {

        /*

         * listxattr request. Get the size first

         */

        size = v9fs_co_llistxattr(pdu, &xattr_fidp->path, NULL, 0);

        if (size < 0) {

            err = size;

            clunk_fid(s, xattr_fidp->fid);

            goto out;

        }

        /*

         * Read the xattr value

         */

        xattr_fidp->fs.xattr.len = size;

        xattr_fidp->fid_type = P9_FID_XATTR;

        xattr_fidp->fs.xattr.copied_len = -1;

        if (size) {

            xattr_fidp->fs.xattr.value = g_malloc(size);

            err = v9fs_co_llistxattr(pdu, &xattr_fidp->path,

                                     xattr_fidp->fs.xattr.value,

                                     xattr_fidp->fs.xattr.len);

            if (err < 0) {

                clunk_fid(s, xattr_fidp->fid);

                goto out;

            }

        }

        offset += pdu_marshal(pdu, offset, "q", size);

        err = offset;

    } else {

        /*

         * specific xattr fid. We check for xattr

         * presence also collect the xattr size

         */

        size = v9fs_co_lgetxattr(pdu, &xattr_fidp->path,

                                 &name, NULL, 0);

        if (size < 0) {

            err = size;

            clunk_fid(s, xattr_fidp->fid);

            goto out;

        }

        /*

         * Read the xattr value

         */

        xattr_fidp->fs.xattr.len = size;

        xattr_fidp->fid_type = P9_FID_XATTR;

        xattr_fidp->fs.xattr.copied_len = -1;

        if (size) {

            xattr_fidp->fs.xattr.value = g_malloc(size);

            err = v9fs_co_lgetxattr(pdu, &xattr_fidp->path,

                                    &name, xattr_fidp->fs.xattr.value,

                                    xattr_fidp->fs.xattr.len);

            if (err < 0) {

                clunk_fid(s, xattr_fidp->fid);

                goto out;

            }

        }

        offset += pdu_marshal(pdu, offset, "q", size);

        err = offset;

    }

    trace_v9fs_xattrwalk_return(pdu->tag, pdu->id, size);

out:

    put_fid(pdu, file_fidp);

    if (xattr_fidp) {

        put_fid(pdu, xattr_fidp);

    }

out_nofid:

    complete_pdu(s, pdu, err);

    v9fs_string_free(&name);

}


void kvm_cpu_synchronize_state(CPUState *env)

{

    if (!env->kvm_vcpu_dirty)

        run_on_cpu(env, do_kvm_cpu_synchronize_state, env);

}


static void virtio_blk_rw_complete(void *opaque, int ret)

{

    VirtIOBlockReq *req = opaque;

    trace_virtio_blk_rw_complete(req, ret);

    if (ret) {

        int p = virtio_ldl_p(VIRTIO_DEVICE(req->dev), &req->out.type);

        bool is_read = !(p & VIRTIO_BLK_T_OUT);

        if (virtio_blk_handle_rw_error(req, -ret, is_read))

            return;

    }

    virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);

    block_acct_done(bdrv_get_stats(req->dev->bs), &req->acct);

    virtio_blk_free_request(req);

}


void qmp_migrate_set_parameters(MigrationParameters *params, Error **errp)

{

    MigrationState *s = migrate_get_current();

    if (params->has_compress_level &&

        (params->compress_level < 0 || params->compress_level > 9)) {

        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level",

                   "is invalid, it should be in the range of 0 to 9");

        return;

    }

    if (params->has_compress_threads &&

        (params->compress_threads < 1 || params->compress_threads > 255)) {

        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,

                   "compress_threads",

                   "is invalid, it should be in the range of 1 to 255");

        return;

    }

    if (params->has_decompress_threads &&

        (params->decompress_threads < 1 || params->decompress_threads > 255)) {

        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,

                   "decompress_threads",

                   "is invalid, it should be in the range of 1 to 255");

        return;

    }

    if (params->has_cpu_throttle_initial &&

        (params->cpu_throttle_initial < 1 ||

         params->cpu_throttle_initial > 99)) {

        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,

                   "cpu_throttle_initial",

                   "an integer in the range of 1 to 99");

        return;

    }

    if (params->has_cpu_throttle_increment &&

        (params->cpu_throttle_increment < 1 ||

         params->cpu_throttle_increment > 99)) {

        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,

                   "cpu_throttle_increment",

                   "an integer in the range of 1 to 99");

        return;

    }

    if (params->has_max_bandwidth &&

        (params->max_bandwidth < 0 || params->max_bandwidth > SIZE_MAX)) {

        error_setg(errp, "Parameter 'max_bandwidth' expects an integer in the"

                         " range of 0 to %zu bytes/second", SIZE_MAX);

        return;

    }

    if (params->has_downtime_limit &&

        (params->downtime_limit < 0 || params->downtime_limit > 2000000)) {

        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,

                   "downtime_limit",

                   "an integer in the range of 0 to 2000000 milliseconds");

        return;

    }

    if (params->has_x_checkpoint_delay && (params->x_checkpoint_delay < 0)) {

        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,

                    "x_checkpoint_delay",

                    "is invalid, it should be positive");

    }

    if (params->has_compress_level) {

        s->parameters.compress_level = params->compress_level;

    }

    if (params->has_compress_threads) {

        s->parameters.compress_threads = params->compress_threads;

    }

    if (params->has_decompress_threads) {

        s->parameters.decompress_threads = params->decompress_threads;

    }

    if (params->has_cpu_throttle_initial) {

        s->parameters.cpu_throttle_initial = params->cpu_throttle_initial;

    }

    if (params->has_cpu_throttle_increment) {

        s->parameters.cpu_throttle_increment = params->cpu_throttle_increment;

    }

    if (params->has_tls_creds) {

        g_free(s->parameters.tls_creds);

        s->parameters.tls_creds = g_strdup(params->tls_creds);

    }

    if (params->has_tls_hostname) {

        g_free(s->parameters.tls_hostname);

        s->parameters.tls_hostname = g_strdup(params->tls_hostname);

    }

    if (params->has_max_bandwidth) {

        s->parameters.max_bandwidth = params->max_bandwidth;

        if (s->to_dst_file) {

            qemu_file_set_rate_limit(s->to_dst_file,

                                s->parameters.max_bandwidth / XFER_LIMIT_RATIO);

        }

    }

    if (params->has_downtime_limit) {

        s->parameters.downtime_limit = params->downtime_limit;

    }

    if (params->has_x_checkpoint_delay) {

        s->parameters.x_checkpoint_delay = params->x_checkpoint_delay;

        if (migration_in_colo_state()) {

            colo_checkpoint_notify(s);

        }

    }

}


uint64_t HELPER(lpq)(CPUS390XState *env, uint64_t addr)

{

    uintptr_t ra = GETPC();

    uint64_t hi, lo;

    if (parallel_cpus) {

#ifndef CONFIG_ATOMIC128

        cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);

#else

        int mem_idx = cpu_mmu_index(env, false);

        TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);

        Int128 v = helper_atomic_ldo_be_mmu(env, addr, oi, ra);

        hi = int128_gethi(v);

        lo = int128_getlo(v);

#endif

    } else {

        check_alignment(env, addr, 16, ra);

        hi = cpu_ldq_data_ra(env, addr + 0, ra);

        lo = cpu_ldq_data_ra(env, addr + 8, ra);

    }

    env->retxl = lo;

    return hi;

}


void breakpoint_handler(CPUState *cs)

{

    X86CPU *cpu = X86_CPU(cs);

    CPUX86State *env = &cpu->env;

    CPUBreakpoint *bp;

    if (cs->watchpoint_hit) {

        if (cs->watchpoint_hit->flags & BP_CPU) {

            cs->watchpoint_hit = NULL;

            if (check_hw_breakpoints(env, false)) {

                raise_exception(env, EXCP01_DB);

            } else {

                cpu_resume_from_signal(cs, NULL);

            }

        }

    } else {

        QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {

            if (bp->pc == env->eip) {

                if (bp->flags & BP_CPU) {

                    check_hw_breakpoints(env, true);

                    raise_exception(env, EXCP01_DB);

                }

                break;

            }

        }

    }

}


static void start_output(DBDMA_channel *ch, int key, uint32_t addr,

                        uint16_t req_count, int is_last)

{

    DBDMA_DPRINTF("start_output\n");

    /* KEY_REGS, KEY_DEVICE and KEY_STREAM

     * are not implemented in the mac-io chip

     */

    DBDMA_DPRINTF("addr 0x%x key 0x%x\n", addr, key);

    if (!addr || key > KEY_STREAM3) {

        kill_channel(ch);

        return;

    }

    ch->io.addr = addr;

    ch->io.len = req_count;

    ch->io.is_last = is_last;

    ch->io.dma_end = dbdma_end;

    ch->io.is_dma_out = 1;

    ch->processing = 1;

    ch->rw(&ch->io);

}


static void FUNCC(pred8x8_dc)(uint8_t *_src, int stride){

    int i;

    int dc0, dc1, dc2;

    pixel4 dc0splat, dc1splat, dc2splat, dc3splat;

    pixel *src = (pixel*)_src;

    stride /= sizeof(pixel);

    dc0=dc1=dc2=0;

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

        dc0+= src[-1+i*stride] + src[i-stride];

        dc1+= src[4+i-stride];

        dc2+= src[-1+(i+4)*stride];

    }

    dc0splat = PIXEL_SPLAT_X4((dc0 + 4)>>3);

    dc1splat = PIXEL_SPLAT_X4((dc1 + 2)>>2);

    dc2splat = PIXEL_SPLAT_X4((dc2 + 2)>>2);

    dc3splat = PIXEL_SPLAT_X4((dc1 + dc2 + 4)>>3);

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

        ((pixel4*)(src+i*stride))[0]= dc0splat;

        ((pixel4*)(src+i*stride))[1]= dc1splat;

    }

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

        ((pixel4*)(src+i*stride))[0]= dc2splat;

        ((pixel4*)(src+i*stride))[1]= dc3splat;

    }

}


static int print_int32(DeviceState *dev, Property *prop, char *dest, size_t len)

{

    int32_t *ptr = qdev_get_prop_ptr(dev, prop);

    return snprintf(dest, len, "%" PRId32, *ptr);

}