static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)

{

    CPUState *cs = CPU(cpu);

    CPUPPCState *env = &cpu->env;

    target_ulong msr, new_msr, vector;

    int srr0, srr1, asrr0, asrr1;

    int lpes0, lpes1, lev, ail;

    if (0) {

        /* XXX: find a suitable condition to enable the hypervisor mode */

        lpes0 = (env->spr[SPR_LPCR] >> 1) & 1;

        lpes1 = (env->spr[SPR_LPCR] >> 2) & 1;

    } else {

        /* Those values ensure we won't enter the hypervisor mode */

        lpes0 = 0;

        lpes1 = 1;

    }

    qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx

                  " => %08x (%02x)\n", env->nip, excp, env->error_code);

    /* new srr1 value excluding must-be-zero bits */

    if (excp_model == POWERPC_EXCP_BOOKE) {

        msr = env->msr;

    } else {

        msr = env->msr & ~0x783f0000ULL;

    }

    /* new interrupt handler msr */

    new_msr = env->msr & ((target_ulong)1 << MSR_ME);

    /* target registers */

    srr0 = SPR_SRR0;

    srr1 = SPR_SRR1;

    asrr0 = -1;

    asrr1 = -1;

    /* Exception targetting modifiers

     *

     * AIL is initialized here but can be cleared by

     * selected exceptions

     */

#if defined(TARGET_PPC64)

    if (excp_model == POWERPC_EXCP_POWER7 ||

        excp_model == POWERPC_EXCP_POWER8) {

        if (excp_model == POWERPC_EXCP_POWER8) {

            ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;

        } else {

            ail = 0;

        }

    } else

