static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,

                           int *is_branch)

{

    int extension = (ctx->opcode >> 6) & 0x3f;

    int minor = (ctx->opcode >> 12) & 0xf;

    uint32_t mips32_op;

    switch (extension) {

    case TEQ:

        mips32_op = OPC_TEQ;

        goto do_trap;

    case TGE:

        mips32_op = OPC_TGE;

        goto do_trap;

    case TGEU:

        mips32_op = OPC_TGEU;

        goto do_trap;

    case TLT:

        mips32_op = OPC_TLT;

        goto do_trap;

    case TLTU:

        mips32_op = OPC_TLTU;

        goto do_trap;

    case TNE:

        mips32_op = OPC_TNE;

    do_trap:

        gen_trap(ctx, mips32_op, rs, rt, -1);

        break;

#ifndef CONFIG_USER_ONLY

    case MFC0:

    case MFC0 + 32:

        check_cp0_enabled(ctx);

        if (rt == 0) {

            /* Treat as NOP. */

            break;

        }

        gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);

        break;

    case MTC0:

    case MTC0 + 32:

        check_cp0_enabled(ctx);

        {

            TCGv t0 = tcg_temp_new();

            gen_load_gpr(t0, rt);

            gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);

            tcg_temp_free(t0);

        }

        break;

#endif

    case 0x2c:

        switch (minor) {

        case SEB:

            gen_bshfl(ctx, OPC_SEB, rs, rt);

            break;

        case SEH:

            gen_bshfl(ctx, OPC_SEH, rs, rt);

            break;

        case CLO:

            mips32_op = OPC_CLO;

            goto do_cl;

        case CLZ:

            mips32_op = OPC_CLZ;

        do_cl:

            check_insn(ctx, ISA_MIPS32);

            gen_cl(ctx, mips32_op, rt, rs);

            break;

        case RDHWR:

            gen_rdhwr(ctx, rt, rs);

            break;

        case WSBH:

            gen_bshfl(ctx, OPC_WSBH, rs, rt);

            break;

        case MULT:

            mips32_op = OPC_MULT;

            goto do_mul;

        case MULTU:

            mips32_op = OPC_MULTU;

            goto do_mul;

        case DIV:

            mips32_op = OPC_DIV;

            goto do_div;

        case DIVU:

            mips32_op = OPC_DIVU;

            goto do_div;

        do_div:

            check_insn(ctx, ISA_MIPS32);

            gen_muldiv(ctx, mips32_op, 0, rs, rt);

            break;

        case MADD:

            mips32_op = OPC_MADD;

            goto do_mul;

        case MADDU:

            mips32_op = OPC_MADDU;

            goto do_mul;

        case MSUB:

            mips32_op = OPC_MSUB;

            goto do_mul;

        case MSUBU:

            mips32_op = OPC_MSUBU;

        do_mul:

            check_insn(ctx, ISA_MIPS32);

            gen_muldiv(ctx, mips32_op, (ctx->opcode >> 14) & 3, rs, rt);

            break;

        default:

            goto pool32axf_invalid;

        }

        break;

    case 0x34:

        switch (minor) {

        case MFC2:

        case MTC2:

        case MFHC2:

        case MTHC2:

        case CFC2:

        case CTC2:

            generate_exception_err(ctx, EXCP_CpU, 2);

            break;

        default:

            goto pool32axf_invalid;

        }

        break;

    case 0x3c:

        switch (minor) {

        case JALR:

        case JALR_HB:

            gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);

            *is_branch = 1;

            break;

        case JALRS:

        case JALRS_HB:

            gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);

            *is_branch = 1;

            break;

        default:

            goto pool32axf_invalid;

        }

        break;

    case 0x05:

        switch (minor) {

        case RDPGPR:

            check_cp0_enabled(ctx);

            check_insn(ctx, ISA_MIPS32R2);

            gen_load_srsgpr(rt, rs);

            break;

        case WRPGPR:

            check_cp0_enabled(ctx);

            check_insn(ctx, ISA_MIPS32R2);

            gen_store_srsgpr(rt, rs);

            break;

        default:

            goto pool32axf_invalid;

        }

        break;

#ifndef CONFIG_USER_ONLY

    case 0x0d:

        switch (minor) {

        case TLBP:

            mips32_op = OPC_TLBP;

            goto do_cp0;

        case TLBR:

            mips32_op = OPC_TLBR;

            goto do_cp0;

        case TLBWI:

            mips32_op = OPC_TLBWI;

            goto do_cp0;

        case TLBWR:

            mips32_op = OPC_TLBWR;

            goto do_cp0;

        case WAIT:

            mips32_op = OPC_WAIT;

            goto do_cp0;

        case DERET:

            mips32_op = OPC_DERET;

            goto do_cp0;

        case ERET:

            mips32_op = OPC_ERET;

        do_cp0:

            gen_cp0(env, ctx, mips32_op, rt, rs);

            break;

        default:

            goto pool32axf_invalid;

        }

        break;

    case 0x1d:

        switch (minor) {

        case DI:

            check_cp0_enabled(ctx);

            {

                TCGv t0 = tcg_temp_new();

                save_cpu_state(ctx, 1);

                gen_helper_di(t0, cpu_env);

                gen_store_gpr(t0, rs);

                /* Stop translation as we may have switched the execution mode */

                ctx->bstate = BS_STOP;

                tcg_temp_free(t0);

            }

            break;

        case EI:

            check_cp0_enabled(ctx);

            {

                TCGv t0 = tcg_temp_new();

                save_cpu_state(ctx, 1);

                gen_helper_ei(t0, cpu_env);

                gen_store_gpr(t0, rs);

                /* Stop translation as we may have switched the execution mode */

                ctx->bstate = BS_STOP;

                tcg_temp_free(t0);

            }

            break;

        default:

            goto pool32axf_invalid;

        }

        break;

#endif

    case 0x2d:

        switch (minor) {

        case SYNC:

            /* NOP */

            break;

        case SYSCALL:

            generate_exception(ctx, EXCP_SYSCALL);

            ctx->bstate = BS_STOP;

            break;

        case SDBBP:

            check_insn(ctx, ISA_MIPS32);

            if (!(ctx->hflags & MIPS_HFLAG_DM)) {

                generate_exception(ctx, EXCP_DBp);

            } else {

                generate_exception(ctx, EXCP_DBp);

            }

            break;

        default:

            goto pool32axf_invalid;

        }

        break;

    case 0x35:

        switch (minor & 3) {

        case MFHI32:

            gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);

            break;

        case MFLO32:

            gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);

            break;

        case MTHI32:

            gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);

            break;

        case MTLO32:

            gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);

            break;

        default:

            goto pool32axf_invalid;

        }

        break;

    default:

    pool32axf_invalid:

        MIPS_INVAL("pool32axf");

        generate_exception(ctx, EXCP_RI);

        break;

    }

}


static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)

{

    MpegTSWrite *ts = s->priv_data;

    uint8_t data[SECTION_LENGTH], *q, *desc_length_ptr, *program_info_length_ptr;

    int val, stream_type, i, err = 0;

    q = data;

    put16(&q, 0xe000 | service->pcr_pid);

    program_info_length_ptr = q;

    q += 2; /* patched after */

    /* put program info here */

    val = 0xf000 | (q - program_info_length_ptr - 2);

    program_info_length_ptr[0] = val >> 8;

    program_info_length_ptr[1] = val;

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

        AVStream *st = s->streams[i];

        MpegTSWriteStream *ts_st = st->priv_data;

        AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);

        if (q - data > SECTION_LENGTH - 32) {

            err = 1;

            break;

        }

        switch (st->codec->codec_id) {

        case AV_CODEC_ID_MPEG1VIDEO:

        case AV_CODEC_ID_MPEG2VIDEO:

            stream_type = STREAM_TYPE_VIDEO_MPEG2;

            break;

        case AV_CODEC_ID_MPEG4:

            stream_type = STREAM_TYPE_VIDEO_MPEG4;

            break;

        case AV_CODEC_ID_H264:

            stream_type = STREAM_TYPE_VIDEO_H264;

            break;

        case AV_CODEC_ID_HEVC:

            stream_type = STREAM_TYPE_VIDEO_HEVC;

            break;

        case AV_CODEC_ID_CAVS:

            stream_type = STREAM_TYPE_VIDEO_CAVS;

            break;

        case AV_CODEC_ID_DIRAC:

            stream_type = STREAM_TYPE_VIDEO_DIRAC;

            break;

        case AV_CODEC_ID_VC1:

            stream_type = STREAM_TYPE_VIDEO_VC1;

            break;

        case AV_CODEC_ID_MP2:

        case AV_CODEC_ID_MP3:

            stream_type = STREAM_TYPE_AUDIO_MPEG1;

            break;

        case AV_CODEC_ID_AAC:

            stream_type = (ts->flags & MPEGTS_FLAG_AAC_LATM)

                          ? STREAM_TYPE_AUDIO_AAC_LATM

                          : STREAM_TYPE_AUDIO_AAC;

            break;

        case AV_CODEC_ID_AAC_LATM:

            stream_type = STREAM_TYPE_AUDIO_AAC_LATM;

            break;

        case AV_CODEC_ID_AC3:

            stream_type = STREAM_TYPE_AUDIO_AC3;

            break;

        case AV_CODEC_ID_DTS:

            stream_type = STREAM_TYPE_AUDIO_DTS;

            break;

        case AV_CODEC_ID_TRUEHD:

            stream_type = STREAM_TYPE_AUDIO_TRUEHD;

            break;

        case AV_CODEC_ID_OPUS:

            stream_type = STREAM_TYPE_PRIVATE_DATA;

            break;

        default:

            stream_type = STREAM_TYPE_PRIVATE_DATA;

            break;

        }

        *q++ = stream_type;

        put16(&q, 0xe000 | ts_st->pid);

        desc_length_ptr = q;

        q += 2; /* patched after */

        /* write optional descriptors here */

        switch (st->codec->codec_type) {

        case AVMEDIA_TYPE_AUDIO:

            if (st->codec->codec_id==AV_CODEC_ID_EAC3) {

                *q++=0x7a; // EAC3 descriptor see A038 DVB SI

                *q++=1; // 1 byte, all flags sets to 0

                *q++=0; // omit all fields...

            }

            if (st->codec->codec_id==AV_CODEC_ID_S302M) {

                *q++ = 0x05; /* MPEG-2 registration descriptor*/

                *q++ = 4;

                *q++ = 'B';

                *q++ = 'S';

                *q++ = 'S';

                *q++ = 'D';

            }

            if (st->codec->codec_id==AV_CODEC_ID_OPUS) {

                /* 6 bytes registration descriptor, 4 bytes Opus audio descriptor */

                if (q - data > SECTION_LENGTH - 6 - 4) {

                    err = 1;

                    break;

                }

                *q++ = 0x05; /* MPEG-2 registration descriptor*/

                *q++ = 4;

                *q++ = 'O';

                *q++ = 'p';

                *q++ = 'u';

                *q++ = 's';

                *q++ = 0x7f; /* DVB extension descriptor */

                *q++ = 2;

                *q++ = 0x80;

                if (st->codec->extradata && st->codec->extradata_size >= 19) {

                    if (st->codec->extradata[18] == 0 && st->codec->channels <= 2) {

                        /* RTP mapping family */

                        *q++ = st->codec->channels;

                    } else if (st->codec->extradata[18] == 1 && st->codec->channels <= 8 &&

                               st->codec->extradata_size >= 21 + st->codec->channels) {

                        static const uint8_t coupled_stream_counts[9] = {

                            1, 0, 1, 1, 2, 2, 2, 3, 3

                        };

                        static const uint8_t channel_map_a[8][8] = {

                            {0},

                            {0, 1},

                            {0, 2, 1},

                            {0, 1, 2, 3},

                            {0, 4, 1, 2, 3},

                            {0, 4, 1, 2, 3, 5},

                            {0, 4, 1, 2, 3, 5, 6},

                            {0, 6, 1, 2, 3, 4, 5, 7},

                        };

                        static const uint8_t channel_map_b[8][8] = {

                            {0},

                            {0, 1},

                            {0, 1, 2},

                            {0, 1, 2, 3},

                            {0, 1, 2, 3, 4},

                            {0, 1, 2, 3, 4, 5},

                            {0, 1, 2, 3, 4, 5, 6},

                            {0, 1, 2, 3, 4, 5, 6, 7},

                        };

                        /* Vorbis mapping family */

                        if (st->codec->extradata[19] == st->codec->channels - coupled_stream_counts[st->codec->channels] &&

                            st->codec->extradata[20] == coupled_stream_counts[st->codec->channels] &&

                            memcmp(&st->codec->extradata[21], channel_map_a[st->codec->channels], st->codec->channels) == 0) {

                            *q++ = st->codec->channels;

                        } else if (st->codec->channels >= 2 && st->codec->extradata[19] == st->codec->channels &&

                                   st->codec->extradata[20] == 0 &&

                                   memcmp(&st->codec->extradata[21], channel_map_b[st->codec->channels], st->codec->channels) == 0) {

                            *q++ = st->codec->channels | 0x80;

                        } else {

                            /* Unsupported, could write an extended descriptor here */

                            av_log(s, AV_LOG_ERROR, "Unsupported Opus Vorbis-style channel mapping");

                            *q++ = 0xff;

                        }

                    } else {

                        /* Unsupported */

                        av_log(s, AV_LOG_ERROR, "Unsupported Opus channel mapping for family %d", st->codec->extradata[18]);

                        *q++ = 0xff;

                    }

                } else if (st->codec->channels <= 2) {

                    /* Assume RTP mapping family */

                    *q++ = st->codec->channels;

                } else {

                    /* Unsupported */

                    av_log(s, AV_LOG_ERROR, "Unsupported Opus channel mapping");

                    *q++ = 0xff;

                }

            }

            if (lang) {

                char *p;

                char *next = lang->value;

                uint8_t *len_ptr;

                *q++     = 0x0a; /* ISO 639 language descriptor */

                len_ptr  = q++;

                *len_ptr = 0;

                for (p = lang->value; next && *len_ptr < 255 / 4 * 4; p = next + 1) {

                    if (q - data > SECTION_LENGTH - 4) {

                        err = 1;

                        break;

                    }

                    next = strchr(p, ',');

                    if (strlen(p) != 3 && (!next || next != p + 3))

                        continue; /* not a 3-letter code */

                    *q++ = *p++;

                    *q++ = *p++;

                    *q++ = *p++;

                    if (st->disposition & AV_DISPOSITION_CLEAN_EFFECTS)

                        *q++ = 0x01;

                    else if (st->disposition & AV_DISPOSITION_HEARING_IMPAIRED)

                        *q++ = 0x02;

                    else if (st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)

                        *q++ = 0x03;

                    else

                        *q++ = 0; /* undefined type */

                    *len_ptr += 4;

                }

                if (*len_ptr == 0)

                    q -= 2; /* no language codes were written */

            }

            break;

        case AVMEDIA_TYPE_SUBTITLE:

        {

           const char default_language[] = "und";

           const char *language = lang && strlen(lang->value) >= 3 ? lang->value : default_language;

           if (st->codec->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {

               uint8_t *len_ptr;

               int extradata_copied = 0;

               *q++ = 0x59; /* subtitling_descriptor */

               len_ptr = q++;

               while (strlen(language) >= 3) {

                   if (sizeof(data) - (q - data) < 8) { /* 8 bytes per DVB subtitle substream data */

                       err = 1;

                       break;

                   }

                   *q++ = *language++;

                   *q++ = *language++;

                   *q++ = *language++;

                   /* Skip comma */

                   if (*language != '\0')

                       language++;

                   if (st->codec->extradata_size - extradata_copied >= 5) {

                       *q++ = st->codec->extradata[extradata_copied + 4]; /* subtitling_type */

                       memcpy(q, st->codec->extradata + extradata_copied, 4); /* composition_page_id and ancillary_page_id */

                       extradata_copied += 5;

                       q += 4;

                   } else {

                       /* subtitling_type:

                        * 0x10 - normal with no monitor aspect ratio criticality

                        * 0x20 - for the hard of hearing with no monitor aspect ratio criticality */

                       *q++ = (st->disposition & AV_DISPOSITION_HEARING_IMPAIRED) ? 0x20 : 0x10;

                       if ((st->codec->extradata_size == 4) && (extradata_copied == 0)) {

                           /* support of old 4-byte extradata format */

                           memcpy(q, st->codec->extradata, 4); /* composition_page_id and ancillary_page_id */

                           extradata_copied += 4;

                           q += 4;

                       } else {

                           put16(&q, 1); /* composition_page_id */

                           put16(&q, 1); /* ancillary_page_id */

                       }

                   }

               }

               *len_ptr = q - len_ptr - 1;

           } else if (st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) {

               uint8_t *len_ptr = NULL;

               int extradata_copied = 0;

               /* The descriptor tag. teletext_descriptor */

               *q++ = 0x56;

               len_ptr = q++;

               while (strlen(language) >= 3 && q - data < sizeof(data) - 6) {

                   *q++ = *language++;

                   *q++ = *language++;

                   *q++ = *language++;

                   /* Skip comma */

                   if (*language != '\0')

                       language++;

                   if (st->codec->extradata_size - 1 > extradata_copied) {

                       memcpy(q, st->codec->extradata + extradata_copied, 2);

                       extradata_copied += 2;

                       q += 2;

                   } else {

                       /* The Teletext descriptor:

                        * teletext_type: This 5-bit field indicates the type of Teletext page indicated. (0x01 Initial Teletext page)

                        * teletext_magazine_number: This is a 3-bit field which identifies the magazine number.

                        * teletext_page_number: This is an 8-bit field giving two 4-bit hex digits identifying the page number. */

                       *q++ = 0x08;

                       *q++ = 0x00;

                   }

               }

               *len_ptr = q - len_ptr - 1;

            }

        }

        break;

        case AVMEDIA_TYPE_VIDEO:

            if (stream_type == STREAM_TYPE_VIDEO_DIRAC) {

                *q++ = 0x05; /*MPEG-2 registration descriptor*/

                *q++ = 4;

                *q++ = 'd';

                *q++ = 'r';

                *q++ = 'a';

                *q++ = 'c';

            } else if (stream_type == STREAM_TYPE_VIDEO_VC1) {

                *q++ = 0x05; /*MPEG-2 registration descriptor*/

                *q++ = 4;

                *q++ = 'V';

                *q++ = 'C';

                *q++ = '-';

                *q++ = '1';

            }

            break;

        case AVMEDIA_TYPE_DATA:

            if (st->codec->codec_id == AV_CODEC_ID_SMPTE_KLV) {

                *q++ = 0x05; /* MPEG-2 registration descriptor */

                *q++ = 4;

                *q++ = 'K';

                *q++ = 'L';

                *q++ = 'V';

                *q++ = 'A';

            }

            break;

        }

        val = 0xf000 | (q - desc_length_ptr - 2);

        desc_length_ptr[0] = val >> 8;

        desc_length_ptr[1] = val;

    }

    if (err)

        av_log(s, AV_LOG_ERROR,

               "The PMT section cannot fit stream %d and all following streams.\n"

               "Try reducing the number of languages in the audio streams "

               "or the total number of streams.\n", i);

    mpegts_write_section1(&service->pmt, PMT_TID, service->sid, ts->tables_version, 0, 0,

                          data, q - data);

    return 0;

}


static void ahci_reset_port(AHCIState *s, int port)
{
    AHCIDevice *d = &s->dev[port];
    AHCIPortRegs *pr = &d->port_regs;
    IDEState *ide_state = &d->port.ifs[0];
    int i;
    DPRINTF(port, "reset port\n");
    ide_bus_reset(&d->port);
    ide_state->ncq_queues = AHCI_MAX_CMDS;
    pr->scr_stat = 0;
    pr->scr_err = 0;
    pr->scr_act = 0;
    d->busy_slot = -1;
    d->init_d2h_sent = 0;
    ide_state = &s->dev[port].port.ifs[0];
    if (!ide_state->bs) {
        return;
    /* reset ncq queue */
    for (i = 0; i < AHCI_MAX_CMDS; i++) {
        NCQTransferState *ncq_tfs = &s->dev[port].ncq_tfs[i];
        if (ncq_tfs->aiocb) {
            bdrv_aio_cancel(ncq_tfs->aiocb);
            ncq_tfs->aiocb = NULL;
        qemu_sglist_destroy(&ncq_tfs->sglist);
        ncq_tfs->used = 0;
    s->dev[port].port_state = STATE_RUN;
    if (!ide_state->bs) {
        s->dev[port].port_regs.sig = 0;
        ide_state->status = SEEK_STAT | WRERR_STAT;
    } else if (ide_state->drive_kind == IDE_CD) {
        s->dev[port].port_regs.sig = SATA_SIGNATURE_CDROM;
        ide_state->lcyl = 0x14;
        ide_state->hcyl = 0xeb;
        DPRINTF(port, "set lcyl = %d\n", ide_state->lcyl);
        ide_state->status = SEEK_STAT | WRERR_STAT | READY_STAT;
    } else {
        s->dev[port].port_regs.sig = SATA_SIGNATURE_DISK;
        ide_state->status = SEEK_STAT | WRERR_STAT;
    ide_state->error = 1;
    ahci_init_d2h(d);


int mjpeg_init(MpegEncContext *s)
{
    MJpegContext *m;
    m = malloc(sizeof(MJpegContext));
    if (!m)
        return -1;
    /* build all the huffman tables */
    build_huffman_codes(m->huff_size_dc_luminance,
                        m->huff_code_dc_luminance,
                        bits_dc_luminance,
                        val_dc_luminance);
    build_huffman_codes(m->huff_size_dc_chrominance,
                        m->huff_code_dc_chrominance,
                        bits_dc_chrominance,
                        val_dc_chrominance);
    build_huffman_codes(m->huff_size_ac_luminance,
                        m->huff_code_ac_luminance,
                        bits_ac_luminance,
                        val_ac_luminance);
    build_huffman_codes(m->huff_size_ac_chrominance,
                        m->huff_code_ac_chrominance,
                        bits_ac_chrominance,
                        val_ac_chrominance);
    s->mjpeg_ctx = m;
    return 0;
}


static void *bochs_bios_init(void)

{

    void *fw_cfg;

    uint8_t *smbios_table;

    size_t smbios_len;

    uint64_t *numa_fw_cfg;

    int i, j;

    fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0);

    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);

    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);

    fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES, (uint8_t *)acpi_tables,

                     acpi_tables_len);

    fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, kvm_allows_irq0_override());

    smbios_table = smbios_get_table(&smbios_len);

    if (smbios_table)

        fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,

                         smbios_table, smbios_len);

    fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE, (uint8_t *)&e820_table,

                     sizeof(e820_table));

    fw_cfg_add_bytes(fw_cfg, FW_CFG_HPET, (uint8_t *)&hpet_cfg,

                     sizeof(struct hpet_fw_config));

    /* allocate memory for the NUMA channel: one (64bit) word for the number

     * of nodes, one word for each VCPU->node and one word for each node to

     * hold the amount of memory.

     */

    numa_fw_cfg = g_new0(uint64_t, 1 + max_cpus + nb_numa_nodes);

    numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes);

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

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

            if (test_bit(i, node_cpumask[j])) {

                numa_fw_cfg[i + 1] = cpu_to_le64(j);

                break;

            }

        }

    }

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

        numa_fw_cfg[max_cpus + 1 + i] = cpu_to_le64(node_mem[i]);

    }

    fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, (uint8_t *)numa_fw_cfg,

                     (1 + max_cpus + nb_numa_nodes) * sizeof(*numa_fw_cfg));

    return fw_cfg;

}