#endif /* defined(TARGET_PPC64) */

    {

        ail = 0;

    }

    switch (excp) {

    case POWERPC_EXCP_NONE:

        /* Should never happen */

        return;

    case POWERPC_EXCP_CRITICAL:    /* Critical input                         */

        switch (excp_model) {

        case POWERPC_EXCP_40x:

            srr0 = SPR_40x_SRR2;

            srr1 = SPR_40x_SRR3;

            break;

        case POWERPC_EXCP_BOOKE:

            srr0 = SPR_BOOKE_CSRR0;

            srr1 = SPR_BOOKE_CSRR1;

            break;

        case POWERPC_EXCP_G2:

            break;

        default:

            goto excp_invalid;

        }

        goto store_next;

    case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */

        if (msr_me == 0) {

            /* Machine check exception is not enabled.

             * Enter checkstop state.

             */

            fprintf(stderr, "Machine check while not allowed. "

                    "Entering checkstop state\n");

            if (qemu_log_separate()) {

                qemu_log("Machine check while not allowed. "

                        "Entering checkstop state\n");

            }

            cs->halted = 1;

            cs->interrupt_request |= CPU_INTERRUPT_EXITTB;

        }

        if (0) {

            /* XXX: find a suitable condition to enable the hypervisor mode */

            new_msr |= (target_ulong)MSR_HVB;

        }

        ail = 0;

        /* machine check exceptions don't have ME set */

        new_msr &= ~((target_ulong)1 << MSR_ME);

        /* XXX: should also have something loaded in DAR / DSISR */

        switch (excp_model) {

        case POWERPC_EXCP_40x:

            srr0 = SPR_40x_SRR2;

            srr1 = SPR_40x_SRR3;

            break;

        case POWERPC_EXCP_BOOKE:

            /* FIXME: choose one or the other based on CPU type */

            srr0 = SPR_BOOKE_MCSRR0;

            srr1 = SPR_BOOKE_MCSRR1;

            asrr0 = SPR_BOOKE_CSRR0;

            asrr1 = SPR_BOOKE_CSRR1;

            break;

        default:

            break;

        }

        goto store_next;

    case POWERPC_EXCP_DSI:       /* Data storage exception                   */

        LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx

                 "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);

        if (lpes1 == 0) {

            new_msr |= (target_ulong)MSR_HVB;

        }

        goto store_next;

    case POWERPC_EXCP_ISI:       /* Instruction storage exception            */

        LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx

                 "\n", msr, env->nip);

        if (lpes1 == 0) {

            new_msr |= (target_ulong)MSR_HVB;

        }

        msr |= env->error_code;

        goto store_next;

    case POWERPC_EXCP_EXTERNAL:  /* External input                           */

        cs = CPU(cpu);

        if (lpes0 == 1) {

            new_msr |= (target_ulong)MSR_HVB;

        }

        if (env->mpic_proxy) {

            /* IACK the IRQ on delivery */

            env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);

        }

        goto store_next;

    case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */

        if (lpes1 == 0) {

            new_msr |= (target_ulong)MSR_HVB;

        }

        /* XXX: this is false */

        /* Get rS/rD and rA from faulting opcode */

        env->spr[SPR_DSISR] |= (cpu_ldl_code(env, (env->nip - 4))

                                & 0x03FF0000) >> 16;

        goto store_next;

    case POWERPC_EXCP_PROGRAM:   /* Program exception                        */

        switch (env->error_code & ~0xF) {

        case POWERPC_EXCP_FP:

            if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {

                LOG_EXCP("Ignore floating point exception\n");

                cs->exception_index = POWERPC_EXCP_NONE;

                env->error_code = 0;

                return;

            }

            if (lpes1 == 0) {

                new_msr |= (target_ulong)MSR_HVB;

            }

            msr |= 0x00100000;

            if (msr_fe0 == msr_fe1) {

                goto store_next;

            }

            msr |= 0x00010000;

            break;

        case POWERPC_EXCP_INVAL:

            LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);

            if (lpes1 == 0) {

                new_msr |= (target_ulong)MSR_HVB;

            }

            msr |= 0x00080000;

            env->spr[SPR_BOOKE_ESR] = ESR_PIL;

            break;

        case POWERPC_EXCP_PRIV:

            if (lpes1 == 0) {

                new_msr |= (target_ulong)MSR_HVB;

            }

            msr |= 0x00040000;

            env->spr[SPR_BOOKE_ESR] = ESR_PPR;

            break;

        case POWERPC_EXCP_TRAP:

            if (lpes1 == 0) {

                new_msr |= (target_ulong)MSR_HVB;

            }

            msr |= 0x00020000;

            env->spr[SPR_BOOKE_ESR] = ESR_PTR;

            break;

        default:

            /* Should never occur */

            cpu_abort(cs, "Invalid program exception %d. Aborting\n",

                      env->error_code);

            break;

        }

        goto store_current;

    case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */

        if (lpes1 == 0) {

            new_msr |= (target_ulong)MSR_HVB;

        }

        goto store_current;

    case POWERPC_EXCP_SYSCALL:   /* System call exception                    */

        dump_syscall(env);

        lev = env->error_code;

        if ((lev == 1) && cpu_ppc_hypercall) {

            cpu_ppc_hypercall(cpu);

            return;

        }

        if (lev == 1 || (lpes0 == 0 && lpes1 == 0)) {

            new_msr |= (target_ulong)MSR_HVB;

        }

        goto store_next;

    case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */

        goto store_current;

    case POWERPC_EXCP_DECR:      /* Decrementer exception                    */

        if (lpes1 == 0) {

            new_msr |= (target_ulong)MSR_HVB;

        }

        goto store_next;

    case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */

        /* FIT on 4xx */

        LOG_EXCP("FIT exception\n");

        goto store_next;

    case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */

        LOG_EXCP("WDT exception\n");

        switch (excp_model) {

        case POWERPC_EXCP_BOOKE:

            srr0 = SPR_BOOKE_CSRR0;

            srr1 = SPR_BOOKE_CSRR1;

            break;

        default:

            break;

        }

        goto store_next;

    case POWERPC_EXCP_DTLB:      /* Data TLB error                           */

        goto store_next;

    case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */

        goto store_next;

    case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */

        switch (excp_model) {

        case POWERPC_EXCP_BOOKE:

            /* FIXME: choose one or the other based on CPU type */

            srr0 = SPR_BOOKE_DSRR0;

            srr1 = SPR_BOOKE_DSRR1;

            asrr0 = SPR_BOOKE_CSRR0;

            asrr1 = SPR_BOOKE_CSRR1;

            break;

        default:

            break;

        }

        /* XXX: TODO */

        cpu_abort(cs, "Debug exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_SPEU:      /* SPE/embedded floating-point unavailable  */

        env->spr[SPR_BOOKE_ESR] = ESR_SPV;

        goto store_current;

    case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */

        /* XXX: TODO */

        cpu_abort(cs, "Embedded floating point data exception "

                  "is not implemented yet !\n");

        env->spr[SPR_BOOKE_ESR] = ESR_SPV;

        goto store_next;

    case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */

        /* XXX: TODO */

        cpu_abort(cs, "Embedded floating point round exception "

                  "is not implemented yet !\n");

        env->spr[SPR_BOOKE_ESR] = ESR_SPV;

        goto store_next;

    case POWERPC_EXCP_EPERFM:    /* Embedded performance monitor interrupt   */

        /* XXX: TODO */

        cpu_abort(cs,

                  "Performance counter exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_DOORI:     /* Embedded doorbell interrupt              */

        goto store_next;

    case POWERPC_EXCP_DOORCI:    /* Embedded doorbell critical interrupt     */

        srr0 = SPR_BOOKE_CSRR0;

        srr1 = SPR_BOOKE_CSRR1;

        goto store_next;

    case POWERPC_EXCP_RESET:     /* System reset exception                   */

        if (msr_pow) {

            /* indicate that we resumed from power save mode */

            msr |= 0x10000;

        } else {

            new_msr &= ~((target_ulong)1 << MSR_ME);

        }

        if (0) {

            /* XXX: find a suitable condition to enable the hypervisor mode */

            new_msr |= (target_ulong)MSR_HVB;

        }

        ail = 0;

        goto store_next;

    case POWERPC_EXCP_DSEG:      /* Data segment exception                   */

        if (lpes1 == 0) {

            new_msr |= (target_ulong)MSR_HVB;

        }

        goto store_next;

    case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */

        if (lpes1 == 0) {

            new_msr |= (target_ulong)MSR_HVB;

        }

        goto store_next;

    case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */

        srr0 = SPR_HSRR0;

        srr1 = SPR_HSRR1;

        new_msr |= (target_ulong)MSR_HVB;

        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);

        goto store_next;

    case POWERPC_EXCP_TRACE:     /* Trace exception                          */

        if (lpes1 == 0) {

            new_msr |= (target_ulong)MSR_HVB;

        }

        goto store_next;

    case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */

        srr0 = SPR_HSRR0;

        srr1 = SPR_HSRR1;

        new_msr |= (target_ulong)MSR_HVB;

        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);

        goto store_next;

    case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */

        srr0 = SPR_HSRR0;

        srr1 = SPR_HSRR1;

        new_msr |= (target_ulong)MSR_HVB;

        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);

        goto store_next;

    case POWERPC_EXCP_HDSEG:     /* Hypervisor data segment exception        */

        srr0 = SPR_HSRR0;

        srr1 = SPR_HSRR1;

        new_msr |= (target_ulong)MSR_HVB;

        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);

        goto store_next;

    case POWERPC_EXCP_HISEG:     /* Hypervisor instruction segment exception */

        srr0 = SPR_HSRR0;

        srr1 = SPR_HSRR1;

        new_msr |= (target_ulong)MSR_HVB;

        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);

        goto store_next;

    case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */

        if (lpes1 == 0) {

            new_msr |= (target_ulong)MSR_HVB;

        }

        goto store_current;

    case POWERPC_EXCP_VSXU:       /* VSX unavailable exception               */

        if (lpes1 == 0) {

            new_msr |= (target_ulong)MSR_HVB;

        }

        goto store_current;

    case POWERPC_EXCP_FU:         /* Facility unavailable exception          */

        if (lpes1 == 0) {

            new_msr |= (target_ulong)MSR_HVB;

        }

        goto store_current;

    case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */

        LOG_EXCP("PIT exception\n");

        goto store_next;

    case POWERPC_EXCP_IO:        /* IO error exception                       */

        /* XXX: TODO */

        cpu_abort(cs, "601 IO error exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_RUNM:      /* Run mode exception                       */

        /* XXX: TODO */

        cpu_abort(cs, "601 run mode exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_EMUL:      /* Emulation trap exception                 */

        /* XXX: TODO */

        cpu_abort(cs, "602 emulation trap exception "

                  "is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */

        if (lpes1 == 0) { /* XXX: check this */

            new_msr |= (target_ulong)MSR_HVB;

        }

        switch (excp_model) {

        case POWERPC_EXCP_602:

        case POWERPC_EXCP_603:

        case POWERPC_EXCP_603E:

        case POWERPC_EXCP_G2:

            goto tlb_miss_tgpr;

        case POWERPC_EXCP_7x5:

            goto tlb_miss;

        case POWERPC_EXCP_74xx:

            goto tlb_miss_74xx;

        default:

            cpu_abort(cs, "Invalid instruction TLB miss exception\n");

            break;

        }

        break;

    case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */

        if (lpes1 == 0) { /* XXX: check this */

            new_msr |= (target_ulong)MSR_HVB;

        }

        switch (excp_model) {

        case POWERPC_EXCP_602:

        case POWERPC_EXCP_603:

        case POWERPC_EXCP_603E:

        case POWERPC_EXCP_G2:

            goto tlb_miss_tgpr;

        case POWERPC_EXCP_7x5:

            goto tlb_miss;

        case POWERPC_EXCP_74xx:

            goto tlb_miss_74xx;

        default:

            cpu_abort(cs, "Invalid data load TLB miss exception\n");

            break;

        }

        break;

    case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */

        if (lpes1 == 0) { /* XXX: check this */

            new_msr |= (target_ulong)MSR_HVB;

        }

        switch (excp_model) {

        case POWERPC_EXCP_602:

        case POWERPC_EXCP_603:

        case POWERPC_EXCP_603E:

        case POWERPC_EXCP_G2:

        tlb_miss_tgpr:

            /* Swap temporary saved registers with GPRs */

            if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {

                new_msr |= (target_ulong)1 << MSR_TGPR;

                hreg_swap_gpr_tgpr(env);

            }

            goto tlb_miss;

        case POWERPC_EXCP_7x5:

        tlb_miss:

#if defined(DEBUG_SOFTWARE_TLB)

            if (qemu_log_enabled()) {

                const char *es;

                target_ulong *miss, *cmp;

                int en;

                if (excp == POWERPC_EXCP_IFTLB) {

                    es = "I";

                    en = 'I';

                    miss = &env->spr[SPR_IMISS];

                    cmp = &env->spr[SPR_ICMP];

                } else {

                    if (excp == POWERPC_EXCP_DLTLB) {

                        es = "DL";

                    } else {

                        es = "DS";

                    }

                    en = 'D';

                    miss = &env->spr[SPR_DMISS];

                    cmp = &env->spr[SPR_DCMP];

                }

                qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "

                         TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "

                         TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,

                         env->spr[SPR_HASH1], env->spr[SPR_HASH2],

                         env->error_code);

            }

#endif

            msr |= env->crf[0] << 28;

            msr |= env->error_code; /* key, D/I, S/L bits */

            /* Set way using a LRU mechanism */

            msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;

            break;

        case POWERPC_EXCP_74xx:

        tlb_miss_74xx:

#if defined(DEBUG_SOFTWARE_TLB)

            if (qemu_log_enabled()) {

                const char *es;

                target_ulong *miss, *cmp;

                int en;

                if (excp == POWERPC_EXCP_IFTLB) {

                    es = "I";

                    en = 'I';

                    miss = &env->spr[SPR_TLBMISS];

                    cmp = &env->spr[SPR_PTEHI];

                } else {

                    if (excp == POWERPC_EXCP_DLTLB) {

                        es = "DL";

                    } else {

                        es = "DS";

                    }

                    en = 'D';

                    miss = &env->spr[SPR_TLBMISS];

                    cmp = &env->spr[SPR_PTEHI];

                }

                qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "

                         TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,

                         env->error_code);

            }

#endif

            msr |= env->error_code; /* key bit */

            break;

        default:

            cpu_abort(cs, "Invalid data store TLB miss exception\n");

            break;

        }

        goto store_next;

    case POWERPC_EXCP_FPA:       /* Floating-point assist exception          */

        /* XXX: TODO */

        cpu_abort(cs, "Floating point assist exception "

                  "is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_DABR:      /* Data address breakpoint                  */

        /* XXX: TODO */

        cpu_abort(cs, "DABR exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */

        /* XXX: TODO */

        cpu_abort(cs, "IABR exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_SMI:       /* System management interrupt              */

        /* XXX: TODO */

        cpu_abort(cs, "SMI exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */

        /* XXX: TODO */

        cpu_abort(cs, "Thermal management exception "

                  "is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */

        if (lpes1 == 0) {

            new_msr |= (target_ulong)MSR_HVB;

        }

        /* XXX: TODO */

        cpu_abort(cs,

                  "Performance counter exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */

        /* XXX: TODO */

        cpu_abort(cs, "VPU assist exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_SOFTP:     /* Soft patch exception                     */

        /* XXX: TODO */

        cpu_abort(cs,

                  "970 soft-patch exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */

        /* XXX: TODO */

        cpu_abort(cs,

                  "970 maintenance exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_MEXTBR:    /* Maskable external breakpoint             */

        /* XXX: TODO */

        cpu_abort(cs, "Maskable external exception "

                  "is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_NMEXTBR:   /* Non maskable external breakpoint         */

        /* XXX: TODO */

        cpu_abort(cs, "Non maskable external exception "

                  "is not implemented yet !\n");

        goto store_next;

    default:

    excp_invalid:

        cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);

        break;

    store_current:

        /* save current instruction location */

        env->spr[srr0] = env->nip - 4;

        break;

    store_next:

        /* save next instruction location */

        env->spr[srr0] = env->nip;

        break;

    }

    /* Save MSR */

    env->spr[srr1] = msr;

    /* If any alternate SRR register are defined, duplicate saved values */

    if (asrr0 != -1) {

        env->spr[asrr0] = env->spr[srr0];

    }

    if (asrr1 != -1) {

        env->spr[asrr1] = env->spr[srr1];

    }

    if (env->spr[SPR_LPCR] & LPCR_AIL) {

        new_msr |= (1 << MSR_IR) | (1 << MSR_DR);

    }

#ifdef TARGET_PPC64

    if (excp_model == POWERPC_EXCP_POWER7 ||

        excp_model == POWERPC_EXCP_POWER8) {

        if (env->spr[SPR_LPCR] & LPCR_ILE) {

            new_msr |= (target_ulong)1 << MSR_LE;

        }

    } else if (msr_ile) {

        new_msr |= (target_ulong)1 << MSR_LE;

    }

#else

    if (msr_ile) {

        new_msr |= (target_ulong)1 << MSR_LE;

    }

#endif

    /* Jump to handler */

    vector = env->excp_vectors[excp];

    if (vector == (target_ulong)-1ULL) {

        cpu_abort(cs, "Raised an exception without defined vector %d\n",

                  excp);

    }

    vector |= env->excp_prefix;

    /* AIL only works if there is no HV transition and we are running with

     * translations enabled

     */

    if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1)) {

        ail = 0;

    }

    /* Handle AIL */

    if (ail) {

        new_msr |= (1 << MSR_IR) | (1 << MSR_DR);

        switch(ail) {

        case AIL_0001_8000:

            vector |= 0x18000;

            break;

        case AIL_C000_0000_0000_4000:

            vector |= 0xc000000000004000ull;

            break;

        default:

            cpu_abort(cs, "Invalid AIL combination %d\n", ail);

            break;

        }

    }

#if defined(TARGET_PPC64)

    if (excp_model == POWERPC_EXCP_BOOKE) {

        if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {

            /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */

            new_msr |= (target_ulong)1 << MSR_CM;

        } else {

            vector = (uint32_t)vector;

        }

    } else {

        if (!msr_isf && !(env->mmu_model & POWERPC_MMU_64)) {

            vector = (uint32_t)vector;

        } else {

            new_msr |= (target_ulong)1 << MSR_SF;

        }

    }

#endif

    /* We don't use hreg_store_msr here as already have treated

     * any special case that could occur. Just store MSR and update hflags

     *

     * Note: We *MUST* not use hreg_store_msr() as-is anyway because it

     * will prevent setting of the HV bit which some exceptions might need

     * to do.

     */

    env->msr = new_msr & env->msr_mask;

    hreg_compute_hflags(env);

    env->nip = vector;

    /* Reset exception state */

    cs->exception_index = POWERPC_EXCP_NONE;

    env->error_code = 0;

    /* Any interrupt is context synchronizing, check if TCG TLB

     * needs a delayed flush on ppc64

     */

    check_tlb_flush(env);

}


static int v9fs_xattr_write(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,

                            uint64_t off, uint32_t count,

                            struct iovec *sg, int cnt)

{

    int i, to_copy;

    ssize_t err = 0;

    int write_count;

    int64_t xattr_len;

    size_t offset = 7;

    xattr_len = fidp->fs.xattr.len;

    write_count = xattr_len - off;

    if (write_count > count) {

        write_count = count;

    } else if (write_count < 0) {

        /*

         * write beyond XATTR value len specified in

         * xattrcreate

         */

        err = -ENOSPC;

        goto out;

    }

    err = pdu_marshal(pdu, offset, "d", write_count);

    if (err < 0) {

        return err;

    }

    err += offset;

    fidp->fs.xattr.copied_len += write_count;

    /*

     * Now copy the content from sg list

     */

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

        if (write_count > sg[i].iov_len) {

            to_copy = sg[i].iov_len;

        } else {

            to_copy = write_count;

        }

        memcpy((char *)fidp->fs.xattr.value + off, sg[i].iov_base, to_copy);

        /* updating vs->off since we are not using below */

        off += to_copy;

        write_count -= to_copy;

    }

out:

    return err;

}


static void test_retry_flush(const char *machine)

{

    QPCIDevice *dev;

    void *bmdma_base, *ide_base;

    uint8_t data;

    const char *s;

    prepare_blkdebug_script(debug_path, "flush_to_disk");

    ide_test_start(

        "-vnc none "

        "-drive file=blkdebug:%s:%s,if=ide,cache=writeback,format=raw,"

        "rerror=stop,werror=stop",

        debug_path, tmp_path);

    dev = get_pci_device(&bmdma_base, &ide_base);

    qtest_irq_intercept_in(global_qtest, "ioapic");

    /* Dirty media so that CMD_FLUSH_CACHE will actually go to disk */

    make_dirty(0);

    /* FLUSH CACHE command on device 0*/

    qpci_io_writeb(dev, ide_base + reg_device, 0);

    qpci_io_writeb(dev, ide_base + reg_command, CMD_FLUSH_CACHE);

    /* Check status while request is in flight*/

    data = qpci_io_readb(dev, ide_base + reg_status);

    assert_bit_set(data, BSY | DRDY);

    assert_bit_clear(data, DF | ERR | DRQ);

    qmp_eventwait("STOP");

    /* Complete the command */

    s = "{'execute':'cont' }";

    qmp_discard_response(s);

    /* Check registers */

    data = qpci_io_readb(dev, ide_base + reg_device);

    g_assert_cmpint(data & DEV, ==, 0);

    do {

        data = qpci_io_readb(dev, ide_base + reg_status);

    } while (data & BSY);

    assert_bit_set(data, DRDY);

    assert_bit_clear(data, BSY | DF | ERR | DRQ);

    ide_test_quit();

}


static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size)

{

    GetBitContext gb;

    HuffContext h[4];

    VLC vlc[4];

    int16_t *samples = data;

    int val;

    int i, res;

    int unp_size;

    int bits, stereo;

    int pred[2] = {0, 0};

    unp_size = AV_RL32(buf);

    init_get_bits(&gb, buf + 4, (buf_size - 4) * 8);

    if(!get_bits1(&gb)){

        av_log(avctx, AV_LOG_INFO, "Sound: no data\n");

        *data_size = 0;

        return 1;

    }

    stereo = get_bits1(&gb);

    bits = get_bits1(&gb);

    if ((unp_size << !bits) > *data_size) {

        av_log(avctx, AV_LOG_ERROR, "Frame is too large to fit in buffer\n");

        return -1;

    }

    memset(vlc, 0, sizeof(VLC) * 4);

    memset(h, 0, sizeof(HuffContext) * 4);

    // Initialize

    for(i = 0; i < (1 << (bits + stereo)); i++) {

        h[i].length = 256;

        h[i].maxlength = 0;

        h[i].current = 0;

        h[i].bits = av_mallocz(256 * 4);

        h[i].lengths = av_mallocz(256 * sizeof(int));

        h[i].values = av_mallocz(256 * sizeof(int));

        skip_bits1(&gb);

        smacker_decode_tree(&gb, &h[i], 0, 0);

        skip_bits1(&gb);

        if(h[i].current > 1) {

            res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length,

                    h[i].lengths, sizeof(int), sizeof(int),

                    h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE);

            if(res < 0) {

                av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n");

                return -1;

            }

        }

    }

    if(bits) { //decode 16-bit data

        for(i = stereo; i >= 0; i--)

            pred[i] = bswap_16(get_bits(&gb, 16));

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

            *samples++ = pred[i];

        for(i = 0; i < unp_size / 2; i++) {

            if(i & stereo) {

                if(vlc[2].table)

                    res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3);

                else

                    res = 0;

                val  = h[2].values[res];

                if(vlc[3].table)

                    res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3);

                else

                    res = 0;

                val |= h[3].values[res] << 8;

                pred[1] += (int16_t)val;

                *samples++ = pred[1];

            } else {

                if(vlc[0].table)

                    res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3);

                else

                    res = 0;

                val  = h[0].values[res];

                if(vlc[1].table)

                    res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3);

                else

                    res = 0;

                val |= h[1].values[res] << 8;

                pred[0] += val;

                *samples++ = pred[0];

            }

        }

    } else { //8-bit data

        for(i = stereo; i >= 0; i--)

            pred[i] = get_bits(&gb, 8);

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

            *samples++ = (pred[i] - 0x80) << 8;

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

            if(i & stereo){

                if(vlc[1].table)

                    res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3);

                else

                    res = 0;

                pred[1] += (int8_t)h[1].values[res];

                *samples++ = (pred[1] - 0x80) << 8;

            } else {

                if(vlc[0].table)

                    res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3);

                else

                    res = 0;

                pred[0] += (int8_t)h[0].values[res];

                *samples++ = (pred[0] - 0x80) << 8;

            }

        }

        unp_size *= 2;

    }

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

        if(vlc[i].table)

            free_vlc(&vlc[i]);

        if(h[i].bits)

            av_free(h[i].bits);

        if(h[i].lengths)

            av_free(h[i].lengths);

        if(h[i].values)

            av_free(h[i].values);

    }

    *data_size = unp_size;

    return buf_size;

}