static CharDriverState *gd_vc_handler(ChardevVC *vc, Error **errp)
{
    ChardevCommon *common = qapi_ChardevVC_base(vc);
    CharDriverState *chr;
    chr = qemu_chr_alloc(common, errp);
    if (!chr) {
    chr->chr_write = gd_vc_chr_write;
    chr->chr_set_echo = gd_vc_chr_set_echo;
    /* Temporary, until gd_vc_vte_init runs.  */
    chr->opaque = g_new0(VirtualConsole, 1);
    vcs[nb_vcs++] = chr;
    return chr;


int av_parse_color(uint8_t *rgba_color, const char *color_string, void *log_ctx)

{

    if (!strcasecmp(color_string, "random") || !strcasecmp(color_string, "bikeshed")) {

        int rgba = ff_random_get_seed();

        rgba_color[0] = rgba >> 24;

        rgba_color[1] = rgba >> 16;

        rgba_color[2] = rgba >> 8;

        rgba_color[3] = rgba;

    } else

    if (!strncmp(color_string, "0x", 2)) {

        char *tail;

        int len = strlen(color_string);

        int rgba = strtol(color_string, &tail, 16);

        if (*tail || (len != 8 && len != 10)) {

            av_log(log_ctx, AV_LOG_ERROR, "Invalid 0xRRGGBB[AA] color string: '%s'\n", color_string);

            return -1;

        }

        if (len == 10) {

            rgba_color[3] = rgba;

            rgba >>= 8;

        }

        rgba_color[0] = rgba >> 16;

        rgba_color[1] = rgba >> 8;

        rgba_color[2] = rgba;

    } else {

        const ColorEntry *entry = bsearch(color_string,

                                          color_table,

                                          FF_ARRAY_ELEMS(color_table),

                                          sizeof(ColorEntry),

                                          color_table_compare);

        if (!entry) {

            av_log(log_ctx, AV_LOG_ERROR, "Cannot find color '%s'\n", color_string);

            return -1;

        }

        memcpy(rgba_color, entry->rgba_color, 4);

    }

    return 0;

}


static av_cold int aac_encode_init(AVCodecContext *avctx)

{

    AACEncContext *s = avctx->priv_data;

    int i;

    const uint8_t *sizes[2];

    uint8_t grouping[AAC_MAX_CHANNELS];

    int lengths[2];

    avctx->frame_size = 1024;

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

        if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[i])

            break;

    if (i == 16) {

        av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d\n", avctx->sample_rate);

        return -1;

    }

    if (avctx->channels > AAC_MAX_CHANNELS) {

        av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %d\n", avctx->channels);

        return -1;

    }

    if (avctx->profile != FF_PROFILE_UNKNOWN && avctx->profile != FF_PROFILE_AAC_LOW) {

        av_log(avctx, AV_LOG_ERROR, "Unsupported profile %d\n", avctx->profile);

        return -1;

    }

    if (1024.0 * avctx->bit_rate / avctx->sample_rate > 6144 * avctx->channels) {

        av_log(avctx, AV_LOG_ERROR, "Too many bits per frame requested\n");

        return -1;

    }

    s->samplerate_index = i;

    dsputil_init(&s->dsp, avctx);

    ff_mdct_init(&s->mdct1024, 11, 0, 1.0);

    ff_mdct_init(&s->mdct128,   8, 0, 1.0);

    // window init

    ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);

    ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128);

    ff_init_ff_sine_windows(10);

    ff_init_ff_sine_windows(7);

    s->chan_map           = aac_chan_configs[avctx->channels-1];

    s->samples            = av_malloc(2 * 1024 * avctx->channels * sizeof(s->samples[0]));

    s->cpe                = av_mallocz(sizeof(ChannelElement) * s->chan_map[0]);

    avctx->extradata      = av_mallocz(5 + FF_INPUT_BUFFER_PADDING_SIZE);

    avctx->extradata_size = 5;

    put_audio_specific_config(avctx);

    sizes[0]   = swb_size_1024[i];

    sizes[1]   = swb_size_128[i];

    lengths[0] = ff_aac_num_swb_1024[i];

    lengths[1] = ff_aac_num_swb_128[i];

    for (i = 0; i < s->chan_map[0]; i++)

        grouping[i] = s->chan_map[i + 1] == TYPE_CPE;

    ff_psy_init(&s->psy, avctx, 2, sizes, lengths, s->chan_map[0], grouping);

    s->psypp = ff_psy_preprocess_init(avctx);

    s->coder = &ff_aac_coders[2];

    s->lambda = avctx->global_quality ? avctx->global_quality : 120;

    ff_aac_tableinit();

    return 0;

}


static int of_dpa_cmd_flow_add(OfDpa *of_dpa, uint64_t cookie,

                               RockerTlv **flow_tlvs)

{

    OfDpaFlow *flow = of_dpa_flow_find(of_dpa, cookie);

    int err = ROCKER_OK;

    if (flow) {

        return -ROCKER_EEXIST;

    }

    flow = of_dpa_flow_alloc(cookie);

    if (!flow) {

        return -ROCKER_ENOMEM;

    }

    err = of_dpa_cmd_flow_add_mod(of_dpa, flow, flow_tlvs);

    if (err) {

        g_free(flow);

        return err;

    }

    return of_dpa_flow_add(of_dpa, flow);

}


static int epaf_read_header(AVFormatContext *s)

{

    int le, sample_rate, codec, channels;

    AVStream *st;

    avio_skip(s->pb, 4);

    if (avio_rl32(s->pb))

        return AVERROR_INVALIDDATA;

    le = avio_rl32(s->pb);

    if (le && le != 1)

        return AVERROR_INVALIDDATA;

    if (le) {

        sample_rate = avio_rl32(s->pb);

        codec       = avio_rl32(s->pb);

        channels    = avio_rl32(s->pb);

    } else {

        sample_rate = avio_rb32(s->pb);

        codec       = avio_rb32(s->pb);

        channels    = avio_rb32(s->pb);

    }

    if (!channels || !sample_rate)

        return AVERROR_INVALIDDATA;

    st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;

    st->codecpar->channels    = channels;

    st->codecpar->sample_rate = sample_rate;

    switch (codec) {

    case 0:

        st->codecpar->codec_id = le ? AV_CODEC_ID_PCM_S16LE : AV_CODEC_ID_PCM_S16BE;

        break;

    case 2:

        st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;

        break;

    case 1:

        avpriv_request_sample(s, "24-bit Paris PCM format");

    default:

        return AVERROR_INVALIDDATA;

    }

    st->codecpar->bits_per_coded_sample = av_get_bits_per_sample(st->codecpar->codec_id);

    st->codecpar->block_align = st->codecpar->bits_per_coded_sample * st->codecpar->channels / 8;

    avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);

    if (avio_skip(s->pb, 2024) < 0)

        return AVERROR_INVALIDDATA;

    return 0;

}


static void audio_init (void)

{

    size_t i;

    int done = 0;

    const char *drvname;

    VMChangeStateEntry *e;

    AudioState *s = &glob_audio_state;

    if (s->drv) {

        return;

    }

    QLIST_INIT (&s->hw_head_out);

    QLIST_INIT (&s->hw_head_in);

    QLIST_INIT (&s->cap_head);

    atexit (audio_atexit);

    s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s);

    if (!s->ts) {

        hw_error("Could not create audio timer\n");

    }

    audio_process_options ("AUDIO", audio_options);

    s->nb_hw_voices_out = conf.fixed_out.nb_voices;

    s->nb_hw_voices_in = conf.fixed_in.nb_voices;

    if (s->nb_hw_voices_out <= 0) {

        dolog ("Bogus number of playback voices %d, setting to 1\n",

               s->nb_hw_voices_out);

        s->nb_hw_voices_out = 1;

    }

    if (s->nb_hw_voices_in <= 0) {

        dolog ("Bogus number of capture voices %d, setting to 0\n",

               s->nb_hw_voices_in);

        s->nb_hw_voices_in = 0;

    }

    {

        int def;

        drvname = audio_get_conf_str ("QEMU_AUDIO_DRV", NULL, &def);

    }

    if (drvname) {

        int found = 0;

        for (i = 0; i < ARRAY_SIZE (drvtab); i++) {

            if (!strcmp (drvname, drvtab[i]->name)) {

                done = !audio_driver_init (s, drvtab[i]);

                found = 1;

                break;

            }

        }

        if (!found) {

            dolog ("Unknown audio driver `%s'\n", drvname);

            dolog ("Run with -audio-help to list available drivers\n");

        }

    }

    if (!done) {

        for (i = 0; !done && i < ARRAY_SIZE (drvtab); i++) {

            if (drvtab[i]->can_be_default) {

                done = !audio_driver_init (s, drvtab[i]);

            }

        }

    }

    if (!done) {

        done = !audio_driver_init (s, &no_audio_driver);

        if (!done) {

            hw_error("Could not initialize audio subsystem\n");

        }

        else {

            dolog ("warning: Using timer based audio emulation\n");

        }

    }

    if (conf.period.hertz <= 0) {

        if (conf.period.hertz < 0) {

            dolog ("warning: Timer period is negative - %d "

                   "treating as zero\n",

                   conf.period.hertz);

        }

        conf.period.ticks = 1;

    } else {

        conf.period.ticks =

            muldiv64 (1, get_ticks_per_sec (), conf.period.hertz);

    }

    e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s);

    if (!e) {

        dolog ("warning: Could not register change state handler\n"

               "(Audio can continue looping even after stopping the VM)\n");

    }

    QLIST_INIT (&s->card_head);

    vmstate_register (NULL, 0, &vmstate_audio, s);

}


static void taihu_405ep_init(MachineState *machine)

{

    ram_addr_t ram_size = machine->ram_size;

    const char *kernel_filename = machine->kernel_filename;

    const char *initrd_filename = machine->initrd_filename;

    char *filename;

    qemu_irq *pic;

    MemoryRegion *sysmem = get_system_memory();

    MemoryRegion *bios;

    MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));

    hwaddr ram_bases[2], ram_sizes[2];

    long bios_size;

    target_ulong kernel_base, initrd_base;

    long kernel_size, initrd_size;

    int linux_boot;

    int fl_idx, fl_sectors;

    DriveInfo *dinfo;

    /* RAM is soldered to the board so the size cannot be changed */

    memory_region_allocate_system_memory(&ram_memories[0], NULL,

                           "taihu_405ep.ram-0", 0x04000000);

    ram_bases[0] = 0;

    ram_sizes[0] = 0x04000000;

    memory_region_allocate_system_memory(&ram_memories[1], NULL,

                           "taihu_405ep.ram-1", 0x04000000);

    ram_bases[1] = 0x04000000;

    ram_sizes[1] = 0x04000000;

    ram_size = 0x08000000;

#ifdef DEBUG_BOARD_INIT

    printf("%s: register cpu\n", __func__);

#endif

    ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes,

                  33333333, &pic, kernel_filename == NULL ? 0 : 1);

    /* allocate and load BIOS */

#ifdef DEBUG_BOARD_INIT

    printf("%s: register BIOS\n", __func__);

#endif

    fl_idx = 0;

#if defined(USE_FLASH_BIOS)

    dinfo = drive_get(IF_PFLASH, 0, fl_idx);

    if (dinfo) {

        bios_size = bdrv_getlength(dinfo->bdrv);

        /* XXX: should check that size is 2MB */

        //        bios_size = 2 * 1024 * 1024;

        fl_sectors = (bios_size + 65535) >> 16;

#ifdef DEBUG_BOARD_INIT

        printf("Register parallel flash %d size %lx"

               " at addr %lx '%s' %d\n",

               fl_idx, bios_size, -bios_size,

               bdrv_get_device_name(dinfo->bdrv), fl_sectors);

#endif

        pflash_cfi02_register((uint32_t)(-bios_size),

                              NULL, "taihu_405ep.bios", bios_size,

                              dinfo->bdrv, 65536, fl_sectors, 1,

                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,

                              1);

        fl_idx++;

    } else

#endif

    {

#ifdef DEBUG_BOARD_INIT

        printf("Load BIOS from file\n");

#endif

        if (bios_name == NULL)

            bios_name = BIOS_FILENAME;

        bios = g_new(MemoryRegion, 1);

        memory_region_allocate_system_memory(bios, NULL, "taihu_405ep.bios",

                                             BIOS_SIZE);

        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);

        if (filename) {

            bios_size = load_image(filename, memory_region_get_ram_ptr(bios));

            g_free(filename);

            if (bios_size < 0 || bios_size > BIOS_SIZE) {

                error_report("Could not load PowerPC BIOS '%s'", bios_name);

                exit(1);

            }

            bios_size = (bios_size + 0xfff) & ~0xfff;

            memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);

        } else if (!qtest_enabled()) {

            error_report("Could not load PowerPC BIOS '%s'", bios_name);

            exit(1);

        }

        memory_region_set_readonly(bios, true);

    }

    /* Register Linux flash */

    dinfo = drive_get(IF_PFLASH, 0, fl_idx);

    if (dinfo) {

        bios_size = bdrv_getlength(dinfo->bdrv);

        /* XXX: should check that size is 32MB */

        bios_size = 32 * 1024 * 1024;

        fl_sectors = (bios_size + 65535) >> 16;

#ifdef DEBUG_BOARD_INIT

        printf("Register parallel flash %d size %lx"

               " at addr " TARGET_FMT_lx " '%s'\n",

               fl_idx, bios_size, (target_ulong)0xfc000000,

               bdrv_get_device_name(dinfo->bdrv));

#endif

        pflash_cfi02_register(0xfc000000, NULL, "taihu_405ep.flash", bios_size,

                              dinfo->bdrv, 65536, fl_sectors, 1,

                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,

                              1);

        fl_idx++;

    }

    /* Register CLPD & LCD display */

#ifdef DEBUG_BOARD_INIT

    printf("%s: register CPLD\n", __func__);

#endif

    taihu_cpld_init(sysmem, 0x50100000);

    /* Load kernel */

    linux_boot = (kernel_filename != NULL);

    if (linux_boot) {

#ifdef DEBUG_BOARD_INIT

        printf("%s: load kernel\n", __func__);

#endif

        kernel_base = KERNEL_LOAD_ADDR;

        /* now we can load the kernel */

        kernel_size = load_image_targphys(kernel_filename, kernel_base,

                                          ram_size - kernel_base);

        if (kernel_size < 0) {

            fprintf(stderr, "qemu: could not load kernel '%s'\n",

                    kernel_filename);

            exit(1);

        }

        /* load initrd */

        if (initrd_filename) {

            initrd_base = INITRD_LOAD_ADDR;

            initrd_size = load_image_targphys(initrd_filename, initrd_base,

                                              ram_size - initrd_base);

            if (initrd_size < 0) {

                fprintf(stderr,

                        "qemu: could not load initial ram disk '%s'\n",

                        initrd_filename);

                exit(1);

            }

        } else {

            initrd_base = 0;

            initrd_size = 0;

        }

    } else {

        kernel_base = 0;

        kernel_size = 0;

        initrd_base = 0;

        initrd_size = 0;

    }

#ifdef DEBUG_BOARD_INIT

    printf("%s: Done\n", __func__);

#endif

}


static void qmp_input_type_any(Visitor *v, const char *name, QObject **obj,
                               Error **errp)
{
    QmpInputVisitor *qiv = to_qiv(v);
    QObject *qobj = qmp_input_get_object(qiv, name, true);
    qobject_incref(qobj);
    *obj = qobj;


PPC_OP(clear_xer_cr)

{

    xer_so = 0;

    xer_ov = 0;

    xer_ca = 0;

    RETURN();

}


static void flush_encoders(void)

{

    int i, ret;

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

        OutputStream   *ost = output_streams[i];

        AVCodecContext *enc = ost->enc_ctx;

        OutputFile      *of = output_files[ost->file_index];

        if (!ost->encoding_needed)

            continue;

        // Try to enable encoding with no input frames.

        // Maybe we should just let encoding fail instead.

        if (!ost->initialized) {

            FilterGraph *fg = ost->filter->graph;

            char error[1024];

            av_log(NULL, AV_LOG_WARNING,

                   "Finishing stream %d:%d without any data written to it.\n",

                   ost->file_index, ost->st->index);

            if (ost->filter && !fg->graph) {

                int x;

                for (x = 0; x < fg->nb_inputs; x++) {

                    InputFilter *ifilter = fg->inputs[x];

                    if (ifilter->format < 0) {

                        AVCodecParameters *par = ifilter->ist->st->codecpar;

                        // We never got any input. Set a fake format, which will

                        // come from libavformat.

                        ifilter->format                 = par->format;

                        ifilter->sample_rate            = par->sample_rate;

                        ifilter->channels               = par->channels;

                        ifilter->channel_layout         = par->channel_layout;

                        ifilter->width                  = par->width;

                        ifilter->height                 = par->height;

                        ifilter->sample_aspect_ratio    = par->sample_aspect_ratio;

                    }

                }

                if (!ifilter_has_all_input_formats(fg))

                    continue;

                ret = configure_filtergraph(fg);

                if (ret < 0) {

                    av_log(NULL, AV_LOG_ERROR, "Error configuring filter graph\n");

                    exit_program(1);

                }

                finish_output_stream(ost);

            }

            ret = init_output_stream(ost, error, sizeof(error));

            if (ret < 0) {

                av_log(NULL, AV_LOG_ERROR, "Error initializing output stream %d:%d -- %s\n",

                       ost->file_index, ost->index, error);

                exit_program(1);

            }

        }

        if (enc->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <= 1)

            continue;

#if FF_API_LAVF_FMT_RAWPICTURE

        if (enc->codec_type == AVMEDIA_TYPE_VIDEO && (of->ctx->oformat->flags & AVFMT_RAWPICTURE) && enc->codec->id == AV_CODEC_ID_RAWVIDEO)

            continue;

#endif

        if (enc->codec_type != AVMEDIA_TYPE_VIDEO && enc->codec_type != AVMEDIA_TYPE_AUDIO)

            continue;

        avcodec_send_frame(enc, NULL);

        for (;;) {

            const char *desc = NULL;

            AVPacket pkt;

            int pkt_size;

            switch (enc->codec_type) {

            case AVMEDIA_TYPE_AUDIO:

                desc   = "audio";

                break;

            case AVMEDIA_TYPE_VIDEO:

                desc   = "video";

                break;

            default:

                av_assert0(0);

            }

                av_init_packet(&pkt);

                pkt.data = NULL;

                pkt.size = 0;

                update_benchmark(NULL);

                ret = avcodec_receive_packet(enc, &pkt);

                update_benchmark("flush_%s %d.%d", desc, ost->file_index, ost->index);

                if (ret < 0 && ret != AVERROR_EOF) {

                    av_log(NULL, AV_LOG_FATAL, "%s encoding failed: %s\n",

                           desc,

                           av_err2str(ret));

                    exit_program(1);

                }

                if (ost->logfile && enc->stats_out) {

                    fprintf(ost->logfile, "%s", enc->stats_out);

                }

                if (ret == AVERROR_EOF) {

                    break;

                }

                if (ost->finished & MUXER_FINISHED) {

                    av_packet_unref(&pkt);

                    continue;

                }

                av_packet_rescale_ts(&pkt, enc->time_base, ost->mux_timebase);

                pkt_size = pkt.size;

                output_packet(of, &pkt, ost);

                if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO && vstats_filename) {

                    do_video_stats(ost, pkt_size);

                }

        }

    }

}


int fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value)

{

    uint32_t *copy;

    copy = g_malloc(sizeof(value));

    *copy = cpu_to_le32(value);

    return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));

}


static void use_normal_update_speed(WmallDecodeCtx *s, int ich)

{

    int ilms, recent, icoef;

    s->update_speed[ich] = 8;

    for (ilms = s->cdlms_ttl[ich]; ilms >= 0; ilms--) {

        recent = s->cdlms[ich][ilms].recent;

        if (s->bV3RTM) {

            for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)

                s->cdlms[ich][ilms].lms_updates[icoef + recent] /= 2;

        } else {

            for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)

                s->cdlms[ich][ilms].lms_updates[icoef] /= 2;

        }

    }

}


static int ram_save_target_page(RAMState *rs, PageSearchStatus *pss,

                                bool last_stage, ram_addr_t dirty_ram_abs)

{

    int res = 0;

    /* Check the pages is dirty and if it is send it */

    if (migration_bitmap_clear_dirty(rs, dirty_ram_abs)) {

        unsigned long *unsentmap;

        /*

         * If xbzrle is on, stop using the data compression after first

         * round of migration even if compression is enabled. In theory,

         * xbzrle can do better than compression.

         */

        if (migrate_use_compression()

            && (rs->ram_bulk_stage || !migrate_use_xbzrle())) {

            res = ram_save_compressed_page(rs, pss, last_stage);

        } else {

            res = ram_save_page(rs, pss, last_stage);

        }

        if (res < 0) {

            return res;

        }

        unsentmap = atomic_rcu_read(&rs->ram_bitmap)->unsentmap;

        if (unsentmap) {

            clear_bit(dirty_ram_abs >> TARGET_PAGE_BITS, unsentmap);

        }

    }

    return res;

}


static int vmdk_parent_open(BlockDriverState *bs, const char * filename)

{

    BDRVVmdkState *s = bs->opaque;

    char *p_name;

    char desc[DESC_SIZE];

    char parent_img_name[1024];

    /* the descriptor offset = 0x200 */

    if (bdrv_pread(s->hd, 0x200, desc, DESC_SIZE) != DESC_SIZE)

        return -1;

    if ((p_name = strstr(desc,"parentFileNameHint")) != 0) {

        char *end_name;

        struct stat file_buf;

        p_name += sizeof("parentFileNameHint") + 1;

        if ((end_name = strchr(p_name,'\"')) == 0)

            return -1;

        strncpy(s->hd->backing_file, p_name, end_name - p_name);

        if (stat(s->hd->backing_file, &file_buf) != 0) {

            path_combine(parent_img_name, sizeof(parent_img_name),

                         filename, s->hd->backing_file);

        } else {

            strcpy(parent_img_name, s->hd->backing_file);

        }

        s->hd->backing_hd = bdrv_new("");

        if (!s->hd->backing_hd) {

            failure:

            bdrv_close(s->hd);

            return -1;

        }

        if (bdrv_open(s->hd->backing_hd, parent_img_name, 0) < 0)

            goto failure;

    }

    return 0;

}


static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)

{

    Error *local_err = NULL;

    BDRVSheepdogState *s = bs->opaque;

    SheepdogReq req;

    int fd, nr = 1024, ret, max = BITS_TO_LONGS(SD_NR_VDIS) * sizeof(long);

    QEMUSnapshotInfo *sn_tab = NULL;

    unsigned wlen, rlen;

    int found = 0;

    static SheepdogInode inode;

    unsigned long *vdi_inuse;

    unsigned int start_nr;

    uint64_t hval;

    uint32_t vid;

    vdi_inuse = g_malloc(max);

    fd = connect_to_sdog(s, &local_err);

    if (fd < 0) {

        error_report("%s", error_get_pretty(local_err));;

        error_free(local_err);

        ret = fd;

        goto out;

    }

    rlen = max;

    wlen = 0;

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

    req.opcode = SD_OP_READ_VDIS;

    req.data_length = max;

    ret = do_req(fd, s->aio_context, (SheepdogReq *)&req,

                 vdi_inuse, &wlen, &rlen);

    closesocket(fd);

    if (ret) {

        goto out;

    }

    sn_tab = g_malloc0(nr * sizeof(*sn_tab));

    /* calculate a vdi id with hash function */

    hval = fnv_64a_buf(s->name, strlen(s->name), FNV1A_64_INIT);

    start_nr = hval & (SD_NR_VDIS - 1);

    fd = connect_to_sdog(s, &local_err);

    if (fd < 0) {

        error_report("%s", error_get_pretty(local_err));;

        error_free(local_err);

        ret = fd;

        goto out;

    }

    for (vid = start_nr; found < nr; vid = (vid + 1) % SD_NR_VDIS) {

        if (!test_bit(vid, vdi_inuse)) {

            break;

        }

        /* we don't need to read entire object */

        ret = read_object(fd, s->aio_context, (char *)&inode,

                          vid_to_vdi_oid(vid),

                          0, SD_INODE_SIZE - sizeof(inode.data_vdi_id), 0,

                          s->cache_flags);

        if (ret) {

            continue;

        }

        if (!strcmp(inode.name, s->name) && is_snapshot(&inode)) {

            sn_tab[found].date_sec = inode.snap_ctime >> 32;

            sn_tab[found].date_nsec = inode.snap_ctime & 0xffffffff;

            sn_tab[found].vm_state_size = inode.vm_state_size;

            sn_tab[found].vm_clock_nsec = inode.vm_clock_nsec;

            snprintf(sn_tab[found].id_str, sizeof(sn_tab[found].id_str),

                     "%" PRIu32, inode.snap_id);

            pstrcpy(sn_tab[found].name,

                    MIN(sizeof(sn_tab[found].name), sizeof(inode.tag)),

                    inode.tag);

            found++;

        }

    }

    closesocket(fd);

out:

    *psn_tab = sn_tab;

    g_free(vdi_inuse);

    if (ret < 0) {

        return ret;

    }

    return found;

}