void do_brinc (void)

{

    uint32_t a, b, d, mask;

    mask = (uint32_t)(-1UL) >> MASKBITS;

    b = T1_64 & mask;

    a = T0_64 & mask;

    d = word_reverse(1 + word_reverse(a | ~mask));

    T0_64 = (T0_64 & ~mask) | (d & mask);

}


static void check_suspend_mode(GuestSuspendMode mode, Error **errp)

{

    SYSTEM_POWER_CAPABILITIES sys_pwr_caps;

    Error *local_err = NULL;

    if (error_is_set(errp)) {

        return;

    }

    ZeroMemory(&sys_pwr_caps, sizeof(sys_pwr_caps));

    if (!GetPwrCapabilities(&sys_pwr_caps)) {

        error_set(&local_err, QERR_QGA_COMMAND_FAILED,

                  "failed to determine guest suspend capabilities");

        goto out;

    }

    switch (mode) {

    case GUEST_SUSPEND_MODE_DISK:

        if (!sys_pwr_caps.SystemS4) {

            error_set(&local_err, QERR_QGA_COMMAND_FAILED,

                      "suspend-to-disk not supported by OS");

        }

        break;

    case GUEST_SUSPEND_MODE_RAM:

        if (!sys_pwr_caps.SystemS3) {

            error_set(&local_err, QERR_QGA_COMMAND_FAILED,

                      "suspend-to-ram not supported by OS");

        }

        break;

    default:

        error_set(&local_err, QERR_INVALID_PARAMETER_VALUE, "mode",

                  "GuestSuspendMode");

    }

out:

    if (local_err) {

        error_propagate(errp, local_err);

    }

}


static gint range_compare(gconstpointer a, gconstpointer b)

{

    Range *ra = (Range *)a, *rb = (Range *)b;

    if (ra->begin == rb->begin && ra->end == rb->end) {

        return 0;

    } else if (range_get_last(ra->begin, ra->end) <

               range_get_last(rb->begin, rb->end)) {

        return -1;

    } else {

        return 1;

    }

}


static void report_unsupported_feature(BlockDriverState *bs,

    Error **errp, Qcow2Feature *table, uint64_t mask)

{

    while (table && table->name[0] != '\0') {

        if (table->type == QCOW2_FEAT_TYPE_INCOMPATIBLE) {

            if (mask & (1 << table->bit)) {

                report_unsupported(bs, errp, "%.46s", table->name);

                mask &= ~(1 << table->bit);

            }

        }

        table++;

    }

    if (mask) {

        report_unsupported(bs, errp, "Unknown incompatible feature: %" PRIx64,

                           mask);

    }

}


void qemu_ram_free(ram_addr_t addr)

{

    RAMBlock *block;

    QLIST_FOREACH(block, &ram_list.blocks, next) {

        if (addr == block->offset) {

            QLIST_REMOVE(block, next);

            if (block->flags & RAM_PREALLOC_MASK) {

                ;

            } else if (mem_path) {

#if defined (__linux__) && !defined(TARGET_S390X)

                if (block->fd) {

                    munmap(block->host, block->length);

                    close(block->fd);

                } else {

                    qemu_vfree(block->host);

                }

#endif

            } else {

#if defined(TARGET_S390X) && defined(CONFIG_KVM)

                munmap(block->host, block->length);

                qemu_vfree(block->host);

#endif

            }

            qemu_free(block);

            return;

        }

    }

}


static int rocker_msix_init(Rocker *r)

{

    PCIDevice *dev = PCI_DEVICE(r);

    int err;

    err = msix_init(dev, ROCKER_MSIX_VEC_COUNT(r->fp_ports),

                    &r->msix_bar,

                    ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_TABLE_OFFSET,

                    &r->msix_bar,

                    ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_PBA_OFFSET,

                    0);

    if (err) {

        return err;

    }

    err = rocker_msix_vectors_use(r, ROCKER_MSIX_VEC_COUNT(r->fp_ports));

    if (err) {

        goto err_msix_vectors_use;

    }

    return 0;

err_msix_vectors_use:

    msix_uninit(dev, &r->msix_bar, &r->msix_bar);

    return err;

}


static void avc_wgt_4width_msa(uint8_t *data,

                               int32_t stride,

                               int32_t height,

                               int32_t log2_denom,

                               int32_t src_weight,

                               int32_t offset_in)

{

    if (2 == height) {

        avc_wgt_4x2_msa(data, stride, log2_denom, src_weight, offset_in);

    } else {

        avc_wgt_4x4multiple_msa(data, stride, height, log2_denom,

                                src_weight, offset_in);

    }

}


static void do_apply_filter(APEContext *ctx, int version, APEFilter *f,

                            int32_t *data, int count, int order, int fracbits)

{

    int res;

    int absres;

    while (count--) {

        /* round fixedpoint scalar product */

        res = ctx->adsp.scalarproduct_and_madd_int16(f->coeffs,

                                                     f->delay - order,

                                                     f->adaptcoeffs - order,

                                                     order, APESIGN(*data));

        res = (res + (1 << (fracbits - 1))) >> fracbits;

        res += *data;

        *data++ = res;

        /* Update the output history */

        *f->delay++ = av_clip_int16(res);

        if (version < 3980) {

            /* Version ??? to < 3.98 files (untested) */

            f->adaptcoeffs[0]  = (res == 0) ? 0 : ((res >> 28) & 8) - 4;

            f->adaptcoeffs[-4] >>= 1;

            f->adaptcoeffs[-8] >>= 1;

        } else {

            /* Version 3.98 and later files */

            /* Update the adaption coefficients */

            absres = FFABS(res);

            if (absres)

                *f->adaptcoeffs = ((res & (-1<<31)) ^ (-1<<30)) >>

                                  (25 + (absres <= f->avg*3) + (absres <= f->avg*4/3));

            else

                *f->adaptcoeffs = 0;

            f->avg += (absres - f->avg) / 16;

            f->adaptcoeffs[-1] >>= 1;

            f->adaptcoeffs[-2] >>= 1;

            f->adaptcoeffs[-8] >>= 1;

        }

        f->adaptcoeffs++;

        /* Have we filled the history buffer? */

        if (f->delay == f->historybuffer + HISTORY_SIZE + (order * 2)) {

            memmove(f->historybuffer, f->delay - (order * 2),

                    (order * 2) * sizeof(*f->historybuffer));

            f->delay = f->historybuffer + order * 2;

            f->adaptcoeffs = f->historybuffer + order;

        }

    }

}


static int ffm2_read_header(AVFormatContext *s)

{

    FFMContext *ffm = s->priv_data;

    AVStream *st;

    AVIOContext *pb = s->pb;

    AVCodecContext *codec;

    const AVCodecDescriptor *codec_desc;

    int ret, i;

    int f_main = 0, f_cprv = -1, f_stvi = -1, f_stau = -1;

    AVCodec *enc;

    char *buffer;

    ffm->packet_size = avio_rb32(pb);

    if (ffm->packet_size != FFM_PACKET_SIZE) {

        av_log(s, AV_LOG_ERROR, "Invalid packet size %d, expected size was %d\n",

               ffm->packet_size, FFM_PACKET_SIZE);

        ret = AVERROR_INVALIDDATA;

    ffm->write_index = avio_rb64(pb);

    /* get also filesize */

    if (pb->seekable) {

        ffm->file_size = avio_size(pb);

        if (ffm->write_index && 0)

            adjust_write_index(s);

    } else {

        ffm->file_size = (UINT64_C(1) << 63) - 1;

    while(!avio_feof(pb)) {

        unsigned id = avio_rb32(pb);

        unsigned size = avio_rb32(pb);

        int64_t next = avio_tell(pb) + size;

        char rc_eq_buf[128];

        if(!id)

            break;

        switch(id) {

        case MKBETAG('M', 'A', 'I', 'N'):

            if (f_main++) {

                ret = AVERROR(EINVAL);

            avio_rb32(pb); /* nb_streams */

            avio_rb32(pb); /* total bitrate */

            break;

        case MKBETAG('C', 'O', 'M', 'M'):

            f_cprv = f_stvi = f_stau = 0;

            st = avformat_new_stream(s, NULL);

            if (!st) {

                ret = AVERROR(ENOMEM);

            avpriv_set_pts_info(st, 64, 1, 1000000);

            codec = st->codec;

            /* generic info */

            codec->codec_id = avio_rb32(pb);

            codec_desc = avcodec_descriptor_get(codec->codec_id);

            if (!codec_desc) {

                av_log(s, AV_LOG_ERROR, "Invalid codec id: %d\n", codec->codec_id);

                codec->codec_id = AV_CODEC_ID_NONE;

            codec->codec_type = avio_r8(pb);

            if (codec->codec_type != codec_desc->type) {

                av_log(s, AV_LOG_ERROR, "Codec type mismatch: expected %d, found %d\n",

                       codec_desc->type, codec->codec_type);

                codec->codec_id = AV_CODEC_ID_NONE;

                codec->codec_type = AVMEDIA_TYPE_UNKNOWN;

            codec->bit_rate = avio_rb32(pb);

            codec->flags = avio_rb32(pb);

            codec->flags2 = avio_rb32(pb);

            codec->debug = avio_rb32(pb);

            if (codec->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {

                int size = avio_rb32(pb);

                codec->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);

                if (!codec->extradata)

                    return AVERROR(ENOMEM);

                codec->extradata_size = size;

                avio_read(pb, codec->extradata, size);

            break;

        case MKBETAG('S', 'T', 'V', 'I'):

            if (f_stvi++) {

                ret = AVERROR(EINVAL);

            codec->time_base.num = avio_rb32(pb);

            codec->time_base.den = avio_rb32(pb);

            if (codec->time_base.num <= 0 || codec->time_base.den <= 0) {

                av_log(s, AV_LOG_ERROR, "Invalid time base %d/%d\n",

                       codec->time_base.num, codec->time_base.den);

                ret = AVERROR_INVALIDDATA;

            codec->width = avio_rb16(pb);

            codec->height = avio_rb16(pb);

            codec->gop_size = avio_rb16(pb);

            codec->pix_fmt = avio_rb32(pb);

            codec->qmin = avio_r8(pb);

            codec->qmax = avio_r8(pb);

            codec->max_qdiff = avio_r8(pb);

            codec->qcompress = avio_rb16(pb) / 10000.0;

            codec->qblur = avio_rb16(pb) / 10000.0;

            codec->bit_rate_tolerance = avio_rb32(pb);

            avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf));

            codec->rc_eq = av_strdup(rc_eq_buf);

            codec->rc_max_rate = avio_rb32(pb);

            codec->rc_min_rate = avio_rb32(pb);

            codec->rc_buffer_size = avio_rb32(pb);

            codec->i_quant_factor = av_int2double(avio_rb64(pb));

            codec->b_quant_factor = av_int2double(avio_rb64(pb));

            codec->i_quant_offset = av_int2double(avio_rb64(pb));

            codec->b_quant_offset = av_int2double(avio_rb64(pb));

            codec->dct_algo = avio_rb32(pb);

            codec->strict_std_compliance = avio_rb32(pb);

            codec->max_b_frames = avio_rb32(pb);

            codec->mpeg_quant = avio_rb32(pb);

            codec->intra_dc_precision = avio_rb32(pb);

            codec->me_method = avio_rb32(pb);

            codec->mb_decision = avio_rb32(pb);

            codec->nsse_weight = avio_rb32(pb);

            codec->frame_skip_cmp = avio_rb32(pb);

            codec->rc_buffer_aggressivity = av_int2double(avio_rb64(pb));

            codec->codec_tag = avio_rb32(pb);

            codec->thread_count = avio_r8(pb);

            codec->coder_type = avio_rb32(pb);

            codec->me_cmp = avio_rb32(pb);

            codec->me_subpel_quality = avio_rb32(pb);

            codec->me_range = avio_rb32(pb);

            codec->keyint_min = avio_rb32(pb);

            codec->scenechange_threshold = avio_rb32(pb);

            codec->b_frame_strategy = avio_rb32(pb);

            codec->qcompress = av_int2double(avio_rb64(pb));

            codec->qblur = av_int2double(avio_rb64(pb));

            codec->max_qdiff = avio_rb32(pb);

            codec->refs = avio_rb32(pb);

            break;

        case MKBETAG('S', 'T', 'A', 'U'):

            if (f_stau++) {

                ret = AVERROR(EINVAL);

            codec->sample_rate = avio_rb32(pb);

            codec->channels = avio_rl16(pb);

            codec->frame_size = avio_rl16(pb);

            break;

        case MKBETAG('C', 'P', 'R', 'V'):

            if (f_cprv++) {

                ret = AVERROR(EINVAL);

            enc = avcodec_find_encoder(codec->codec_id);

            if (enc && enc->priv_data_size && enc->priv_class) {

                buffer = av_malloc(size + 1);

                if (!buffer) {

                    ret = AVERROR(ENOMEM);

                avio_get_str(pb, size, buffer, size + 1);

                if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0)

            break;

        case MKBETAG('S', '2', 'V', 'I'):

            if (f_stvi++ || !size) {

                ret = AVERROR(EINVAL);

            buffer = av_malloc(size);

            if (!buffer) {

                ret = AVERROR(ENOMEM);

            avio_get_str(pb, INT_MAX, buffer, size);

            av_set_options_string(codec, buffer, "=", ",");

            if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0)

            break;

        case MKBETAG('S', '2', 'A', 'U'):

            if (f_stau++ || !size) {

                ret = AVERROR(EINVAL);

            buffer = av_malloc(size);

            if (!buffer) {

                ret = AVERROR(ENOMEM);

            avio_get_str(pb, INT_MAX, buffer, size);

            av_set_options_string(codec, buffer, "=", ",");

            if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0)

            break;

        avio_seek(pb, next, SEEK_SET);

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

        avcodec_parameters_from_context(s->streams[i]->codecpar, s->streams[i]->codec);

    /* get until end of block reached */

    while ((avio_tell(pb) % ffm->packet_size) != 0 && !pb->eof_reached)

        avio_r8(pb);

    /* init packet demux */

    ffm->packet_ptr = ffm->packet;

    ffm->packet_end = ffm->packet;

    ffm->frame_offset = 0;

    ffm->dts = 0;

    ffm->read_state = READ_HEADER;

    ffm->first_packet = 1;

    return 0;

 fail:

    ffm_close(s);

    return ret;


static int h263p_decode_umotion(MpegEncContext * s, int pred)

{

   int code = 0, sign;

   if (get_bits1(&s->gb)) /* Motion difference = 0 */

      return pred;

   code = 2 + get_bits1(&s->gb);

   while (get_bits1(&s->gb))

   {

      code <<= 1;

      code += get_bits1(&s->gb);

      if (code >= 32768) {

          avpriv_request_sample(s->avctx, "Huge DMV");

          return AVERROR_INVALIDDATA;

      }

   }

   sign = code & 1;

   code >>= 1;

   code = (sign) ? (pred - code) : (pred + code);

   ff_tlog(s->avctx,"H.263+ UMV Motion = %d\n", code);

   return code;

}


static void stream_pause(VideoState *is)

{

    is->paused = !is->paused;

    if (!is->paused) {

        if(is->read_pause_return != AVERROR(ENOSYS)){

            is->video_current_pts = get_video_clock(is);

        }

        is->frame_timer += (av_gettime() - is->video_current_pts_time) / 1000000.0;

        is->video_current_pts_time= av_gettime();

    }

}


static void gen_tlbia(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

    gen_helper_tlbia(cpu_env);

#endif

}


int ff_MPV_encode_picture(AVCodecContext *avctx, AVPacket *pkt,

                          const AVFrame *pic_arg, int *got_packet)

{

    MpegEncContext *s = avctx->priv_data;

    int i, stuffing_count, ret;

    int context_count = s->slice_context_count;

    s->picture_in_gop_number++;

    if (load_input_picture(s, pic_arg) < 0)

        return -1;

    if (select_input_picture(s) < 0) {

        return -1;

    }

    /* output? */

    if (s->new_picture.f.data[0]) {

        if (!pkt->data &&

            (ret = ff_alloc_packet(pkt, s->mb_width*s->mb_height*MAX_MB_BYTES)) < 0)

            return ret;

        if (s->mb_info) {

            s->mb_info_ptr = av_packet_new_side_data(pkt,

                                 AV_PKT_DATA_H263_MB_INFO,

                                 s->mb_width*s->mb_height*12);

            s->prev_mb_info = s->last_mb_info = s->mb_info_size = 0;

        }

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

            int start_y = s->thread_context[i]->start_mb_y;

            int   end_y = s->thread_context[i]->  end_mb_y;

            int h       = s->mb_height;

            uint8_t *start = pkt->data + (size_t)(((int64_t) pkt->size) * start_y / h);

            uint8_t *end   = pkt->data + (size_t)(((int64_t) pkt->size) *   end_y / h);

            init_put_bits(&s->thread_context[i]->pb, start, end - start);

        }

        s->pict_type = s->new_picture.f.pict_type;

        //emms_c();

        //printf("qs:%f %f %d\n", s->new_picture.quality,

        //       s->current_picture.quality, s->qscale);

        ff_MPV_frame_start(s, avctx);

vbv_retry:

        if (encode_picture(s, s->picture_number) < 0)

            return -1;

        avctx->header_bits = s->header_bits;

        avctx->mv_bits     = s->mv_bits;

        avctx->misc_bits   = s->misc_bits;

        avctx->i_tex_bits  = s->i_tex_bits;

        avctx->p_tex_bits  = s->p_tex_bits;

        avctx->i_count     = s->i_count;

        // FIXME f/b_count in avctx

        avctx->p_count     = s->mb_num - s->i_count - s->skip_count;

        avctx->skip_count  = s->skip_count;

        ff_MPV_frame_end(s);

        if (CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG)

            ff_mjpeg_encode_picture_trailer(s);

        if (avctx->rc_buffer_size) {

            RateControlContext *rcc = &s->rc_context;

            int max_size = rcc->buffer_index * avctx->rc_max_available_vbv_use;

            if (put_bits_count(&s->pb) > max_size &&

                s->lambda < s->avctx->lmax) {

                s->next_lambda = FFMAX(s->lambda + 1, s->lambda *

                                       (s->qscale + 1) / s->qscale);

                if (s->adaptive_quant) {

                    int i;

                    for (i = 0; i < s->mb_height * s->mb_stride; i++)

                        s->lambda_table[i] =

                            FFMAX(s->lambda_table[i] + 1,

                                  s->lambda_table[i] * (s->qscale + 1) /

                                  s->qscale);

                }

                s->mb_skipped = 0;        // done in MPV_frame_start()

                // done in encode_picture() so we must undo it

                if (s->pict_type == AV_PICTURE_TYPE_P) {

                    if (s->flipflop_rounding          ||

                        s->codec_id == AV_CODEC_ID_H263P ||

                        s->codec_id == AV_CODEC_ID_MPEG4)

                        s->no_rounding ^= 1;

                }

                if (s->pict_type != AV_PICTURE_TYPE_B) {

                    s->time_base       = s->last_time_base;

                    s->last_non_b_time = s->time - s->pp_time;

                }

                //av_log(NULL, AV_LOG_ERROR, "R:%d ", s->next_lambda);

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

                    PutBitContext *pb = &s->thread_context[i]->pb;

                    init_put_bits(pb, pb->buf, pb->buf_end - pb->buf);

                }

                goto vbv_retry;

            }

            assert(s->avctx->rc_max_rate);

        }

        if (s->flags & CODEC_FLAG_PASS1)

            ff_write_pass1_stats(s);

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

            s->current_picture_ptr->f.error[i] = s->current_picture.f.error[i];

            avctx->error[i] += s->current_picture_ptr->f.error[i];

        }

        if (s->flags & CODEC_FLAG_PASS1)

            assert(avctx->header_bits + avctx->mv_bits + avctx->misc_bits +

                   avctx->i_tex_bits + avctx->p_tex_bits ==

                       put_bits_count(&s->pb));

        flush_put_bits(&s->pb);

        s->frame_bits  = put_bits_count(&s->pb);

        stuffing_count = ff_vbv_update(s, s->frame_bits);

        if (stuffing_count) {

            if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) <

                    stuffing_count + 50) {

                av_log(s->avctx, AV_LOG_ERROR, "stuffing too large\n");

                return -1;

            }

            switch (s->codec_id) {

            case AV_CODEC_ID_MPEG1VIDEO:

            case AV_CODEC_ID_MPEG2VIDEO:

                while (stuffing_count--) {

                    put_bits(&s->pb, 8, 0);

                }

            break;

            case AV_CODEC_ID_MPEG4:

                put_bits(&s->pb, 16, 0);

                put_bits(&s->pb, 16, 0x1C3);

                stuffing_count -= 4;

                while (stuffing_count--) {

                    put_bits(&s->pb, 8, 0xFF);

                }

            break;

            default:

                av_log(s->avctx, AV_LOG_ERROR, "vbv buffer overflow\n");

            }

            flush_put_bits(&s->pb);

            s->frame_bits  = put_bits_count(&s->pb);

        }

        /* update mpeg1/2 vbv_delay for CBR */

        if (s->avctx->rc_max_rate                          &&

            s->avctx->rc_min_rate == s->avctx->rc_max_rate &&

            s->out_format == FMT_MPEG1                     &&

            90000LL * (avctx->rc_buffer_size - 1) <=

                s->avctx->rc_max_rate * 0xFFFFLL) {

            int vbv_delay, min_delay;

            double inbits  = s->avctx->rc_max_rate *

                             av_q2d(s->avctx->time_base);

            int    minbits = s->frame_bits - 8 *

                             (s->vbv_delay_ptr - s->pb.buf - 1);

            double bits    = s->rc_context.buffer_index + minbits - inbits;

            if (bits < 0)

                av_log(s->avctx, AV_LOG_ERROR,

                       "Internal error, negative bits\n");

            assert(s->repeat_first_field == 0);

            vbv_delay = bits * 90000 / s->avctx->rc_max_rate;

            min_delay = (minbits * 90000LL + s->avctx->rc_max_rate - 1) /

                        s->avctx->rc_max_rate;

            vbv_delay = FFMAX(vbv_delay, min_delay);

            assert(vbv_delay < 0xFFFF);

            s->vbv_delay_ptr[0] &= 0xF8;

            s->vbv_delay_ptr[0] |= vbv_delay >> 13;

            s->vbv_delay_ptr[1]  = vbv_delay >> 5;

            s->vbv_delay_ptr[2] &= 0x07;

            s->vbv_delay_ptr[2] |= vbv_delay << 3;

            avctx->vbv_delay     = vbv_delay * 300;

        }

        s->total_bits     += s->frame_bits;

        avctx->frame_bits  = s->frame_bits;

        pkt->pts = s->current_picture.f.pts;

        if (!s->low_delay) {

            if (!s->current_picture.f.coded_picture_number)

                pkt->dts = pkt->pts - s->dts_delta;

            else

                pkt->dts = s->reordered_pts;

            s->reordered_pts = s->input_picture[0]->f.pts;

        } else

            pkt->dts = pkt->pts;

        if (s->current_picture.f.key_frame)

            pkt->flags |= AV_PKT_FLAG_KEY;

        if (s->mb_info)

            av_packet_shrink_side_data(pkt, AV_PKT_DATA_H263_MB_INFO, s->mb_info_size);

    } else {

        assert((put_bits_ptr(&s->pb) == s->pb.buf));

        s->frame_bits = 0;

    }

    assert((s->frame_bits & 7) == 0);

    pkt->size = s->frame_bits / 8;

    *got_packet = !!pkt->size;

    return 0;

}


static inline void RENAME(rgb32tobgr15)(const uint8_t *src, uint8_t *dst, unsigned src_size)

{

	const uint8_t *s = src;

	const uint8_t *end;

#ifdef HAVE_MMX

	const uint8_t *mm_end;

#endif

	uint16_t *d = (uint16_t *)dst;

	end = s + src_size;

#ifdef HAVE_MMX

	__asm __volatile(PREFETCH"	%0"::"m"(*src):"memory");

	__asm __volatile(

	    "movq	%0, %%mm7\n\t"

	    "movq	%1, %%mm6\n\t"

	    ::"m"(red_15mask),"m"(green_15mask));

	mm_end = end - 15;

	while(s < mm_end)

	{

	    __asm __volatile(

		PREFETCH" 32%1\n\t"

		"movd	%1, %%mm0\n\t"

		"movd	4%1, %%mm3\n\t"

		"punpckldq 8%1, %%mm0\n\t"

		"punpckldq 12%1, %%mm3\n\t"

		"movq	%%mm0, %%mm1\n\t"

		"movq	%%mm0, %%mm2\n\t"

		"movq	%%mm3, %%mm4\n\t"

		"movq	%%mm3, %%mm5\n\t"

		"psllq	$7, %%mm0\n\t"

		"psllq	$7, %%mm3\n\t"

		"pand	%%mm7, %%mm0\n\t"

		"pand	%%mm7, %%mm3\n\t"

		"psrlq	$6, %%mm1\n\t"

		"psrlq	$6, %%mm4\n\t"

		"pand	%%mm6, %%mm1\n\t"

		"pand	%%mm6, %%mm4\n\t"

		"psrlq	$19, %%mm2\n\t"

		"psrlq	$19, %%mm5\n\t"

		"pand	%2, %%mm2\n\t"

		"pand	%2, %%mm5\n\t"

		"por	%%mm1, %%mm0\n\t"

		"por	%%mm4, %%mm3\n\t"

		"por	%%mm2, %%mm0\n\t"

		"por	%%mm5, %%mm3\n\t"

		"psllq	$16, %%mm3\n\t"

		"por	%%mm3, %%mm0\n\t"

		MOVNTQ"	%%mm0, %0\n\t"

		:"=m"(*d):"m"(*s),"m"(blue_15mask):"memory");

		d += 4;

		s += 16;

	}

	__asm __volatile(SFENCE:::"memory");

	__asm __volatile(EMMS:::"memory");

#endif

	while(s < end)

	{

		const int src= *((uint32_t*)s)++;

		*d++ = ((src&0xF8)<<7) + ((src&0xF800)>>6) + ((src&0xF80000)>>19);

	}

}


static void FUNC(hevc_loop_filter_chroma)(uint8_t *_pix, ptrdiff_t _xstride,

                                          ptrdiff_t _ystride, int *_tc,

                                          uint8_t *_no_p, uint8_t *_no_q)

{

    int d, j, no_p, no_q;

    pixel *pix        = (pixel *)_pix;

    ptrdiff_t xstride = _xstride / sizeof(pixel);

    ptrdiff_t ystride = _ystride / sizeof(pixel);

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

        const int tc = _tc[j] << (BIT_DEPTH - 8);

        if (tc <= 0) {

            pix += 4 * ystride;

            continue;

        }

        no_p = _no_p[j];

        no_q = _no_q[j];

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

            int delta0;

            const int p1 = P1;

            const int p0 = P0;

            const int q0 = Q0;

            const int q1 = Q1;

            delta0 = av_clip((((q0 - p0) << 2) + p1 - q1 + 4) >> 3, -tc, tc);

            if (!no_p)

                P0 = av_clip_pixel(p0 + delta0);

            if (!no_q)

                Q0 = av_clip_pixel(q0 - delta0);

            pix += ystride;

        }

    }

}


static inline void xchg_mb_border(H264Context *h, uint8_t *src_y,

                                  uint8_t *src_cb, uint8_t *src_cr,

                                  int linesize, int uvlinesize,

                                  int xchg, int simple, int pixel_shift){

    MpegEncContext * const s = &h->s;

    int deblock_left;

    int deblock_top;

    int top_idx = 1;

    uint8_t *top_border_m1;

    uint8_t *top_border;

    if(!simple && FRAME_MBAFF){

        if(s->mb_y&1){

            if(!MB_MBAFF)

                return;

        }else{

            top_idx = MB_MBAFF ? 0 : 1;

        }

    }

    if(h->deblocking_filter == 2) {

        deblock_left = h->left_type[0];

        deblock_top  = h->top_type;

    } else {

        deblock_left = (s->mb_x > 0);

        deblock_top =  (s->mb_y > !!MB_FIELD);

    }

    src_y  -=   linesize + 1 + pixel_shift;

    src_cb -= uvlinesize + 1 + pixel_shift;

    src_cr -= uvlinesize + 1 + pixel_shift;

    top_border_m1 = h->top_borders[top_idx][s->mb_x-1];

    top_border    = h->top_borders[top_idx][s->mb_x];

#define XCHG(a,b,xchg)\

    if (pixel_shift) {\

        if (xchg) {\

            AV_SWAP64(b+0,a+0);\

            AV_SWAP64(b+8,a+8);\

        } else {\

            AV_COPY128(b,a); \

        }\

    } else \

if (xchg) AV_SWAP64(b,a);\

else      AV_COPY64(b,a);

    if(deblock_top){

        if(deblock_left){

            XCHG(top_border_m1 + (8 << pixel_shift), src_y - (7 << pixel_shift), 1);

        }

        XCHG(top_border + (0 << pixel_shift), src_y + (1 << pixel_shift), xchg);

        XCHG(top_border + (8 << pixel_shift), src_y + (9 << pixel_shift), 1);

        if(s->mb_x+1 < s->mb_width){

            XCHG(h->top_borders[top_idx][s->mb_x+1], src_y + (17 << pixel_shift), 1);

        }

    }

    if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){

        if(deblock_top){

            if(deblock_left){

                XCHG(top_border_m1 + (16 << pixel_shift), src_cb - (7 << pixel_shift), 1);

                XCHG(top_border_m1 + (24 << pixel_shift), src_cr - (7 << pixel_shift), 1);

            }

            XCHG(top_border + (16 << pixel_shift), src_cb+1+pixel_shift, 1);

            XCHG(top_border + (24 << pixel_shift), src_cr+1+pixel_shift, 1);

        }

    }

}


static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output,

                             AVPacket *avpkt)

{

    int ret;

    HEVCContext *s = avctx->priv_data;

    if (!avpkt->size) {

        ret = ff_hevc_output_frame(s, data, 1);

        if (ret < 0)

            return ret;

        *got_output = ret;

        return 0;

    }

    s->ref = NULL;

    ret    = decode_nal_units(s, avpkt->data, avpkt->size);

    if (ret < 0)

        return ret;

    /* verify the SEI checksum */

    if (avctx->err_recognition & AV_EF_CRCCHECK && s->is_decoded &&

        avctx->err_recognition & AV_EF_EXPLODE &&

        s->is_md5) {

        ret = verify_md5(s, s->ref->frame);

        if (ret < 0) {

            ff_hevc_unref_frame(s, s->ref, ~0);

            return ret;

        }

    }

    s->is_md5 = 0;

    if (s->is_decoded) {

        av_log(avctx, AV_LOG_DEBUG, "Decoded frame with POC %d.\n", s->poc);

        s->is_decoded = 0;

    }

    if (s->output_frame->buf[0]) {

        av_frame_move_ref(data, s->output_frame);

        *got_output = 1;

    }

    return avpkt->size;

}


static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)

{

    uint32_t dw10 = le32_to_cpu(cmd->cdw10);

    uint32_t result;

    switch (dw10) {

    case NVME_VOLATILE_WRITE_CACHE:

        result = blk_enable_write_cache(n->conf.blk);

        break;

    case NVME_NUMBER_OF_QUEUES:

        result = cpu_to_le32((n->num_queues - 1) | ((n->num_queues - 1) << 16));

        break;

    default:

        return NVME_INVALID_FIELD | NVME_DNR;

    }

    req->cqe.result = result;

    return NVME_SUCCESS;

}


static int decode_subframe(TAKDecContext *s, int32_t *decoded,

                           int subframe_size, int prev_subframe_size)

{

    GetBitContext *gb = &s->gb;

    int x, y, i, j, ret = 0;

    int dshift, size, filter_quant, filter_order, filter_order16;

    int tfilter[MAX_PREDICTORS];

    if (!get_bits1(gb))

        return decode_residues(s, decoded, subframe_size);

    filter_order = predictor_sizes[get_bits(gb, 4)];

    if (prev_subframe_size > 0 && get_bits1(gb)) {

        if (filter_order > prev_subframe_size)

            return AVERROR_INVALIDDATA;

        decoded       -= filter_order;

        subframe_size += filter_order;

        if (filter_order > subframe_size)

            return AVERROR_INVALIDDATA;

    } else {

        int lpc_mode;

        if (filter_order > subframe_size)

            return AVERROR_INVALIDDATA;

        lpc_mode = get_bits(gb, 2);

        if (lpc_mode > 2)

            return AVERROR_INVALIDDATA;

        if ((ret = decode_residues(s, decoded, filter_order)) < 0)

            return ret;

        if (lpc_mode)

            decode_lpc(decoded, lpc_mode, filter_order);

    }

    dshift = get_bits_esc4(gb);

    size   = get_bits1(gb) + 6;

    filter_quant = 10;

    if (get_bits1(gb)) {

        filter_quant -= get_bits(gb, 3) + 1;

        if (filter_quant < 3)

            return AVERROR_INVALIDDATA;

    }

    s->predictors[0] = get_sbits(gb, 10);

    s->predictors[1] = get_sbits(gb, 10);

    s->predictors[2] = get_sbits(gb, size) << (10 - size);

    s->predictors[3] = get_sbits(gb, size) << (10 - size);

    if (filter_order > 4) {

        int tmp = size - get_bits1(gb);

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

            if (!(i & 3))

                x = tmp - get_bits(gb, 2);

            s->predictors[i] = get_sbits(gb, x) << (10 - size);

        }

    }

    tfilter[0] = s->predictors[0] << 6;

    for (i = 1; i < filter_order; i++) {

        int32_t *p1 = &tfilter[0];

        int32_t *p2 = &tfilter[i - 1];

        for (j = 0; j < (i + 1) / 2; j++) {

            x     = *p1 + (s->predictors[i] * *p2 + 256 >> 9);

            *p2  += s->predictors[i] * *p1 + 256 >> 9;

            *p1++ = x;

            p2--;

        }

        tfilter[i] = s->predictors[i] << 6;

    }

    filter_order16 = FFALIGN(filter_order, 16);

    AV_ZERO128(s->filter + filter_order16 - 16);

    AV_ZERO128(s->filter + filter_order16 -  8);

    x = 1 << (32 - (15 - filter_quant));

    y = 1 << ((15 - filter_quant) - 1);

    for (i = 0, j = filter_order - 1; i < filter_order / 2; i++, j--) {

        s->filter[j] = x - ((tfilter[i] + y) >> (15 - filter_quant));

        s->filter[i] = x - ((tfilter[j] + y) >> (15 - filter_quant));

    }

    if ((ret = decode_residues(s, &decoded[filter_order],

                               subframe_size - filter_order)) < 0)

        return ret;

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

        s->residues[i] = *decoded++ >> dshift;

    y    = FF_ARRAY_ELEMS(s->residues) - filter_order;

    x    = subframe_size - filter_order;

    while (x > 0) {

        int tmp = FFMIN(y, x);

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

            int v = 1 << (filter_quant - 1);

            v += s->adsp.scalarproduct_int16(&s->residues[i], s->filter,

                                             filter_order16);

            v = (av_clip_intp2(v >> filter_quant, 13) << dshift) - *decoded;

            *decoded++ = v;

            s->residues[filter_order + i] = v >> dshift;

        }

        x -= tmp;

        if (x > 0)

            memcpy(s->residues, &s->residues[y], 2 * filter_order);

    }

    emms_c();

    return 0;

}


iscsi_allocmap_update(IscsiLun *iscsilun, int64_t sector_num,

                      int nb_sectors, bool allocated, bool valid)

{

    int64_t cl_num_expanded, nb_cls_expanded, cl_num_shrunk, nb_cls_shrunk;

    if (iscsilun->allocmap == NULL) {

        return;

    }

    /* expand to entirely contain all affected clusters */

    cl_num_expanded = sector_num / iscsilun->cluster_sectors;

    nb_cls_expanded = DIV_ROUND_UP(sector_num + nb_sectors,

                                   iscsilun->cluster_sectors) - cl_num_expanded;

    /* shrink to touch only completely contained clusters */

    cl_num_shrunk = DIV_ROUND_UP(sector_num, iscsilun->cluster_sectors);

    nb_cls_shrunk = (sector_num + nb_sectors) / iscsilun->cluster_sectors

                      - cl_num_shrunk;

    if (allocated) {

        bitmap_set(iscsilun->allocmap, cl_num_expanded, nb_cls_expanded);

    } else {

        bitmap_clear(iscsilun->allocmap, cl_num_shrunk, nb_cls_shrunk);

    }

    if (iscsilun->allocmap_valid == NULL) {

        return;

    }

    if (valid) {

        bitmap_set(iscsilun->allocmap_valid, cl_num_shrunk, nb_cls_shrunk);

    } else {

        bitmap_clear(iscsilun->allocmap_valid, cl_num_expanded,

                     nb_cls_expanded);

    }

}


static int dca_decode_frame(AVCodecContext * avctx,

                            void *data, int *data_size,

                            const uint8_t * buf, int buf_size)

{

    int i, j, k;

    int16_t *samples = data;

    DCAContext *s = avctx->priv_data;

    int channels;

    s->dca_buffer_size = dca_convert_bitstream(buf, buf_size, s->dca_buffer, DCA_MAX_FRAME_SIZE);

    if (s->dca_buffer_size == -1) {

        av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n");

        return -1;

    }

    init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8);

    if (dca_parse_frame_header(s) < 0) {

        //seems like the frame is corrupt, try with the next one

        *data_size=0;

        return buf_size;

    }

    //set AVCodec values with parsed data

    avctx->sample_rate = s->sample_rate;

    avctx->bit_rate = s->bit_rate;

    channels = s->prim_channels + !!s->lfe;

    if(avctx->request_channels == 2 && s->prim_channels > 2) {

        channels = 2;

        s->output = DCA_STEREO;

    }

    avctx->channels = channels;

    if(*data_size < (s->sample_blocks / 8) * 256 * sizeof(int16_t) * channels)

        return -1;

    *data_size = 0;

    for (i = 0; i < (s->sample_blocks / 8); i++) {

        dca_decode_block(s);

        s->dsp.float_to_int16(s->tsamples, s->samples, 256 * channels);

        /* interleave samples */

        for (j = 0; j < 256; j++) {

            for (k = 0; k < channels; k++)

                samples[k] = s->tsamples[j + k * 256];

            samples += channels;

        }

        *data_size += 256 * sizeof(int16_t) * channels;

    }

    return buf_size;

}


static int teletext_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt)

{

    TeletextContext *ctx = avctx->priv_data;

    AVSubtitle      *sub = data;

    int             ret = 0;

    if (!ctx->vbi) {

        if (!(ctx->vbi = vbi_decoder_new()))

            return AVERROR(ENOMEM);

        if (!vbi_event_handler_add(ctx->vbi, VBI_EVENT_TTX_PAGE, handler, ctx)) {

            vbi_decoder_delete(ctx->vbi);

            ctx->vbi = NULL;

            return AVERROR(ENOMEM);

        }

    }

    if (avctx->pkt_timebase.den && pkt->pts != AV_NOPTS_VALUE)

        ctx->pts = av_rescale_q(pkt->pts, avctx->pkt_timebase, AV_TIME_BASE_Q);

    if (pkt->size) {

        int lines;

        const int full_pes_size = pkt->size + 45; /* PES header is 45 bytes */

        // We allow unreasonably big packets, even if the standard only allows a max size of 1472

        if (full_pes_size < 184 || full_pes_size > 65504 || full_pes_size % 184 != 0)

            return AVERROR_INVALIDDATA;

        ctx->handler_ret = pkt->size;

        if (data_identifier_is_teletext(*pkt->data)) {

            if ((lines = slice_to_vbi_lines(ctx, pkt->data + 1, pkt->size - 1)) < 0)

                return lines;

            av_dlog(avctx, "ctx=%p buf_size=%d lines=%u pkt_pts=%7.3f\n",

                    ctx, pkt->size, lines, (double)pkt->pts/90000.0);

            if (lines > 0) {

#ifdef DEBUG

                int i;

                av_log(avctx, AV_LOG_DEBUG, "line numbers:");

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

                    av_log(avctx, AV_LOG_DEBUG, " %d", ctx->sliced[i].line);

                av_log(avctx, AV_LOG_DEBUG, "\n");

#endif

                vbi_decode(ctx->vbi, ctx->sliced, lines, 0.0);

                ctx->lines_processed += lines;

            }

        }

        ctx->pts = AV_NOPTS_VALUE;

        ret = ctx->handler_ret;

    }

    if (ret < 0)

        return ret;

    // is there a subtitle to pass?

    if (ctx->nb_pages) {

        int i;

        sub->format = ctx->format_id;

        sub->start_display_time = 0;

        sub->end_display_time = ctx->sub_duration;

        sub->num_rects = 0;

        sub->pts = ctx->pages->pts;

        if (ctx->pages->sub_rect->type != SUBTITLE_NONE) {

            sub->rects = av_malloc(sizeof(*sub->rects));

            if (sub->rects) {

                sub->num_rects = 1;

                sub->rects[0] = ctx->pages->sub_rect;

            } else {

                ret = AVERROR(ENOMEM);

            }

        } else {

            av_log(avctx, AV_LOG_DEBUG, "sending empty sub\n");

            sub->rects = NULL;

        }

        if (!sub->rects) // no rect was passed

            subtitle_rect_free(&ctx->pages->sub_rect);

        for (i = 0; i < ctx->nb_pages - 1; i++)

            ctx->pages[i] = ctx->pages[i + 1];

        ctx->nb_pages--;

        if (ret >= 0)

            *data_size = 1;

    } else

        *data_size = 0;

    return ret;

}


static void pc_init_pci_1_5(QEMUMachineInitArgs *args)

{

    has_pci_info = false;

    pc_init_pci(args);

}


static int usbnet_can_receive(NetClientState *nc)
{
    USBNetState *s = qemu_get_nic_opaque(nc);
    if (is_rndis(s) && s->rndis_state != RNDIS_DATA_INITIALIZED) {
        return 1;
    return !s->in_len;


static inline int hpel_motion_lowres(MpegEncContext *s,

                                     uint8_t *dest, uint8_t *src,

                                     int field_based, int field_select,

                                     int src_x, int src_y,

                                     int width, int height, int stride,

                                     int h_edge_pos, int v_edge_pos,

                                     int w, int h, h264_chroma_mc_func *pix_op,

                                     int motion_x, int motion_y)

{

    const int lowres   = s->avctx->lowres;

    const int op_index = FFMIN(lowres, 3);

    const int s_mask   = (2 << lowres) - 1;

    int emu = 0;

    int sx, sy;

    if (s->quarter_sample) {

        motion_x /= 2;

        motion_y /= 2;

    }

    sx = motion_x & s_mask;

    sy = motion_y & s_mask;

    src_x += motion_x >> lowres + 1;

    src_y += motion_y >> lowres + 1;

    src   += src_y * stride + src_x;

    if ((unsigned)src_x > FFMAX( h_edge_pos - (!!sx) - w,                 0) ||

        (unsigned)src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) {

        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w + 1,

                                (h + 1) << field_based, src_x,

                                src_y   << field_based,

                                h_edge_pos,

                                v_edge_pos);

        src = s->edge_emu_buffer;

        emu = 1;

    }

    sx = (sx << 2) >> lowres;

    sy = (sy << 2) >> lowres;

    if (field_select)

        src += s->linesize;

    pix_op[op_index](dest, src, stride, h, sx, sy);

    return emu;

}


int qemu_devtree_add_subnode(void *fdt, const char *name)

{

    int offset;

    char *dupname = g_strdup(name);

    char *basename = strrchr(dupname, '/');

    int retval;

    if (!basename) {

        return -1;

    }

    basename[0] = '\0';

    basename++;

    offset = fdt_path_offset(fdt, dupname);

    if (offset < 0) {

        return offset;

    }

    retval = fdt_add_subnode(fdt, offset, basename);

    g_free(dupname);

    return retval;

}


av_cold void ff_mlz_init_dict(void* context, MLZ *mlz) {

    mlz->dict = av_malloc_array(TABLE_SIZE, sizeof(*mlz->dict));

    mlz->flush_code            = FLUSH_CODE;

    mlz->current_dic_index_max = DIC_INDEX_INIT;

    mlz->dic_code_bit          = CODE_BIT_INIT;

    mlz->bump_code             = (DIC_INDEX_INIT - 1);

    mlz->next_code             = FIRST_CODE;

    mlz->freeze_flag           = 0;

    mlz->context               = context;

}


static int decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice,

                               uint16_t *dst, int dst_stride,

                               const uint8_t *buf, unsigned buf_size,

                               const int16_t *qmat, int log2_blocks_per_mb)

{

    ProresContext *ctx = avctx->priv_data;

    LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]);

    int16_t *block;

    GetBitContext gb;

    int i, j, blocks_per_slice = slice->mb_count << log2_blocks_per_mb;

    int ret;

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

        ctx->bdsp.clear_block(blocks+(i<<6));

    init_get_bits(&gb, buf, buf_size << 3);

    decode_dc_coeffs(&gb, blocks, blocks_per_slice);

    if ((ret = decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice)) < 0)

        return ret;

    block = blocks;

    for (i = 0; i < slice->mb_count; i++) {

        for (j = 0; j < log2_blocks_per_mb; j++) {

            ctx->prodsp.idct_put(dst,              dst_stride, block+(0<<6), qmat);

            ctx->prodsp.idct_put(dst+4*dst_stride, dst_stride, block+(1<<6), qmat);

            block += 2*64;

            dst += 8;

        }

    }

    return 0;

}