static void config_parse(GAConfig *config, int argc, char **argv)

{

    const char *sopt = "hVvdm:p:l:f:F::b:s:t:D";

    int opt_ind = 0, ch;

    const struct option lopt[] = {

        { "help", 0, NULL, 'h' },

        { "version", 0, NULL, 'V' },

        { "dump-conf", 0, NULL, 'D' },

        { "logfile", 1, NULL, 'l' },

        { "pidfile", 1, NULL, 'f' },

#ifdef CONFIG_FSFREEZE

        { "fsfreeze-hook", 2, NULL, 'F' },

#endif

        { "verbose", 0, NULL, 'v' },

        { "method", 1, NULL, 'm' },

        { "path", 1, NULL, 'p' },

        { "daemonize", 0, NULL, 'd' },

        { "blacklist", 1, NULL, 'b' },

#ifdef _WIN32

        { "service", 1, NULL, 's' },

#endif

        { "statedir", 1, NULL, 't' },

        { NULL, 0, NULL, 0 }

    };

    config->log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL;

    while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {

        switch (ch) {

        case 'm':

            g_free(config->method);

            config->method = g_strdup(optarg);

            break;

        case 'p':

            g_free(config->channel_path);

            config->channel_path = g_strdup(optarg);

            break;

        case 'l':

            g_free(config->log_filepath);

            config->log_filepath = g_strdup(optarg);

            break;

        case 'f':

            g_free(config->pid_filepath);

            config->pid_filepath = g_strdup(optarg);

            break;

#ifdef CONFIG_FSFREEZE

        case 'F':

            g_free(config->fsfreeze_hook);

            config->fsfreeze_hook = g_strdup(optarg ?: QGA_FSFREEZE_HOOK_DEFAULT);

            break;

#endif

        case 't':

            g_free(config->state_dir);

            config->state_dir = g_strdup(optarg);

            break;

        case 'v':

            /* enable all log levels */

            config->log_level = G_LOG_LEVEL_MASK;

            break;

        case 'V':

            printf("QEMU Guest Agent %s\n", QEMU_VERSION);

            exit(EXIT_SUCCESS);

        case 'd':

            config->daemonize = 1;

            break;

        case 'D':

            config->dumpconf = 1;

            break;

        case 'b': {

            if (is_help_option(optarg)) {

                qmp_for_each_command(ga_print_cmd, NULL);

                exit(EXIT_SUCCESS);

            }

            config->blacklist = g_list_concat(config->blacklist,

                                             split_list(optarg, ","));

            break;

        }

#ifdef _WIN32

        case 's':

            config->service = optarg;

            if (strcmp(config->service, "install") == 0) {

                if (ga_install_vss_provider()) {

                    exit(EXIT_FAILURE);

                }

                if (ga_install_service(config->channel_path,

                                       config->log_filepath, config->state_dir)) {

                    exit(EXIT_FAILURE);

                }

                exit(EXIT_SUCCESS);

            } else if (strcmp(config->service, "uninstall") == 0) {

                ga_uninstall_vss_provider();

                exit(ga_uninstall_service());

            } else if (strcmp(config->service, "vss-install") == 0) {

                if (ga_install_vss_provider()) {

                    exit(EXIT_FAILURE);

                }

                exit(EXIT_SUCCESS);

            } else if (strcmp(config->service, "vss-uninstall") == 0) {

                ga_uninstall_vss_provider();

                exit(EXIT_SUCCESS);

            } else {

                printf("Unknown service command.\n");

                exit(EXIT_FAILURE);

            }

            break;

#endif

        case 'h':

            usage(argv[0]);

            exit(EXIT_SUCCESS);

        case '?':

            g_print("Unknown option, try '%s --help' for more information.\n",

                    argv[0]);

            exit(EXIT_FAILURE);

        }

    }

}


static void gen_abs(DisasContext *ctx)

{

    int l1 = gen_new_label();

    int l2 = gen_new_label();

    tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);

    tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);

    tcg_gen_br(l2);

    gen_set_label(l1);

    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);

    gen_set_label(l2);

    if (unlikely(Rc(ctx->opcode) != 0))

        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);

}


static void ga_channel_client_close(GAChannel *c)

{

    g_assert(c->client_channel);

    g_io_channel_shutdown(c->client_channel, true, NULL);

    g_io_channel_unref(c->client_channel);

    c->client_channel = NULL;

    if (c->method == GA_CHANNEL_UNIX_LISTEN && c->listen_channel) {

        ga_channel_listen_add(c, 0, false);

    }

}


static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,

                target_phys_addr_t addr)

{

    return range_covers_byte(0xfffb0000, 0xffff0000 - 0xfffb0000, addr);

}


static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)

{

    int v, i;

    if (n <= 0) {

        *pnum = 0;

        return 0;

    }

    v = is_not_zero(buf, 512);

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

        buf += 512;

        if (v != is_not_zero(buf, 512))

            break;

    }

    *pnum = i;

    return v;

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);

    k->init = s390_virtio_blk_init;

    dc->props = s390_virtio_blk_properties;

    dc->alias = "virtio-blk";

}


void do_info_vnc(Monitor *mon, QObject **ret_data)

{

    if (vnc_display == NULL || vnc_display->display == NULL) {

        *ret_data = qobject_from_jsonf("{ 'enabled': false }");

    } else {

        QDict *qdict;

        QList *clist;

        clist = qlist_new();

        if (vnc_display->clients) {

            VncState *client = vnc_display->clients;

            while (client) {

                qdict = do_info_vnc_client(mon, client);

                if (qdict)

                    qlist_append(clist, qdict);

                client = client->next;

            }

        }

        *ret_data = qobject_from_jsonf("{ 'enabled': true, 'clients': %p }",

                                       QOBJECT(clist));

        assert(*ret_data != NULL);

        if (vnc_server_info_put(qobject_to_qdict(*ret_data)) < 0) {

            qobject_decref(*ret_data);

            *ret_data = NULL;

        }

    }

}


static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)

{

    target_phys_addr_t addr;

    ram_addr_t ram_addr;

    MemoryRegionSection *section;

    addr = cpu_get_phys_page_debug(env, pc);

    section = phys_page_find(addr >> TARGET_PAGE_BITS);

    if (!(memory_region_is_ram(section->mr)

          || (section->mr->rom_device && section->mr->readable))) {

        return;

    }

    ram_addr = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)

        + section_addr(section, addr);

    tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);

}


static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp)

{

    CharDriverState *chr;

    const char *chardev;

    const char *mode;

    int flags;

    mode = qemu_opt_get(opts, "mode");

    if (mode == NULL) {

        mode = "readline";

    }

    if (strcmp(mode, "readline") == 0) {

        flags = MONITOR_USE_READLINE;

    } else if (strcmp(mode, "control") == 0) {

        flags = MONITOR_USE_CONTROL;

    } else {

        fprintf(stderr, "unknown monitor mode \"%s\"\n", mode);

        exit(1);

    }

    if (qemu_opt_get_bool(opts, "pretty", 0))

        flags |= MONITOR_USE_PRETTY;

    if (qemu_opt_get_bool(opts, "default", 0))

        flags |= MONITOR_IS_DEFAULT;

    chardev = qemu_opt_get(opts, "chardev");

    chr = qemu_chr_find(chardev);

    if (chr == NULL) {

        fprintf(stderr, "chardev \"%s\" not found\n", chardev);

        exit(1);

    }

    qemu_chr_fe_claim_no_fail(chr);

    monitor_init(chr, flags);

    return 0;

}


static void show_parts(const char *device)

{

    if (fork() == 0) {

        int nbd;

        /* linux just needs an open() to trigger

         * the partition table update

         * but remember to load the module with max_part != 0 :

         *     modprobe nbd max_part=63

         */

        nbd = open(device, O_RDWR);

        if (nbd != -1)

              close(nbd);

        exit(0);

    }

}


static void isa_mmio_writel(void *opaque, target_phys_addr_t addr,

                               uint32_t val)

{

    cpu_outl(addr & IOPORTS_MASK, val);

}


static inline void t_gen_subx_carry(DisasContext *dc, TCGv d)

{

	if (dc->flagx_known) {

		if (dc->flags_x) {

			TCGv c;

			c = tcg_temp_new(TCG_TYPE_TL);

			t_gen_mov_TN_preg(c, PR_CCS);

			/* C flag is already at bit 0.  */

			tcg_gen_andi_tl(c, c, C_FLAG);

			tcg_gen_sub_tl(d, d, c);

			tcg_temp_free(c);

		}

	} else {

		TCGv x, c;

		x = tcg_temp_new(TCG_TYPE_TL);

		c = tcg_temp_new(TCG_TYPE_TL);

		t_gen_mov_TN_preg(x, PR_CCS);

		tcg_gen_mov_tl(c, x);

		/* Propagate carry into d if X is set. Branch free.  */

		tcg_gen_andi_tl(c, c, C_FLAG);

		tcg_gen_andi_tl(x, x, X_FLAG);

		tcg_gen_shri_tl(x, x, 4);

		tcg_gen_and_tl(x, x, c);

		tcg_gen_sub_tl(d, d, x);

		tcg_temp_free(x);

		tcg_temp_free(c);

	}

}


SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags,

                         SwsFilter *srcFilter, SwsFilter *dstFilter){

	SwsContext *c;

	int i;

	SwsFilter dummyFilter= {NULL, NULL, NULL, NULL};

#ifdef ARCH_X86

	if(gCpuCaps.hasMMX)

		asm volatile("emms\n\t"::: "memory");

#endif

	if(swScale==NULL) globalInit();

	/* sanity check */

	if(srcW<4 || srcH<1 || dstW<8 || dstH<1) return NULL; //FIXME check if these are enough and try to lowwer them after fixing the relevant parts of the code

//	if(!isSupportedIn(srcFormat)) return NULL;

//	if(!isSupportedOut(dstFormat)) return NULL;

	if(!dstFilter) dstFilter= &dummyFilter;

	if(!srcFilter) srcFilter= &dummyFilter;

	c= memalign(64, sizeof(SwsContext));

	memset(c, 0, sizeof(SwsContext));

	c->srcW= srcW;

	c->srcH= srcH;

	c->dstW= dstW;

	c->dstH= dstH;

	c->lumXInc= ((srcW<<16) + (dstW>>1))/dstW;

	c->lumYInc= ((srcH<<16) + (dstH>>1))/dstH;

	c->flags= flags;

	c->dstFormat= dstFormat;

	c->srcFormat= srcFormat;

	if(cpuCaps.hasMMX2)

	{

		c->canMMX2BeUsed= (dstW >=srcW && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0;

		if(!c->canMMX2BeUsed && dstW >=srcW && (srcW&15)==0 && (flags&SWS_FAST_BILINEAR))

		{

			if(flags&SWS_PRINT_INFO)

				fprintf(stderr, "SwScaler: output Width is not a multiple of 32 -> no MMX2 scaler\n");

		}

	}

	else

		c->canMMX2BeUsed=0;

	/* dont use full vertical UV input/internaly if the source doesnt even have it */

	if(isHalfChrV(srcFormat)) c->flags= flags= flags&(~SWS_FULL_CHR_V);

	/* dont use full horizontal UV input if the source doesnt even have it */

	if(isHalfChrH(srcFormat)) c->flags= flags= flags&(~SWS_FULL_CHR_H_INP);

	/* dont use full horizontal UV internally if the destination doesnt even have it */

	if(isHalfChrH(dstFormat)) c->flags= flags= flags&(~SWS_FULL_CHR_H_INT);

	if(flags&SWS_FULL_CHR_H_INP)	c->chrSrcW= srcW;

	else				c->chrSrcW= (srcW+1)>>1;

	if(flags&SWS_FULL_CHR_H_INT)	c->chrDstW= dstW;

	else				c->chrDstW= (dstW+1)>>1;

	if(flags&SWS_FULL_CHR_V)	c->chrSrcH= srcH;

	else				c->chrSrcH= (srcH+1)>>1;

	if(isHalfChrV(dstFormat))	c->chrDstH= (dstH+1)>>1;

	else				c->chrDstH= dstH;

	c->chrXInc= ((c->chrSrcW<<16) + (c->chrDstW>>1))/c->chrDstW;

	c->chrYInc= ((c->chrSrcH<<16) + (c->chrDstH>>1))/c->chrDstH;

	// match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src to pixel n-2 of dst

	// but only for the FAST_BILINEAR mode otherwise do correct scaling

	// n-2 is the last chrominance sample available

	// this is not perfect, but noone shuld notice the difference, the more correct variant

	// would be like the vertical one, but that would require some special code for the

	// first and last pixel

	if(flags&SWS_FAST_BILINEAR)

	{

		if(c->canMMX2BeUsed)

		{

			c->lumXInc+= 20;

			c->chrXInc+= 20;

		}

		//we dont use the x86asm scaler if mmx is available

		else if(cpuCaps.hasMMX)

		{

			c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20;

			c->chrXInc = ((c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20;

		}

	}

	/* precalculate horizontal scaler filter coefficients */

	{

		const int filterAlign= cpuCaps.hasMMX ? 4 : 1;

		initFilter(&c->hLumFilter, &c->hLumFilterPos, &c->hLumFilterSize, c->lumXInc,

				 srcW      ,       dstW, filterAlign, 1<<14, flags,

				 srcFilter->lumH, dstFilter->lumH);

		initFilter(&c->hChrFilter, &c->hChrFilterPos, &c->hChrFilterSize, c->chrXInc,

				(srcW+1)>>1, c->chrDstW, filterAlign, 1<<14, flags,

				 srcFilter->chrH, dstFilter->chrH);

#ifdef ARCH_X86

// cant downscale !!!

		if(c->canMMX2BeUsed && (flags & SWS_FAST_BILINEAR))

		{

			initMMX2HScaler(      dstW, c->lumXInc, c->funnyYCode);

			initMMX2HScaler(c->chrDstW, c->chrXInc, c->funnyUVCode);

		}

#endif

	} // Init Horizontal stuff

	/* precalculate vertical scaler filter coefficients */

	initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize, c->lumYInc,

			srcH      ,        dstH, 1, (1<<12)-4, flags,

			srcFilter->lumV, dstFilter->lumV);

	initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize, c->chrYInc,

			(srcH+1)>>1, c->chrDstH, 1, (1<<12)-4, flags,

			 srcFilter->chrV, dstFilter->chrV);

	// Calculate Buffer Sizes so that they wont run out while handling these damn slices

	c->vLumBufSize= c->vLumFilterSize;

	c->vChrBufSize= c->vChrFilterSize;

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

	{

		int chrI= i*c->chrDstH / dstH;

		int nextSlice= MAX(c->vLumFilterPos[i   ] + c->vLumFilterSize - 1,

				 ((c->vChrFilterPos[chrI] + c->vChrFilterSize - 1)<<1));

		nextSlice&= ~1; // Slices start at even boundaries

		if(c->vLumFilterPos[i   ] + c->vLumBufSize < nextSlice)

			c->vLumBufSize= nextSlice - c->vLumFilterPos[i   ];

		if(c->vChrFilterPos[chrI] + c->vChrBufSize < (nextSlice>>1))

			c->vChrBufSize= (nextSlice>>1) - c->vChrFilterPos[chrI];

	}

	// allocate pixbufs (we use dynamic allocation because otherwise we would need to

	c->lumPixBuf= (int16_t**)memalign(4, c->vLumBufSize*2*sizeof(int16_t*));

	c->chrPixBuf= (int16_t**)memalign(4, c->vChrBufSize*2*sizeof(int16_t*));

	//Note we need at least one pixel more at the end because of the mmx code (just in case someone wanna replace the 4000/8000)

	for(i=0; i<c->vLumBufSize; i++)

		c->lumPixBuf[i]= c->lumPixBuf[i+c->vLumBufSize]= (uint16_t*)memalign(8, 4000);

	for(i=0; i<c->vChrBufSize; i++)

		c->chrPixBuf[i]= c->chrPixBuf[i+c->vChrBufSize]= (uint16_t*)memalign(8, 8000);

	//try to avoid drawing green stuff between the right end and the stride end

	for(i=0; i<c->vLumBufSize; i++) memset(c->lumPixBuf[i], 0, 4000);

	for(i=0; i<c->vChrBufSize; i++) memset(c->chrPixBuf[i], 64, 8000);

	ASSERT(c->chrDstH <= dstH)

	// pack filter data for mmx code

	if(cpuCaps.hasMMX)

	{

		c->lumMmxFilter= (int16_t*)memalign(8, c->vLumFilterSize*      dstH*4*sizeof(int16_t));

		c->chrMmxFilter= (int16_t*)memalign(8, c->vChrFilterSize*c->chrDstH*4*sizeof(int16_t));

		for(i=0; i<c->vLumFilterSize*dstH; i++)

			c->lumMmxFilter[4*i]=c->lumMmxFilter[4*i+1]=c->lumMmxFilter[4*i+2]=c->lumMmxFilter[4*i+3]=

				c->vLumFilter[i];

		for(i=0; i<c->vChrFilterSize*c->chrDstH; i++)

			c->chrMmxFilter[4*i]=c->chrMmxFilter[4*i+1]=c->chrMmxFilter[4*i+2]=c->chrMmxFilter[4*i+3]=

				c->vChrFilter[i];

	}

	if(flags&SWS_PRINT_INFO)

	{

#ifdef DITHER1XBPP

		char *dither= " dithered";

#else

		char *dither= "";

#endif

		if(flags&SWS_FAST_BILINEAR)

			fprintf(stderr, "\nSwScaler: FAST_BILINEAR scaler, ");

		else if(flags&SWS_BILINEAR)

			fprintf(stderr, "\nSwScaler: BILINEAR scaler, ");

		else if(flags&SWS_BICUBIC)

			fprintf(stderr, "\nSwScaler: BICUBIC scaler, ");

		else if(flags&SWS_X)

			fprintf(stderr, "\nSwScaler: Experimental scaler, ");

		else if(flags&SWS_POINT)

			fprintf(stderr, "\nSwScaler: Nearest Neighbor / POINT scaler, ");

		else if(flags&SWS_AREA)

			fprintf(stderr, "\nSwScaler: Area Averageing scaler, ");

		else

			fprintf(stderr, "\nSwScaler: ehh flags invalid?! ");

		if(dstFormat==IMGFMT_BGR15 || dstFormat==IMGFMT_BGR16)

			fprintf(stderr, "from %s to%s %s ",

				vo_format_name(srcFormat), dither, vo_format_name(dstFormat));

		else

			fprintf(stderr, "from %s to %s ",

				vo_format_name(srcFormat), vo_format_name(dstFormat));

		if(cpuCaps.hasMMX2)

			fprintf(stderr, "using MMX2\n");

		else if(cpuCaps.has3DNow)

			fprintf(stderr, "using 3DNOW\n");

		else if(cpuCaps.hasMMX)

			fprintf(stderr, "using MMX\n");

		else

			fprintf(stderr, "using C\n");

	}

	if((flags & SWS_PRINT_INFO) && verbose)

	{

		if(cpuCaps.hasMMX)

		{

			if(c->canMMX2BeUsed && (flags&SWS_FAST_BILINEAR))

				printf("SwScaler: using FAST_BILINEAR MMX2 scaler for horizontal scaling\n");

			else

			{

				if(c->hLumFilterSize==4)

					printf("SwScaler: using 4-tap MMX scaler for horizontal luminance scaling\n");

				else if(c->hLumFilterSize==8)

					printf("SwScaler: using 8-tap MMX scaler for horizontal luminance scaling\n");

				else

					printf("SwScaler: using n-tap MMX scaler for horizontal luminance scaling\n");

				if(c->hChrFilterSize==4)

					printf("SwScaler: using 4-tap MMX scaler for horizontal chrominance scaling\n");

				else if(c->hChrFilterSize==8)

					printf("SwScaler: using 8-tap MMX scaler for horizontal chrominance scaling\n");

				else

					printf("SwScaler: using n-tap MMX scaler for horizontal chrominance scaling\n");

			}

		}

		else

		{

#ifdef ARCH_X86

			printf("SwScaler: using X86-Asm scaler for horizontal scaling\n");

#else

			if(flags & SWS_FAST_BILINEAR)

				printf("SwScaler: using FAST_BILINEAR C scaler for horizontal scaling\n");

			else

				printf("SwScaler: using C scaler for horizontal scaling\n");

#endif

		}

		if(isPlanarYUV(dstFormat))

		{

			if(c->vLumFilterSize==1)

				printf("SwScaler: using 1-tap %s \"scaler\" for vertical scaling (YV12 like)\n", cpuCaps.hasMMX ? "MMX" : "C");

			else

				printf("SwScaler: using n-tap %s scaler for vertical scaling (YV12 like)\n", cpuCaps.hasMMX ? "MMX" : "C");

		}

		else

		{

			if(c->vLumFilterSize==1 && c->vChrFilterSize==2)

				printf("SwScaler: using 1-tap %s \"scaler\" for vertical luminance scaling (BGR)\n"

				       "SwScaler:       2-tap scaler for vertical chrominance scaling (BGR)\n",cpuCaps.hasMMX ? "MMX" : "C");

			else if(c->vLumFilterSize==2 && c->vChrFilterSize==2)

				printf("SwScaler: using 2-tap linear %s scaler for vertical scaling (BGR)\n", cpuCaps.hasMMX ? "MMX" : "C");

			else

				printf("SwScaler: using n-tap %s scaler for vertical scaling (BGR)\n", cpuCaps.hasMMX ? "MMX" : "C");

		}

		if(dstFormat==IMGFMT_BGR24)

			printf("SwScaler: using %s YV12->BGR24 Converter\n",

				cpuCaps.hasMMX2 ? "MMX2" : (cpuCaps.hasMMX ? "MMX" : "C"));

		else if(dstFormat==IMGFMT_BGR32)

			printf("SwScaler: using %s YV12->BGR32 Converter\n", cpuCaps.hasMMX ? "MMX" : "C");

		else if(dstFormat==IMGFMT_BGR16)

			printf("SwScaler: using %s YV12->BGR16 Converter\n", cpuCaps.hasMMX ? "MMX" : "C");

		else if(dstFormat==IMGFMT_BGR15)

			printf("SwScaler: using %s YV12->BGR15 Converter\n", cpuCaps.hasMMX ? "MMX" : "C");

		printf("SwScaler: %dx%d -> %dx%d\n", srcW, srcH, dstW, dstH);

	}

	if((flags & SWS_PRINT_INFO) && verbose>1)

	{

		printf("SwScaler:Lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",

			c->srcW, c->srcH, c->dstW, c->dstH, c->lumXInc, c->lumYInc);

		printf("SwScaler:Chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",

			c->chrSrcW, c->chrSrcH, c->chrDstW, c->chrDstH, c->chrXInc, c->chrYInc);

	}

	return c;

}


struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size,

                DisplayState *ds, const char *revision)