static int mxf_write_footer(AVFormatContext *s)

{

    MXFContext *mxf = s->priv_data;

    AVIOContext *pb = s->pb;

    mxf->duration = mxf->last_indexed_edit_unit + mxf->edit_units_count;

    mxf_write_klv_fill(s);

    mxf->footer_partition_offset = avio_tell(pb);

    if (mxf->edit_unit_byte_count) { // no need to repeat index

        mxf_write_partition(s, 0, 0, footer_partition_key, 0);

    } else {

        mxf_write_partition(s, 0, 2, footer_partition_key, 0);

        mxf_write_klv_fill(s);

        mxf_write_index_table_segment(s);

    }

    mxf_write_klv_fill(s);

    mxf_write_random_index_pack(s);

    if (s->pb->seekable) {

        avio_seek(pb, 0, SEEK_SET);

        if (mxf->edit_unit_byte_count) {

            mxf_write_partition(s, 1, 2, header_closed_partition_key, 1);

            mxf_write_klv_fill(s);

            mxf_write_index_table_segment(s);

        } else {

            mxf_write_partition(s, 0, 0, header_closed_partition_key, 1);

        }

    }

    ff_audio_interleave_close(s);

    av_freep(&mxf->index_entries);

    av_freep(&mxf->body_partition_offset);

    av_freep(&mxf->timecode_track->priv_data);

    av_freep(&mxf->timecode_track);

    mxf_free(s);

    return 0;

}


static void pxa2xx_pcmcia_initfn(Object *obj)

{

    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    PXA2xxPCMCIAState *s = PXA2XX_PCMCIA(obj);

    memory_region_init(&s->container_mem, obj, "container", 0x10000000);

    sysbus_init_mmio(sbd, &s->container_mem);

    /* Socket I/O Memory Space */

    memory_region_init_io(&s->iomem, NULL, &pxa2xx_pcmcia_io_ops, s,

                          "pxa2xx-pcmcia-io", 0x04000000);

    memory_region_add_subregion(&s->container_mem, 0x00000000,

                                &s->iomem);

    /* Then next 64 MB is reserved */

    /* Socket Attribute Memory Space */

    memory_region_init_io(&s->attr_iomem, NULL, &pxa2xx_pcmcia_attr_ops, s,

                          "pxa2xx-pcmcia-attribute", 0x04000000);

    memory_region_add_subregion(&s->container_mem, 0x08000000,

                                &s->attr_iomem);

    /* Socket Common Memory Space */

    memory_region_init_io(&s->common_iomem, NULL, &pxa2xx_pcmcia_common_ops, s,

                          "pxa2xx-pcmcia-common", 0x04000000);

    memory_region_add_subregion(&s->container_mem, 0x0c000000,

                                &s->common_iomem);

    s->slot.irq = qemu_allocate_irqs(pxa2xx_pcmcia_set_irq, s, 1)[0];

    object_property_add_link(obj, "card", TYPE_PCMCIA_CARD,

                             (Object **)&s->card,

                             NULL, /* read-only property */

                             0, NULL);

}