{

    struct pxa2xx_state_s *s;

    struct pxa2xx_ssp_s *ssp;

    int iomemtype, i;

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

    if (revision && strncmp(revision, "pxa27", 5)) {

        fprintf(stderr, "Machine requires a PXA27x processor.\n");

        exit(1);

    }

    s->env = cpu_init();

    cpu_arm_set_model(s->env, revision ?: "pxa270");

    register_savevm("cpu", 0, 0, cpu_save, cpu_load, s->env);

    /* SDRAM & Internal Memory Storage */

    cpu_register_physical_memory(PXA2XX_SDRAM_BASE,

                    sdram_size, qemu_ram_alloc(sdram_size) | IO_MEM_RAM);

    cpu_register_physical_memory(PXA2XX_INTERNAL_BASE,

                    0x40000, qemu_ram_alloc(0x40000) | IO_MEM_RAM);

    s->pic = pxa2xx_pic_init(0x40d00000, s->env);

    s->dma = pxa27x_dma_init(0x40000000, s->pic[PXA2XX_PIC_DMA]);

    pxa27x_timer_init(0x40a00000, &s->pic[PXA2XX_PIC_OST_0],

                    s->pic[PXA27X_PIC_OST_4_11]);

    s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 121);

    s->mmc = pxa2xx_mmci_init(0x41100000, s->pic[PXA2XX_PIC_MMC], s->dma);

    for (i = 0; pxa270_serial[i].io_base; i ++)

        if (serial_hds[i])

            serial_mm_init(pxa270_serial[i].io_base, 2,

                            s->pic[pxa270_serial[i].irqn], serial_hds[i], 1);

        else

            break;

    if (serial_hds[i])

        s->fir = pxa2xx_fir_init(0x40800000, s->pic[PXA2XX_PIC_ICP],

                        s->dma, serial_hds[i]);

    if (ds)

        s->lcd = pxa2xx_lcdc_init(0x44000000, s->pic[PXA2XX_PIC_LCD], ds);

    s->cm_base = 0x41300000;

    s->cm_regs[CCCR >> 4] = 0x02000210;	/* 416.0 MHz */

    s->clkcfg = 0x00000009;		/* Turbo mode active */

    iomemtype = cpu_register_io_memory(0, pxa2xx_cm_readfn,

                    pxa2xx_cm_writefn, s);

    cpu_register_physical_memory(s->cm_base, 0xfff, iomemtype);

    register_savevm("pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s);

    cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s);

    s->mm_base = 0x48000000;

    s->mm_regs[MDMRS >> 2] = 0x00020002;

    s->mm_regs[MDREFR >> 2] = 0x03ca4000;

    s->mm_regs[MECR >> 2] = 0x00000001;	/* Two PC Card sockets */

    iomemtype = cpu_register_io_memory(0, pxa2xx_mm_readfn,

                    pxa2xx_mm_writefn, s);

    cpu_register_physical_memory(s->mm_base, 0xfff, iomemtype);

    register_savevm("pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s);

    for (i = 0; pxa27x_ssp[i].io_base; i ++);

    s->ssp = (struct pxa2xx_ssp_s **)

            qemu_mallocz(sizeof(struct pxa2xx_ssp_s *) * i);

    ssp = (struct pxa2xx_ssp_s *)

            qemu_mallocz(sizeof(struct pxa2xx_ssp_s) * i);

    for (i = 0; pxa27x_ssp[i].io_base; i ++) {

        s->ssp[i] = &ssp[i];

        ssp[i].base = pxa27x_ssp[i].io_base;

        ssp[i].irq = s->pic[pxa27x_ssp[i].irqn];

        iomemtype = cpu_register_io_memory(0, pxa2xx_ssp_readfn,

                        pxa2xx_ssp_writefn, &ssp[i]);

        cpu_register_physical_memory(ssp[i].base, 0xfff, iomemtype);

        register_savevm("pxa2xx_ssp", i, 0,

                        pxa2xx_ssp_save, pxa2xx_ssp_load, s);

    }

    if (usb_enabled) {

        usb_ohci_init_pxa(0x4c000000, 3, -1, s->pic[PXA2XX_PIC_USBH1]);

    }

    s->pcmcia[0] = pxa2xx_pcmcia_init(0x20000000);

    s->pcmcia[1] = pxa2xx_pcmcia_init(0x30000000);

    s->rtc_base = 0x40900000;

    iomemtype = cpu_register_io_memory(0, pxa2xx_rtc_readfn,

                    pxa2xx_rtc_writefn, s);

    cpu_register_physical_memory(s->rtc_base, 0xfff, iomemtype);

    pxa2xx_rtc_init(s);

    register_savevm("pxa2xx_rtc", 0, 0, pxa2xx_rtc_save, pxa2xx_rtc_load, s);

    /* Note that PM registers are in the same page with PWRI2C registers.

     * As a workaround we don't map PWRI2C into memory and we expect

     * PM handlers to call PWRI2C handlers when appropriate.  */

    s->i2c[0] = pxa2xx_i2c_init(0x40301600, s->pic[PXA2XX_PIC_I2C], 1);

    s->i2c[1] = pxa2xx_i2c_init(0x40f00100, s->pic[PXA2XX_PIC_PWRI2C], 0);

    s->pm_base = 0x40f00000;

    iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn,

                    pxa2xx_pm_writefn, s);

    cpu_register_physical_memory(s->pm_base, 0xfff, iomemtype);

    register_savevm("pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s);

    s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma);

    /* GPIO1 resets the processor */

    /* The handler can be overriden by board-specific code */

    pxa2xx_gpio_handler_set(s->gpio, 1, pxa2xx_reset, s);

    return s;

}


static int qemu_rbd_snap_rollback(BlockDriverState *bs,

                                  const char *snapshot_name)

{

    BDRVRBDState *s = bs->opaque;

    int r;

    r = rbd_snap_rollback(s->image, snapshot_name);

    return r;

}


static void test_visitor_out_empty(TestOutputVisitorData *data,

                                   const void *unused)

{

    QObject *arg;

    arg = qmp_output_get_qobject(data->qov);

    g_assert(qobject_type(arg) == QTYPE_QNULL);

    /* Check that qnull reference counting is sane */

    g_assert(arg->refcnt == 2);

    qobject_decref(arg);

}


void qio_dns_resolver_lookup_result(QIODNSResolver *resolver,

                                    QIOTask *task,

                                    size_t *naddrs,

                                    SocketAddressLegacy ***addrs)

{

    struct QIODNSResolverLookupData *data =

        qio_task_get_result_pointer(task);

    size_t i;

    *naddrs = 0;

    *addrs = NULL;

    if (!data) {

        return;

    }

    *naddrs = data->naddrs;

    *addrs = g_new0(SocketAddressLegacy *, data->naddrs);

    for (i = 0; i < data->naddrs; i++) {

        (*addrs)[i] = QAPI_CLONE(SocketAddressLegacy, data->addrs[i]);

    }

}


iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,

                        void *command_data, void *opaque)

{

    struct IscsiTask *iTask = opaque;

    struct scsi_task *task = command_data;

    iTask->status = status;

    iTask->do_retry = 0;

    iTask->task = task;

    if (status != SCSI_STATUS_GOOD) {

        if (iTask->retries++ < ISCSI_CMD_RETRIES) {

            if (status == SCSI_STATUS_CHECK_CONDITION

                && task->sense.key == SCSI_SENSE_UNIT_ATTENTION) {

                error_report("iSCSI CheckCondition: %s",

                             iscsi_get_error(iscsi));

                iTask->do_retry = 1;

                goto out;

            }

            if (status == SCSI_STATUS_BUSY ||

                status == SCSI_STATUS_TIMEOUT ||

                status == SCSI_STATUS_TASK_SET_FULL) {

                unsigned retry_time =

                    exp_random(iscsi_retry_times[iTask->retries - 1]);

                if (status == SCSI_STATUS_TIMEOUT) {

                    /* make sure the request is rescheduled AFTER the

                     * reconnect is initiated */

                    retry_time = EVENT_INTERVAL * 2;

                    iTask->iscsilun->request_timed_out = true;

                }

                error_report("iSCSI Busy/TaskSetFull/TimeOut"

                             " (retry #%u in %u ms): %s",

                             iTask->retries, retry_time,

                             iscsi_get_error(iscsi));

                aio_timer_init(iTask->iscsilun->aio_context,

                               &iTask->retry_timer, QEMU_CLOCK_REALTIME,

                               SCALE_MS, iscsi_retry_timer_expired, iTask);

                timer_mod(&iTask->retry_timer,

                          qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + retry_time);

                iTask->do_retry = 1;

                return;

            }

        }

        iTask->err_code = iscsi_translate_sense(&task->sense);

        error_report("iSCSI Failure: %s", iscsi_get_error(iscsi));

    } else {

        iTask->iscsilun->force_next_flush |= iTask->force_next_flush;

    }

out:

    if (iTask->co) {

        iTask->bh = aio_bh_new(iTask->iscsilun->aio_context,

                               iscsi_co_generic_bh_cb, iTask);

        qemu_bh_schedule(iTask->bh);

    } else {

        iTask->complete = 1;

    }

}


void cpu_exec_exit(CPUState *cpu)

{

    if (cpu->cpu_index == -1) {

        /* cpu_index was never allocated by this @cpu or was already freed. */

        return;

    }

    bitmap_clear(cpu_index_map, cpu->cpu_index, 1);

    cpu->cpu_index = -1;

}


build_header(GArray *linker, GArray *table_data,

             AcpiTableHeader *h, const char *sig, int len, uint8_t rev,

             const char *oem_id, const char *oem_table_id)

{

    memcpy(&h->signature, sig, 4);

    h->length = cpu_to_le32(len);

    h->revision = rev;

    if (oem_id) {

        strncpy((char *)h->oem_id, oem_id, sizeof h->oem_id);

    } else {

        memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);

    }

    if (oem_table_id) {

        strncpy((char *)h->oem_table_id, oem_table_id, sizeof(h->oem_table_id));

    } else {

        memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);

        memcpy(h->oem_table_id + 4, sig, 4);

    }

    h->oem_revision = cpu_to_le32(1);

    memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);

    h->asl_compiler_revision = cpu_to_le32(1);

    h->checksum = 0;

    /* Checksum to be filled in by Guest linker */

    bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,

                                    table_data, h, len, &h->checksum);

}


static int kvm_has_msr_hsave_pa(CPUState *env)

{

    kvm_supported_msrs(env);

    return has_msr_hsave_pa;

}


static void sd_cardchange(void *opaque, bool load)

{

    SDState *sd = opaque;

    qemu_set_irq(sd->inserted_cb, blk_is_inserted(sd->blk));

    if (blk_is_inserted(sd->blk)) {

        sd_reset(DEVICE(sd));

        qemu_set_irq(sd->readonly_cb, sd->wp_switch);

    }

}


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

                        int *got_frame_ptr, AVPacket *pkt)

{

    GetBitContext  gb;

    VimaContext    *vima = avctx->priv_data;

    int16_t        pcm_data[2];

    uint32_t       samples;

    int8_t         channel_hint[2];

    int            ret, chan, channels = 1;

    init_get_bits(&gb, pkt->data, pkt->size * 8);

    if (pkt->size < 13)

        return AVERROR_INVALIDDATA;

    samples = get_bits_long(&gb, 32);

    if (samples == 0xffffffff) {

        skip_bits_long(&gb, 32);

        samples = get_bits_long(&gb, 32);

    }

    if (samples > pkt->size * 2)

        return AVERROR_INVALIDDATA;

    channel_hint[0] = get_sbits(&gb, 8);

    if (channel_hint[0] & 0x80) {

        channel_hint[0] = ~channel_hint[0];

        channels = 2;

    }

    avctx->channels = channels;

    avctx->channel_layout = (channels == 2) ? AV_CH_LAYOUT_STEREO :

                                              AV_CH_LAYOUT_MONO;

    pcm_data[0] = get_sbits(&gb, 16);

    if (channels > 1) {

        channel_hint[1] = get_sbits(&gb, 8);

        pcm_data[1] = get_sbits(&gb, 16);

    }

    vima->frame.nb_samples = samples;

    if ((ret = avctx->get_buffer(avctx, &vima->frame)) < 0) {

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

        return ret;

    }

    for (chan = 0; chan < channels; chan++) {

        uint16_t *dest = (uint16_t*)vima->frame.data[0] + chan;

        int step_index = channel_hint[chan];

        int output = pcm_data[chan];

        int sample;

        for (sample = 0; sample < samples; sample++) {

            int lookup_size, lookup, highbit, lowbits;

            step_index  = av_clip(step_index, 0, 88);

            lookup_size = size_table[step_index];

            lookup      = get_bits(&gb, lookup_size);

            highbit     = 1 << (lookup_size - 1);

            lowbits     = highbit - 1;

            if (lookup & highbit)

                lookup ^= highbit;

            else

                highbit = 0;

            if (lookup == lowbits) {

                output = get_sbits(&gb, 16);

            } else {

                int predict_index, diff;

                predict_index = (lookup << (7 - lookup_size)) | (step_index << 6);

                predict_index = av_clip(predict_index, 0, 5785);

                diff          = vima->predict_table[predict_index];

                if (lookup)

                    diff += ff_adpcm_step_table[step_index] >> (lookup_size - 1);

                if (highbit)

                    diff  = -diff;

                output  = av_clip_int16(output + diff);

            }

            *dest = output;

            dest += channels;

            step_index += step_index_tables[lookup_size - 2][lookup];

        }

    }

    *got_frame_ptr   = 1;

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

    return pkt->size;

}