static int mirror_cow_align(MirrorBlockJob *s, int64_t *offset,

                            uint64_t *bytes)

{

    bool need_cow;

    int ret = 0;

    int64_t align_offset = *offset;

    unsigned int align_bytes = *bytes;

    int max_bytes = s->granularity * s->max_iov;

    assert(*bytes < INT_MAX);

    need_cow = !test_bit(*offset / s->granularity, s->cow_bitmap);

    need_cow |= !test_bit((*offset + *bytes - 1) / s->granularity,

                          s->cow_bitmap);

    if (need_cow) {

        bdrv_round_to_clusters(blk_bs(s->target), *offset, *bytes,

                               &align_offset, &align_bytes);

    }

    if (align_bytes > max_bytes) {

        align_bytes = max_bytes;

        if (need_cow) {

            align_bytes = QEMU_ALIGN_DOWN(align_bytes, s->target_cluster_size);

        }

    }

    /* Clipping may result in align_bytes unaligned to chunk boundary, but

     * that doesn't matter because it's already the end of source image. */

    align_bytes = mirror_clip_bytes(s, align_offset, align_bytes);

    ret = align_offset + align_bytes - (*offset + *bytes);

    *offset = align_offset;

    *bytes = align_bytes;

    assert(ret >= 0);

    return ret;

}


static void GCC_FMT_ATTR(2, 3) blkverify_err(BlkverifyAIOCB *acb,

                                             const char *fmt, ...)

{

    va_list ap;

    va_start(ap, fmt);

    fprintf(stderr, "blkverify: %s sector_num=%" PRId64 " nb_sectors=%d ",

            acb->is_write ? "write" : "read", acb->sector_num,

            acb->nb_sectors);

    vfprintf(stderr, fmt, ap);

    fprintf(stderr, "\n");

    va_end(ap);

    exit(1);

}


static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt)

{

    MatroskaMuxContext *mkv = s->priv_data;

    int codec_type          = s->streams[pkt->stream_index]->codec->codec_type;

    int keyframe            = !!(pkt->flags & AV_PKT_FLAG_KEY);

    int cluster_size;

    int cluster_size_limit;

    int64_t cluster_time;

    int64_t cluster_time_limit;

    AVIOContext *pb;

    int ret;

    if (mkv->tracks[pkt->stream_index].write_dts)

        cluster_time = pkt->dts - mkv->cluster_pts;

    else

        cluster_time = pkt->pts - mkv->cluster_pts;

    // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or

    // after 4k and on a keyframe

    if (s->pb->seekable) {

        pb = s->pb;

        cluster_size = avio_tell(pb) - mkv->cluster_pos;

        cluster_time_limit = 5000;

        cluster_size_limit = 5 * 1024 * 1024;

    } else {

        pb = mkv->dyn_bc;

        cluster_size = avio_tell(pb);

        cluster_time_limit = 1000;

        cluster_size_limit = 32 * 1024;

    }

    if (mkv->cluster_pos &&

        (cluster_size > cluster_size_limit ||

         cluster_time > cluster_time_limit ||

         (codec_type == AVMEDIA_TYPE_VIDEO && keyframe &&

          cluster_size > 4 * 1024))) {

        av_log(s, AV_LOG_DEBUG, "Starting new cluster at offset %" PRIu64

               " bytes, pts %" PRIu64 "dts %" PRIu64 "\n",

               avio_tell(pb), pkt->pts, pkt->dts);

        end_ebml_master(pb, mkv->cluster);

        mkv->cluster_pos = 0;

        if (mkv->dyn_bc)

            mkv_flush_dynbuf(s);

    }

    // check if we have an audio packet cached

    if (mkv->cur_audio_pkt.size > 0) {

        ret = mkv_write_packet_internal(s, &mkv->cur_audio_pkt);

        av_free_packet(&mkv->cur_audio_pkt);

        if (ret < 0) {

            av_log(s, AV_LOG_ERROR, "Could not write cached audio packet ret:%d\n", ret);

            return ret;

        }

    }

    // buffer an audio packet to ensure the packet containing the video

    // keyframe's timecode is contained in the same cluster for WebM

    if (codec_type == AVMEDIA_TYPE_AUDIO) {

        mkv->cur_audio_pkt = *pkt;

        if (pkt->buf) {

            mkv->cur_audio_pkt.buf = av_buffer_ref(pkt->buf);

            ret = mkv->cur_audio_pkt.buf ? 0 : AVERROR(ENOMEM);

        } else

            ret = av_dup_packet(&mkv->cur_audio_pkt);

    } else

        ret = mkv_write_packet_internal(s, pkt);

    return ret;

}


static int64_t getutime(void)

{

#ifdef HAVE_GETRUSAGE

    struct rusage rusage;

    getrusage(RUSAGE_SELF, &rusage);

    return (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;

#elif defined(__MINGW32__)

  return av_gettime();

#endif

}


static void colored_fputs(int level, const char *str)

{

    if (!*str)

        return;

    if (use_color < 0) {

#if HAVE_SETCONSOLETEXTATTRIBUTE

        CONSOLE_SCREEN_BUFFER_INFO con_info;

        con = GetStdHandle(STD_ERROR_HANDLE);

        use_color = (con != INVALID_HANDLE_VALUE) && !getenv("NO_COLOR") &&

                    !getenv("AV_LOG_FORCE_NOCOLOR");

        if (use_color) {

            GetConsoleScreenBufferInfo(con, &con_info);

            attr_orig  = con_info.wAttributes;

            background = attr_orig & 0xF0;

        }

#elif HAVE_ISATTY

        use_color = !getenv("NO_COLOR") && !getenv("AV_LOG_FORCE_NOCOLOR") &&

                    (getenv("TERM") && isatty(2) ||

                     getenv("AV_LOG_FORCE_COLOR"));

        if (getenv("AV_LOG_FORCE_256COLOR"))

            use_color *= 256;

#else

        use_color = getenv("AV_LOG_FORCE_COLOR") && !getenv("NO_COLOR") &&

                   !getenv("AV_LOG_FORCE_NOCOLOR");

#endif

    }

#if HAVE_SETCONSOLETEXTATTRIBUTE

    if (use_color && level != AV_LOG_INFO/8)

        SetConsoleTextAttribute(con, background | color[level]);

    fputs(str, stderr);

    if (use_color && level != AV_LOG_INFO/8)

        SetConsoleTextAttribute(con, attr_orig);

#else

    if (use_color == 1 && level != AV_LOG_INFO/8) {

        fprintf(stderr,

                "\033[%d;3%dm%s\033[0m",

                (color[level] >> 4) & 15,

                color[level] & 15,

                str);

    } else if (use_color == 256 && level != AV_LOG_INFO/8) {

        fprintf(stderr,

                "\033[48;5;%dm\033[38;5;%dm%s\033[0m",

                (color[level] >> 16) & 0xff,

                (color[level] >> 8) & 0xff,

                str);

    } else

        fputs(str, stderr);

#endif

}


static int alsa_poll_helper (snd_pcm_t *handle, struct pollhlp *hlp, int mask)

{

    int i, count, err;

    struct pollfd *pfds;

    count = snd_pcm_poll_descriptors_count (handle);

    if (count <= 0) {

        dolog ("Could not initialize poll mode\n"

               "Invalid number of poll descriptors %d\n", count);

        return -1;

    }

    pfds = audio_calloc ("alsa_poll_helper", count, sizeof (*pfds));

    if (!pfds) {

        dolog ("Could not initialize poll mode\n");

        return -1;

    }

    err = snd_pcm_poll_descriptors (handle, pfds, count);

    if (err < 0) {

        alsa_logerr (err, "Could not initialize poll mode\n"

                     "Could not obtain poll descriptors\n");

        g_free (pfds);

        return -1;

    }

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

        if (pfds[i].events & POLLIN) {

            err = qemu_set_fd_handler (pfds[i].fd, alsa_poll_handler,

                                       NULL, hlp);

        }

        if (pfds[i].events & POLLOUT) {

            if (conf.verbose) {

                dolog ("POLLOUT %d %d\n", i, pfds[i].fd);

            }

            err = qemu_set_fd_handler (pfds[i].fd, NULL,

                                       alsa_poll_handler, hlp);

        }

        if (conf.verbose) {

            dolog ("Set handler events=%#x index=%d fd=%d err=%d\n",

                   pfds[i].events, i, pfds[i].fd, err);

        }

        if (err) {

            dolog ("Failed to set handler events=%#x index=%d fd=%d err=%d\n",

                   pfds[i].events, i, pfds[i].fd, err);

            while (i--) {

                qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL);

            }

            g_free (pfds);

            return -1;

        }

    }

    hlp->pfds = pfds;

    hlp->count = count;

    hlp->handle = handle;

    hlp->mask = mask;

    return 0;

}


AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms,

                                                     enum AVSampleFormat sample_fmt, int size,

                                                     int64_t channel_layout, int planar)