sPAPRTCETable *spapr_tce_find_by_liobn(uint32_t liobn)

{

    sPAPRTCETable *tcet;

    if (liobn & 0xFFFFFFFF00000000ULL) {

        hcall_dprintf("Request for out-of-bounds LIOBN 0x" TARGET_FMT_lx "\n",

                      liobn);

        return NULL;

    }

    QLIST_FOREACH(tcet, &spapr_tce_tables, list) {

        if (tcet->liobn == liobn) {

            return tcet;

        }

    }

    return NULL;

}


static void channel_event(int event, SpiceChannelEventInfo *info)

{

    SpiceServerInfo *server = g_malloc0(sizeof(*server));

    SpiceChannel *client = g_malloc0(sizeof(*client));

    server->base = g_malloc0(sizeof(*server->base));

    client->base = g_malloc0(sizeof(*client->base));

    /*

     * Spice server might have called us from spice worker thread

     * context (happens on display channel disconnects).  Spice should

     * not do that.  It isn't that easy to fix it in spice and even

     * when it is fixed we still should cover the already released

     * spice versions.  So detect that we've been called from another

     * thread and grab the iothread lock if so before calling qemu

     * functions.

     */

    bool need_lock = !qemu_thread_is_self(&me);

    if (need_lock) {

        qemu_mutex_lock_iothread();

    }

    if (info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) {

        add_addr_info(client->base, (struct sockaddr *)&info->paddr_ext,

                      info->plen_ext);

        add_addr_info(server->base, (struct sockaddr *)&info->laddr_ext,

                      info->llen_ext);

    } else {

        error_report("spice: %s, extended address is expected",

                     __func__);

    }

    switch (event) {

    case SPICE_CHANNEL_EVENT_CONNECTED:

        qapi_event_send_spice_connected(server->base, client->base, &error_abort);

        break;

    case SPICE_CHANNEL_EVENT_INITIALIZED:

        if (auth) {

            server->has_auth = true;

            server->auth = g_strdup(auth);

        }

        add_channel_info(client, info);

        channel_list_add(info);

        qapi_event_send_spice_initialized(server, client, &error_abort);

        break;

    case SPICE_CHANNEL_EVENT_DISCONNECTED:

        channel_list_del(info);

        qapi_event_send_spice_disconnected(server->base, client->base, &error_abort);

        break;

    default:

        break;

    }

    if (need_lock) {

        qemu_mutex_unlock_iothread();

    }

    qapi_free_SpiceServerInfo(server);

    qapi_free_SpiceChannel(client);

}


static void qemu_chr_parse_spice_vmc(QemuOpts *opts, ChardevBackend *backend,

                                     Error **errp)

{

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

    if (name == NULL) {

        error_setg(errp, "chardev: spice channel: no name given");

        return;

    }

    backend->u.spicevmc = g_new0(ChardevSpiceChannel, 1);

    backend->u.spicevmc->type = g_strdup(name);

}


void msix_unuse_all_vectors(PCIDevice *dev)

{

    if (!(dev->cap_present & QEMU_PCI_CAP_MSIX))

        return;

    msix_free_irq_entries(dev);

}


static void pc_system_flash_init(MemoryRegion *rom_memory)

{

    int unit;

    DriveInfo *pflash_drv;

    BlockDriverState *bdrv;

    int64_t size;

    char *fatal_errmsg = NULL;

    hwaddr phys_addr = 0x100000000ULL;

    int sector_bits, sector_size;

    pflash_t *system_flash;

    MemoryRegion *flash_mem;

    char name[64];

    sector_bits = 12;

    sector_size = 1 << sector_bits;

    for (unit = 0;

         (unit < FLASH_MAP_UNIT_MAX &&

          (pflash_drv = drive_get(IF_PFLASH, 0, unit)) != NULL);

         ++unit) {

        bdrv = blk_bs(blk_by_legacy_dinfo(pflash_drv));

        size = bdrv_getlength(bdrv);

        if (size < 0) {

            fatal_errmsg = g_strdup_printf("failed to get backing file size");

        } else if (size == 0) {

            fatal_errmsg = g_strdup_printf("PC system firmware (pflash) "

                               "cannot have zero size");

        } else if ((size % sector_size) != 0) {

            fatal_errmsg = g_strdup_printf("PC system firmware (pflash) "

                               "must be a multiple of 0x%x", sector_size);

        } else if (phys_addr < size || phys_addr - size < FLASH_MAP_BASE_MIN) {

            fatal_errmsg = g_strdup_printf("oversized backing file, pflash "

                               "segments cannot be mapped under "

                               TARGET_FMT_plx, FLASH_MAP_BASE_MIN);

        }

        if (fatal_errmsg != NULL) {

            Location loc;

            /* push a new, "none" location on the location stack; overwrite its

             * contents with the location saved in the option; print the error

             * (includes location); pop the top

             */

            loc_push_none(&loc);

            if (pflash_drv->opts != NULL) {

                qemu_opts_loc_restore(pflash_drv->opts);

            }

            error_report("%s", fatal_errmsg);

            loc_pop(&loc);

            g_free(fatal_errmsg);

            exit(1);

        }

        phys_addr -= size;

        /* pflash_cfi01_register() creates a deep copy of the name */

        snprintf(name, sizeof name, "system.flash%d", unit);

        system_flash = pflash_cfi01_register(phys_addr, NULL /* qdev */, name,

                                             size, bdrv, sector_size,

                                             size >> sector_bits,

                                             1      /* width */,

                                             0x0000 /* id0 */,

                                             0x0000 /* id1 */,

                                             0x0000 /* id2 */,

                                             0x0000 /* id3 */,

                                             0      /* be */);

        if (unit == 0) {

            flash_mem = pflash_cfi01_get_memory(system_flash);

            pc_isa_bios_init(rom_memory, flash_mem, size);

        }

    }

}


static int load_textfile(AVFilterContext *ctx)

{

    DrawTextContext *s = ctx->priv;

    int err;

    uint8_t *textbuf;

    size_t textbuf_size;

    if ((err = av_file_map(s->textfile, &textbuf, &textbuf_size, 0, ctx)) < 0) {

        av_log(ctx, AV_LOG_ERROR,

               "The text file '%s' could not be read or is empty\n",

               s->textfile);

        return err;

    }

    if (!(s->text = av_realloc(s->text, textbuf_size + 1)))

        return AVERROR(ENOMEM);

    memcpy(s->text, textbuf, textbuf_size);

    s->text[textbuf_size] = 0;

    av_file_unmap(textbuf, textbuf_size);

    return 0;

}


static int ftp_send_command(FTPContext *s, const char *command,
                            const int response_codes[], char **response)
{
    int err;
    ff_dlog(s, "%s", command);
    if (response)
        *response = NULL;
    if ((err = ffurl_write(s->conn_control, command, strlen(command))) < 0)
        return err;
    if (!err)
        return -1;
    /* return status */
    if (response_codes) {
        return ftp_status(s, response, response_codes);
    }
    return 0;
}


static void sun4c_hw_init(const struct hwdef *hwdef, ram_addr_t RAM_size,

                          const char *boot_device,

                          DisplayState *ds, const char *kernel_filename,

                          const char *kernel_cmdline,

                          const char *initrd_filename, const char *cpu_model)

{

    CPUState *env;

    unsigned int i;

    void *iommu, *espdma, *ledma, *main_esp, *nvram;

    qemu_irq *cpu_irqs, *slavio_irq, *espdma_irq, *ledma_irq;

    qemu_irq *esp_reset, *le_reset;

    qemu_irq *fdc_tc;

    unsigned long prom_offset, kernel_size;

    int ret;

    char buf[1024];

    BlockDriverState *fd[MAX_FD];

    int drive_index;

    void *fw_cfg;

    /* init CPU */

    if (!cpu_model)

        cpu_model = hwdef->default_cpu_model;

    env = cpu_init(cpu_model);

    if (!env) {

        fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");

        exit(1);

    }

    cpu_sparc_set_id(env, 0);

    qemu_register_reset(main_cpu_reset, env);

    cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);

    env->prom_addr = hwdef->slavio_base;

    /* allocate RAM */

    if ((uint64_t)RAM_size > hwdef->max_mem) {

        fprintf(stderr,

                "qemu: Too much memory for this machine: %d, maximum %d\n",

                (unsigned int)(RAM_size / (1024 * 1024)),

                (unsigned int)(hwdef->max_mem / (1024 * 1024)));

        exit(1);

    }

    cpu_register_physical_memory(0, RAM_size, 0);

    /* load boot prom */

    prom_offset = RAM_size + hwdef->vram_size;

    cpu_register_physical_memory(hwdef->slavio_base,

                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) &

                                 TARGET_PAGE_MASK,

                                 prom_offset | IO_MEM_ROM);

    if (bios_name == NULL)

        bios_name = PROM_FILENAME;

    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);

    ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL);

    if (ret < 0 || ret > PROM_SIZE_MAX)

        ret = load_image_targphys(buf, hwdef->slavio_base, PROM_SIZE_MAX);

    if (ret < 0 || ret > PROM_SIZE_MAX) {

        fprintf(stderr, "qemu: could not load prom '%s'\n",

                buf);

        exit(1);

    }

    prom_offset += (ret + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;

    /* set up devices */

    slavio_intctl = sun4c_intctl_init(hwdef->sun4c_intctl_base,

                                      &slavio_irq, cpu_irqs);

    iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,

                       slavio_irq[hwdef->me_irq]);

    espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],

                              iommu, &espdma_irq, &esp_reset);

    ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,

                             slavio_irq[hwdef->le_irq], iommu, &ledma_irq,

                             &le_reset);

    if (graphic_depth != 8 && graphic_depth != 24) {

        fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);

        exit (1);

    }

    tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size,

             hwdef->vram_size, graphic_width, graphic_height, graphic_depth);

    if (nd_table[0].model == NULL

        || strcmp(nd_table[0].model, "lance") == 0) {

        lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);

    } else if (strcmp(nd_table[0].model, "?") == 0) {

        fprintf(stderr, "qemu: Supported NICs: lance\n");

        exit (1);

    } else {

        fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);

        exit (1);

    }

    nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,

                        hwdef->nvram_size, 2);

    slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq],

                              nographic);

    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device

    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device

    slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],

                       serial_hds[1], serial_hds[0]);

    slavio_misc = slavio_misc_init(-1, hwdef->apc_base,

                                   hwdef->aux1_base, hwdef->aux2_base,

                                   slavio_irq[hwdef->me_irq], env, &fdc_tc);

    if (hwdef->fd_base != (target_phys_addr_t)-1) {

        /* there is zero or one floppy drive */

        fd[1] = fd[0] = NULL;

        drive_index = drive_get_index(IF_FLOPPY, 0, 0);

        if (drive_index != -1)

            fd[0] = drives_table[drive_index].bdrv;

        sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd,

                          fdc_tc);

    }

    if (drive_get_max_bus(IF_SCSI) > 0) {

        fprintf(stderr, "qemu: too many SCSI bus\n");

        exit(1);

    }

    main_esp = esp_init(hwdef->esp_base, 2,

                        espdma_memory_read, espdma_memory_write,

                        espdma, *espdma_irq, esp_reset);

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

        drive_index = drive_get_index(IF_SCSI, 0, i);

        if (drive_index == -1)

            continue;

        esp_scsi_attach(main_esp, drives_table[drive_index].bdrv, i);

    }

    kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,

                                    RAM_size);

    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,

               boot_device, RAM_size, kernel_size, graphic_width,

               graphic_height, graphic_depth, hwdef->nvram_machine_id,

               "Sun4c");

    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);

    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);

    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);

    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);

}