{

    AVFilterBuffer *samples = av_mallocz(sizeof(AVFilterBuffer));

    AVFilterBufferRef *ref = NULL;

    int i, sample_size, chans_nb, bufsize, per_channel_size, step_size = 0;

    char *buf;

    if (!samples || !(ref = av_mallocz(sizeof(AVFilterBufferRef))))

        goto fail;

    ref->buf                   = samples;

    ref->format                = sample_fmt;

    ref->audio = av_mallocz(sizeof(AVFilterBufferRefAudioProps));

    if (!ref->audio)

        goto fail;

    ref->audio->channel_layout = channel_layout;

    ref->audio->size           = size;

    ref->audio->planar         = planar;

    /* make sure the buffer gets read permission or it's useless for output */

    ref->perms = perms | AV_PERM_READ;

    samples->refcount   = 1;

    samples->free       = ff_avfilter_default_free_buffer;

    sample_size = av_get_bytes_per_sample(sample_fmt);

    chans_nb = av_get_channel_layout_nb_channels(channel_layout);

    per_channel_size = size/chans_nb;

    ref->audio->nb_samples = per_channel_size/sample_size;

    /* Set the number of bytes to traverse to reach next sample of a particular channel:

     * For planar, this is simply the sample size.

     * For packed, this is the number of samples * sample_size.

     */

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

        samples->linesize[i] = planar > 0 ? per_channel_size : sample_size;

    memset(&samples->linesize[chans_nb], 0, (8-chans_nb) * sizeof(samples->linesize[0]));

    /* Calculate total buffer size, round to multiple of 16 to be SIMD friendly */

    bufsize = (size + 15)&~15;

    buf = av_malloc(bufsize);

    if (!buf)

        goto fail;

    /* For planar, set the start point of each channel's data within the buffer

     * For packed, set the start point of the entire buffer only

     */

    samples->data[0] = buf;

    if (buf && planar) {

        for (i = 1; i < chans_nb; i++) {

            step_size += per_channel_size;

            samples->data[i] = buf + step_size;

        }

    } else {

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

            samples->data[i] = buf;

    }

    memset(&samples->data[chans_nb], 0, (8-chans_nb) * sizeof(samples->data[0]));

    memcpy(ref->data,     samples->data,     sizeof(ref->data));

    memcpy(ref->linesize, samples->linesize, sizeof(ref->linesize));

    return ref;

fail:

    if (ref)

        av_free(ref->audio);

    av_free(ref);

    av_free(samples);

    return NULL;

}


static MigrationState *migrate_init(const MigrationParams *params)

{

    MigrationState *s = migrate_get_current();

    int64_t bandwidth_limit = s->bandwidth_limit;

    bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];

    int64_t xbzrle_cache_size = s->xbzrle_cache_size;

    memcpy(enabled_capabilities, s->enabled_capabilities,

           sizeof(enabled_capabilities));

    memset(s, 0, sizeof(*s));

    s->params = *params;

    memcpy(s->enabled_capabilities, enabled_capabilities,

           sizeof(enabled_capabilities));

    s->xbzrle_cache_size = xbzrle_cache_size;

    s->bandwidth_limit = bandwidth_limit;

    s->state = MIG_STATE_SETUP;

    trace_migrate_set_state(MIG_STATE_SETUP);

    s->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);

    return s;

}


static void chr_read(void *opaque, const uint8_t *buf, int size)
{
    TestServer *s = opaque;
    CharDriverState *chr = s->chr;
    VhostUserMsg msg;
    uint8_t *p = (uint8_t *) &msg;
    int fd;
    if (size != VHOST_USER_HDR_SIZE) {
        g_test_message("Wrong message size received %d\n", size);
        return;
    g_mutex_lock(&s->data_mutex);
    memcpy(p, buf, VHOST_USER_HDR_SIZE);
    if (msg.size) {
        p += VHOST_USER_HDR_SIZE;
        size = qemu_chr_fe_read_all(chr, p, msg.size);
        if (size != msg.size) {
            g_test_message("Wrong message size received %d != %d\n",
                           size, msg.size);
            return;
    switch (msg.request) {
    case VHOST_USER_GET_FEATURES:
        /* send back features to qemu */
        msg.flags |= VHOST_USER_REPLY_MASK;
        msg.size = sizeof(m.payload.u64);
        msg.payload.u64 = 0x1ULL << VHOST_F_LOG_ALL |
            0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES;
        p = (uint8_t *) &msg;
        qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
        break;
    case VHOST_USER_SET_FEATURES:
	g_assert_cmpint(msg.payload.u64 & (0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES),
			!=, 0ULL);
        break;
    case VHOST_USER_GET_PROTOCOL_FEATURES:
        /* send back features to qemu */
        msg.flags |= VHOST_USER_REPLY_MASK;
        msg.size = sizeof(m.payload.u64);
        msg.payload.u64 = 1 << VHOST_USER_PROTOCOL_F_LOG_SHMFD;
        p = (uint8_t *) &msg;
        qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
        break;
    case VHOST_USER_GET_VRING_BASE:
        /* send back vring base to qemu */
        msg.flags |= VHOST_USER_REPLY_MASK;
        msg.size = sizeof(m.payload.state);
        msg.payload.state.num = 0;
        p = (uint8_t *) &msg;
        qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
        assert(msg.payload.state.index < 2);
        s->rings &= ~(0x1ULL << msg.payload.state.index);
        break;
    case VHOST_USER_SET_MEM_TABLE:
        /* received the mem table */
        memcpy(&s->memory, &msg.payload.memory, sizeof(msg.payload.memory));
        s->fds_num = qemu_chr_fe_get_msgfds(chr, s->fds, G_N_ELEMENTS(s->fds));
        /* signal the test that it can continue */
        g_cond_signal(&s->data_cond);
        break;
    case VHOST_USER_SET_VRING_KICK:
    case VHOST_USER_SET_VRING_CALL:
        /* consume the fd */
        qemu_chr_fe_get_msgfds(chr, &fd, 1);
        /*
         * This is a non-blocking eventfd.
         * The receive function forces it to be blocking,
         * so revert it back to non-blocking.
         */
        qemu_set_nonblock(fd);
        break;
    case VHOST_USER_SET_LOG_BASE:
        if (s->log_fd != -1) {
            close(s->log_fd);
            s->log_fd = -1;
        qemu_chr_fe_get_msgfds(chr, &s->log_fd, 1);
        msg.flags |= VHOST_USER_REPLY_MASK;
        msg.size = 0;
        p = (uint8_t *) &msg;
        qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE);
        g_cond_signal(&s->data_cond);
        break;
    case VHOST_USER_SET_VRING_BASE:
        assert(msg.payload.state.index < 2);
        s->rings |= 0x1ULL << msg.payload.state.index;
        break;
    default:
        break;
    g_mutex_unlock(&s->data_mutex);


static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, int precno,

                          uint8_t *expn, int numgbits)

{

    int bandno, empty = 1;

    // init bitstream

    *s->buf = 0;

    s->bit_index = 0;

    // header

    // is the packet empty?

    for (bandno = 0; bandno < rlevel->nbands; bandno++){

        if (rlevel->band[bandno].coord[0][0] < rlevel->band[bandno].coord[0][1]

        &&  rlevel->band[bandno].coord[1][0] < rlevel->band[bandno].coord[1][1]){

            empty = 0;

            break;

        }

    }

    put_bits(s, !empty, 1);

    if (empty){

        j2k_flush(s);

        return 0;

    }

    for (bandno = 0; bandno < rlevel->nbands; bandno++){

        Jpeg2000Band *band = rlevel->band + bandno;

        Jpeg2000Prec *prec = band->prec + precno;

        int yi, xi, pos;

        int cblknw = prec->nb_codeblocks_width;

        if (band->coord[0][0] == band->coord[0][1]

        ||  band->coord[1][0] == band->coord[1][1])

            continue;

        for (pos=0, yi = 0; yi < prec->nb_codeblocks_height; yi++){

            for (xi = 0; xi < cblknw; xi++, pos++){

                prec->cblkincl[pos].val = prec->cblk[yi * cblknw + xi].ninclpasses == 0;

                tag_tree_update(prec->cblkincl + pos);

                prec->zerobits[pos].val = expn[bandno] + numgbits - 1 - prec->cblk[yi * cblknw + xi].nonzerobits;

                tag_tree_update(prec->zerobits + pos);

            }

        }

        for (pos=0, yi = 0; yi < prec->nb_codeblocks_height; yi++){

            for (xi = 0; xi < cblknw; xi++, pos++){

                int pad = 0, llen, length;

                Jpeg2000Cblk *cblk = prec->cblk + yi * cblknw + xi;

                if (s->buf_end - s->buf < 20) // approximately

                    return -1;

                // inclusion information

                tag_tree_code(s, prec->cblkincl + pos, 1);

                if (!cblk->ninclpasses)

                    continue;

                // zerobits information

                tag_tree_code(s, prec->zerobits + pos, 100);

                // number of passes

                putnumpasses(s, cblk->ninclpasses);

                length = cblk->passes[cblk->ninclpasses-1].rate;

                llen = av_log2(length) - av_log2(cblk->ninclpasses) - 2;

                if (llen < 0){

                    pad = -llen;

                    llen = 0;

                }

                // length of code block

                put_bits(s, 1, llen);

                put_bits(s, 0, 1);

                put_num(s, length, av_log2(length)+1+pad);

            }

        }

    }

    j2k_flush(s);

    for (bandno = 0; bandno < rlevel->nbands; bandno++){

        Jpeg2000Band *band = rlevel->band + bandno;

        Jpeg2000Prec *prec = band->prec + precno;

        int yi, cblknw = prec->nb_codeblocks_width;

        for (yi =0; yi < prec->nb_codeblocks_height; yi++){

            int xi;

            for (xi = 0; xi < cblknw; xi++){

                Jpeg2000Cblk *cblk = prec->cblk + yi * cblknw + xi;

                if (cblk->ninclpasses){

                    if (s->buf_end - s->buf < cblk->passes[cblk->ninclpasses-1].rate)

                        return -1;

                    bytestream_put_buffer(&s->buf, cblk->data,   cblk->passes[cblk->ninclpasses-1].rate

                                                               - cblk->passes[cblk->ninclpasses-1].flushed_len);

                    bytestream_put_buffer(&s->buf, cblk->passes[cblk->ninclpasses-1].flushed,

                                                   cblk->passes[cblk->ninclpasses-1].flushed_len);

                }

            }

        }

    }

    return 0;

}


static int ivi_init_tiles(IVIBandDesc *band, IVITile *ref_tile,

                          int p, int b, int t_height, int t_width)

{

    int x, y;

    IVITile *tile = band->tiles;

    for (y = 0; y < band->height; y += t_height) {

        for (x = 0; x < band->width; x += t_width) {

            tile->xpos     = x;

            tile->ypos     = y;

            tile->mb_size  = band->mb_size;

            tile->width    = FFMIN(band->width - x,  t_width);

            tile->height   = FFMIN(band->height - y, t_height);

            tile->is_empty = tile->data_size = 0;

            /* calculate number of macroblocks */

            tile->num_MBs  = IVI_MBs_PER_TILE(tile->width, tile->height,

                                              band->mb_size);

            av_freep(&tile->mbs);

            tile->mbs = av_malloc(tile->num_MBs * sizeof(IVIMbInfo));

            if (!tile->mbs)

                return AVERROR(ENOMEM);

            tile->ref_mbs = 0;

            if (p || b) {

                if (tile->num_MBs != ref_tile->num_MBs) {

                    av_log(NULL, AV_LOG_DEBUG, "ref_tile mismatch\n");

                    return AVERROR_INVALIDDATA;

                }

                tile->ref_mbs = ref_tile->mbs;

                ref_tile++;

            }

            tile++;

        }

    }

    return 0;

}


static av_cold int common_end(AVCodecContext *avctx){
    FFV1Context *s = avctx->priv_data;
    int i, j;
    for(j=0; j<s->slice_count; j++){
        FFV1Context *fs= s->slice_context[j];
        for(i=0; i<s->plane_count; i++){
            PlaneContext *p= &fs->plane[i];
            av_freep(&p->state);
            av_freep(&p->vlc_state);
        av_freep(&fs->sample_buffer);
    av_freep(&avctx->stats_out);
    for(j=0; j<s->quant_table_count; j++){
        av_freep(&s->initial_states[j]);
            FFV1Context *sf= s->slice_context[i];
            av_freep(&sf->rc_stat2[j]);
        av_freep(&s->rc_stat2[j]);
    return 0;


unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx,

                                    const AVDXVAContext *ctx,

                                    const AVFrame *frame)

{

    void *surface = ff_dxva2_get_surface(frame);

    unsigned i;

    for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++)

        if (DXVA_CONTEXT_SURFACE(avctx, ctx, i) == surface)

            return i;

    assert(0);

    return 0;

}