print_insn_sparc (bfd_vma memaddr, disassemble_info *info)

{

  FILE *stream = info->stream;

  bfd_byte buffer[4];

  unsigned long insn;

  sparc_opcode_hash *op;

  /* Nonzero of opcode table has been initialized.  */

  static int opcodes_initialized = 0;

  /* bfd mach number of last call.  */

  static unsigned long current_mach = 0;

  bfd_vma (*getword) (const unsigned char *);

  if (!opcodes_initialized

      || info->mach != current_mach)

    {

      int i;

      current_arch_mask = compute_arch_mask (info->mach);

      if (!opcodes_initialized)

        sorted_opcodes =

          malloc (sparc_num_opcodes * sizeof (sparc_opcode *));

      /* Reset the sorted table so we can resort it.  */

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

        sorted_opcodes[i] = &sparc_opcodes[i];

      qsort ((char *) sorted_opcodes, sparc_num_opcodes,

             sizeof (sorted_opcodes[0]), compare_opcodes);

      build_hash_table (sorted_opcodes, opcode_hash_table, sparc_num_opcodes);

      current_mach = info->mach;

      opcodes_initialized = 1;

    }

  {

    int status =

      (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);

    if (status != 0)

      {

        (*info->memory_error_func) (status, memaddr, info);

        return -1;

      }

  }

  /* On SPARClite variants such as DANlite (sparc86x), instructions

     are always big-endian even when the machine is in little-endian mode.  */

  if (info->endian == BFD_ENDIAN_BIG || info->mach == bfd_mach_sparc_sparclite)

    getword = bfd_getb32;

  else

    getword = bfd_getl32;

  insn = getword (buffer);

  info->insn_info_valid = 1;                    /* We do return this info.  */

  info->insn_type = dis_nonbranch;              /* Assume non branch insn.  */

  info->branch_delay_insns = 0;                 /* Assume no delay.  */

  info->target = 0;                             /* Assume no target known.  */

  for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)

    {

      const sparc_opcode *opcode = op->opcode;

      /* If the insn isn't supported by the current architecture, skip it.  */

      if (! (opcode->architecture & current_arch_mask))

        continue;

      if ((opcode->match & insn) == opcode->match

          && (opcode->lose & insn) == 0)

        {

          /* Nonzero means that we have found an instruction which has

             the effect of adding or or'ing the imm13 field to rs1.  */

          int imm_added_to_rs1 = 0;

          int imm_ored_to_rs1 = 0;

          /* Nonzero means that we have found a plus sign in the args

             field of the opcode table.  */

          int found_plus = 0;

          /* Nonzero means we have an annulled branch.  */

          /* int is_annulled = 0; */ /* see FIXME below */

          /* Do we have an `add' or `or' instruction combining an

             immediate with rs1?  */

          if (opcode->match == 0x80102000) /* or */

            imm_ored_to_rs1 = 1;

          if (opcode->match == 0x80002000) /* add */

            imm_added_to_rs1 = 1;

          if (X_RS1 (insn) != X_RD (insn)

              && strchr (opcode->args, 'r') != NULL)

              /* Can't do simple format if source and dest are different.  */

              continue;

          if (X_RS2 (insn) != X_RD (insn)

              && strchr (opcode->args, 'O') != NULL)

              /* Can't do simple format if source and dest are different.  */

              continue;

          (*info->fprintf_func) (stream, opcode->name);

          {

            const char *s;

            if (opcode->args[0] != ',')

              (*info->fprintf_func) (stream, " ");

            for (s = opcode->args; *s != '\0'; ++s)

              {

                while (*s == ',')

                  {

                    (*info->fprintf_func) (stream, ",");

                    ++s;

                    switch (*s)

                      {

                      case 'a':

                        (*info->fprintf_func) (stream, "a");

                        /* is_annulled = 1; */ /* see FIXME below */

                        ++s;

                        continue;

                      case 'N':

                        (*info->fprintf_func) (stream, "pn");

                        ++s;

                        continue;

                      case 'T':

                        (*info->fprintf_func) (stream, "pt");

                        ++s;

                        continue;

                      default:

                        break;

                      }

                  }

                (*info->fprintf_func) (stream, " ");

                switch (*s)

                  {

                  case '+':

                    found_plus = 1;

                    /* Fall through.  */

                  default:

                    (*info->fprintf_func) (stream, "%c", *s);

                    break;

                  case '#':

                    (*info->fprintf_func) (stream, "0");

                    break;

#define reg(n)  (*info->fprintf_func) (stream, "%%%s", reg_names[n])

                  case '1':

                  case 'r':

                    reg (X_RS1 (insn));

                    break;

                  case '2':

                  case 'O':

                    reg (X_RS2 (insn));

                    break;

                  case 'd':

                    reg (X_RD (insn));

                    break;

#undef  reg

#define freg(n)         (*info->fprintf_func) (stream, "%%%s", freg_names[n])

#define fregx(n)        (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])

                  case 'e':

                    freg (X_RS1 (insn));

                    break;

                  case 'v':     /* Double/even.  */

                  case 'V':     /* Quad/multiple of 4.  */

                    fregx (X_RS1 (insn));

                    break;

                  case 'f':

                    freg (X_RS2 (insn));

                    break;

                  case 'B':     /* Double/even.  */

                  case 'R':     /* Quad/multiple of 4.  */

                    fregx (X_RS2 (insn));

                    break;

                  case 'g':

                    freg (X_RD (insn));

                    break;

                  case 'H':     /* Double/even.  */

                  case 'J':     /* Quad/multiple of 4.  */

                    fregx (X_RD (insn));

                    break;

#undef  freg

#undef  fregx

#define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))

                  case 'b':

                    creg (X_RS1 (insn));

                    break;

                  case 'c':

                    creg (X_RS2 (insn));

                    break;

                  case 'D':

                    creg (X_RD (insn));

                    break;

#undef  creg

                  case 'h':

                    (*info->fprintf_func) (stream, "%%hi(%#x)",

                                           ((unsigned) 0xFFFFFFFF

                                            & ((int) X_IMM22 (insn) << 10)));

                    break;

                  case 'i':     /* 13 bit immediate.  */

                  case 'I':     /* 11 bit immediate.  */

                  case 'j':     /* 10 bit immediate.  */

                    {

                      int imm;

                      if (*s == 'i')

                        imm = X_SIMM (insn, 13);

                      else if (*s == 'I')

                        imm = X_SIMM (insn, 11);

                      else

                        imm = X_SIMM (insn, 10);

                      /* Check to see whether we have a 1+i, and take

                         note of that fact.

                         Note: because of the way we sort the table,

                         we will be matching 1+i rather than i+1,

                         so it is OK to assume that i is after +,

                         not before it.  */

                      if (found_plus)

                        imm_added_to_rs1 = 1;

                      if (imm <= 9)

                        (*info->fprintf_func) (stream, "%d", imm);

                      else

                        (*info->fprintf_func) (stream, "%#x", imm);

                    }

                    break;

                  case 'X':     /* 5 bit unsigned immediate.  */

                  case 'Y':     /* 6 bit unsigned immediate.  */

                    {

                      int imm = X_IMM (insn, *s == 'X' ? 5 : 6);

                      if (imm <= 9)

                        (info->fprintf_func) (stream, "%d", imm);

                      else

                        (info->fprintf_func) (stream, "%#x", (unsigned) imm);

                    }

                    break;

                  case '3':

                    (info->fprintf_func) (stream, "%ld", X_IMM (insn, 3));

                    break;

                  case 'K':

                    {

                      int mask = X_MEMBAR (insn);

                      int bit = 0x40, printed_one = 0;

                      const char *name;

                      if (mask == 0)

                        (info->fprintf_func) (stream, "0");

                      else

                        while (bit)

                          {

                            if (mask & bit)

                              {

                                if (printed_one)

                                  (info->fprintf_func) (stream, "|");

                                name = sparc_decode_membar (bit);

                                (info->fprintf_func) (stream, "%s", name);

                                printed_one = 1;

                              }

                            bit >>= 1;

                          }

                      break;

                    }

                  case 'k':

                    info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4;

                    (*info->print_address_func) (info->target, info);

                    break;

                  case 'G':

                    info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4;

                    (*info->print_address_func) (info->target, info);

                    break;

                  case '6':

                  case '7':

                  case '8':

                  case '9':

                    (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');

                    break;

                  case 'z':

                    (*info->fprintf_func) (stream, "%%icc");

                    break;

                  case 'Z':

                    (*info->fprintf_func) (stream, "%%xcc");

                    break;

                  case 'E':

                    (*info->fprintf_func) (stream, "%%ccr");

                    break;

                  case 's':

                    (*info->fprintf_func) (stream, "%%fprs");

                    break;

                  case 'o':

                    (*info->fprintf_func) (stream, "%%asi");

                    break;

                  case 'W':

                    (*info->fprintf_func) (stream, "%%tick");

                    break;

                  case 'P':

                    (*info->fprintf_func) (stream, "%%pc");

                    break;

                  case '?':

                    if (X_RS1 (insn) == 31)

                      (*info->fprintf_func) (stream, "%%ver");

                    else if ((unsigned) X_RS1 (insn) < 17)

                      (*info->fprintf_func) (stream, "%%%s",

                                             v9_priv_reg_names[X_RS1 (insn)]);

                    else

                      (*info->fprintf_func) (stream, "%%reserved");

                    break;

                  case '!':

                    if ((unsigned) X_RD (insn) < 17)

                      (*info->fprintf_func) (stream, "%%%s",

                                             v9_priv_reg_names[X_RD (insn)]);

                    else

                      (*info->fprintf_func) (stream, "%%reserved");

                    break;

                  case '$':

                    if ((unsigned) X_RS1 (insn) < 32)

                      (*info->fprintf_func) (stream, "%%%s",

                                             v9_hpriv_reg_names[X_RS1 (insn)]);

                    else

                      (*info->fprintf_func) (stream, "%%reserved");

                    break;

                  case '%':

                    if ((unsigned) X_RD (insn) < 32)

                      (*info->fprintf_func) (stream, "%%%s",

                                             v9_hpriv_reg_names[X_RD (insn)]);

                    else

                      (*info->fprintf_func) (stream, "%%reserved");

                    break;

                  case '/':

                    if (X_RS1 (insn) < 16 || X_RS1 (insn) > 25)

                      (*info->fprintf_func) (stream, "%%reserved");

                    else

                      (*info->fprintf_func) (stream, "%%%s",

                                             v9a_asr_reg_names[X_RS1 (insn)-16]);

                    break;

                  case '_':

                    if (X_RD (insn) < 16 || X_RD (insn) > 25)

                      (*info->fprintf_func) (stream, "%%reserved");

                    else

                      (*info->fprintf_func) (stream, "%%%s",

                                             v9a_asr_reg_names[X_RD (insn)-16]);

                    break;

                  case '*':

                    {

                      const char *name = sparc_decode_prefetch (X_RD (insn));

                      if (name)

                        (*info->fprintf_func) (stream, "%s", name);

                      else

                        (*info->fprintf_func) (stream, "%ld", X_RD (insn));

                      break;

                    }

                  case 'M':

                    (*info->fprintf_func) (stream, "%%asr%ld", X_RS1 (insn));

                    break;

                  case 'm':

                    (*info->fprintf_func) (stream, "%%asr%ld", X_RD (insn));

                    break;

                  case 'L':

                    info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4;

                    (*info->print_address_func) (info->target, info);

                    break;

                  case 'n':

                    (*info->fprintf_func)

                      (stream, "%#x", SEX (X_DISP22 (insn), 22));

                    break;

                  case 'l':

                    info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4;

                    (*info->print_address_func) (info->target, info);

                    break;

                  case 'A':

                    {

                      const char *name;

                      if ((info->mach == bfd_mach_sparc_v8plusa) ||

                          ((info->mach >= bfd_mach_sparc_v9) &&

                           (info->mach <= bfd_mach_sparc_v9b)))

                        name = sparc_decode_asi_v9 (X_ASI (insn));

                      else

                        name = sparc_decode_asi_v8 (X_ASI (insn));

                      if (name)

                        (*info->fprintf_func) (stream, "%s", name);

                      else

                        (*info->fprintf_func) (stream, "(%ld)", X_ASI (insn));

                      break;

                    }

                  case 'C':

                    (*info->fprintf_func) (stream, "%%csr");

                    break;

                  case 'F':

                    (*info->fprintf_func) (stream, "%%fsr");

                    break;

                  case 'p':

                    (*info->fprintf_func) (stream, "%%psr");

                    break;

                  case 'q':

                    (*info->fprintf_func) (stream, "%%fq");

                    break;

                  case 'Q':

                    (*info->fprintf_func) (stream, "%%cq");

                    break;

                  case 't':

                    (*info->fprintf_func) (stream, "%%tbr");

                    break;

                  case 'w':

                    (*info->fprintf_func) (stream, "%%wim");

                    break;

                  case 'x':

                    (*info->fprintf_func) (stream, "%ld",

                                           ((X_LDST_I (insn) << 8)

                                            + X_ASI (insn)));

                    break;

                  case 'y':

                    (*info->fprintf_func) (stream, "%%y");

                    break;

                  case 'u':

                  case 'U':

                    {

                      int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn);

                      const char *name = sparc_decode_sparclet_cpreg (val);

                      if (name)

                        (*info->fprintf_func) (stream, "%s", name);

                      else

                        (*info->fprintf_func) (stream, "%%cpreg(%d)", val);

                      break;

                    }

                  }

              }

          }

          /* If we are adding or or'ing something to rs1, then

             check to see whether the previous instruction was

             a sethi to the same register as in the sethi.

             If so, attempt to print the result of the add or

             or (in this context add and or do the same thing)

             and its symbolic value.  */

          if (imm_ored_to_rs1 || imm_added_to_rs1)

            {

              unsigned long prev_insn;

              int errcode;

              if (memaddr >= 4)

                errcode =

                  (*info->read_memory_func)

                  (memaddr - 4, buffer, sizeof (buffer), info);

              else

                errcode = 1;

              prev_insn = getword (buffer);

              if (errcode == 0)

                {

                  /* If it is a delayed branch, we need to look at the

                     instruction before the delayed branch.  This handles

                     sequences such as:

                     sethi %o1, %hi(_foo), %o1

                     call _printf

                     or %o1, %lo(_foo), %o1  */

                  if (is_delayed_branch (prev_insn))

                    {

                      if (memaddr >= 8)

                        errcode = (*info->read_memory_func)

                          (memaddr - 8, buffer, sizeof (buffer), info);

                      else

                        errcode = 1;

                      prev_insn = getword (buffer);

                    }

                }

              /* If there was a problem reading memory, then assume

                 the previous instruction was not sethi.  */

              if (errcode == 0)

                {

                  /* Is it sethi to the same register?  */

                  if ((prev_insn & 0xc1c00000) == 0x01000000

                      && X_RD (prev_insn) == X_RS1 (insn))

                    {

                      (*info->fprintf_func) (stream, "\t! ");

                      info->target =

                        ((unsigned) 0xFFFFFFFF

                         & ((int) X_IMM22 (prev_insn) << 10));

                      if (imm_added_to_rs1)

                        info->target += X_SIMM (insn, 13);

                      else

                        info->target |= X_SIMM (insn, 13);

                      (*info->print_address_func) (info->target, info);

                      info->insn_type = dis_dref;

                      info->data_size = 4;  /* FIXME!!! */

                    }

                }

            }

          if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))

            {

                /* FIXME -- check is_annulled flag.  */

              if (opcode->flags & F_UNBR)

                info->insn_type = dis_branch;

              if (opcode->flags & F_CONDBR)

                info->insn_type = dis_condbranch;

              if (opcode->flags & F_JSR)

                info->insn_type = dis_jsr;

              if (opcode->flags & F_DELAYED)

                info->branch_delay_insns = 1;

            }

          return sizeof (buffer);

        }

    }

  info->insn_type = dis_noninsn;        /* Mark as non-valid instruction.  */

  (*info->fprintf_func) (stream, _("unknown"));

  return sizeof (buffer);

}


static int max7310_tx(I2CSlave *i2c, uint8_t data)

{

    MAX7310State *s = MAX7310(i2c);

    uint8_t diff;

    int line;

    if (s->len ++ > 1) {

#ifdef VERBOSE

        printf("%s: message too long (%i bytes)\n", __FUNCTION__, s->len);

#endif

        return 1;

    }

    if (s->i2c_command_byte) {

        s->command = data;

        s->i2c_command_byte = 0;

        return 0;

    }

    switch (s->command) {

    case 0x01:	/* Output port */

        for (diff = (data ^ s->level) & ~s->direction; diff;

                        diff &= ~(1 << line)) {

            line = ffs(diff) - 1;

            if (s->handler[line])

                qemu_set_irq(s->handler[line], (data >> line) & 1);

        }

        s->level = (s->level & s->direction) | (data & ~s->direction);

        break;

    case 0x02:	/* Polarity inversion */

        s->polarity = data;

        break;

    case 0x03:	/* Configuration */

        s->level &= ~(s->direction ^ data);

        s->direction = data;

        break;

    case 0x04:	/* Timeout */

        s->status = data;

        break;

    case 0x00:	/* Input port - ignore writes */

	break;

    default:

#ifdef VERBOSE

        printf("%s: unknown register %02x\n", __FUNCTION__, s->command);

#endif

        return 1;

    }

    return 0;

}


BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv)

{

    DriveInfo *dinfo;

    TAILQ_FOREACH(dinfo, &drives, next) {

        if (dinfo->bdrv == bdrv)

            return dinfo->onerror;

    }

    return BLOCK_ERR_STOP_ENOSPC;

}


static inline void tcg_out_movi_imm32(TCGContext *s, int ret, uint32_t arg)

{

    if (check_fit_tl(arg, 12))

        tcg_out_movi_imm13(s, ret, arg);

    else {

        tcg_out_sethi(s, ret, arg);

        if (arg & 0x3ff)

            tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);

    }

}


static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg)

{

    uint8_t type;

    while (dev) {

        if (!pci_is_express(dev)) {

            /* just ignore it */

            /* TODO: Shouldn't we set PCI_STATUS_SIG_SYSTEM_ERROR?

             * Consider e.g. a PCI bridge above a PCI Express device. */

            return;

        }

        type = pcie_cap_get_type(dev);

        if ((type == PCI_EXP_TYPE_ROOT_PORT ||

            type == PCI_EXP_TYPE_UPSTREAM ||

            type == PCI_EXP_TYPE_DOWNSTREAM) &&

            !pcie_aer_msg_vbridge(dev, msg)) {

                return;

        }

        if (!pcie_aer_msg_alldev(dev, msg)) {

            return;

        }

        if (type == PCI_EXP_TYPE_ROOT_PORT) {

            pcie_aer_msg_root_port(dev, msg);

            /* Root port can notify system itself,

               or send the error message to root complex event collector. */

            /*

             * if root port is associated with an event collector,

             * return the root complex event collector here.

             * For now root complex event collector isn't supported.

             */

            return;

        }

        dev = pci_bridge_get_device(dev->bus);

    }

}


static int ide_drive_pio_post_load(void *opaque, int version_id)

{

    IDEState *s = opaque;

    if (s->end_transfer_fn_idx < 0 ||

        s->end_transfer_fn_idx > ARRAY_SIZE(transfer_end_table)) {

        return -EINVAL;

    }

    s->end_transfer_func = transfer_end_table[s->end_transfer_fn_idx];

    s->data_ptr = s->io_buffer + s->cur_io_buffer_offset;

    s->data_end = s->data_ptr + s->cur_io_buffer_len;

    return 0;

}


void timer_del(QEMUTimer *ts)

{

    QEMUTimer **pt, *t;

    pt = &ts->timer_list->active_timers;

    for(;;) {

        t = *pt;

        if (!t)

            break;

        if (t == ts) {

            *pt = t->next;

            break;

        }

        pt = &t->next;

    }

}


static int xen_host_pci_get_value(XenHostPCIDevice *d, const char *name,

                                  unsigned int *pvalue, int base)

{

    char path[PATH_MAX];

    char buf[XEN_HOST_PCI_GET_VALUE_BUFFER_SIZE];

    int fd, rc;

    unsigned long value;

    char *endptr;

    xen_host_pci_sysfs_path(d, name, path, sizeof(path));

    fd = open(path, O_RDONLY);

    if (fd == -1) {

        XEN_HOST_PCI_LOG("Error: Can't open %s: %s\n", path, strerror(errno));

        return -errno;

    }

    do {

        rc = read(fd, &buf, sizeof (buf) - 1);

        if (rc < 0 && errno != EINTR) {

            rc = -errno;

            goto out;

        }

    } while (rc < 0);

    buf[rc] = 0;

    value = strtol(buf, &endptr, base);

    if (endptr == buf || *endptr != '\n') {

        rc = -1;

    } else if ((value == LONG_MIN || value == LONG_MAX) && errno == ERANGE) {

        rc = -errno;

    } else {

        rc = 0;

        *pvalue = value;

    }

out:

    close(fd);

    return rc;

}


uint32_t helper_float_cvtw_s(CPUMIPSState *env, uint32_t fst0)

{

    uint32_t wt2;

    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);

    update_fcr31(env, GETPC());

    if (get_float_exception_flags(&env->active_fpu.fp_status)

        & (float_flag_invalid | float_flag_overflow)) {

        wt2 = FP_TO_INT32_OVERFLOW;

    }

    return wt2;

}


static void test_visitor_in_native_list_int16(TestInputVisitorData *data,

                                              const void *unused)

{

    test_native_list_integer_helper(data, unused,

                                    USER_DEF_NATIVE_LIST_UNION_KIND_S16);

}


int get_osversion(void)

{

    static int osversion;

    struct new_utsname buf;

    const char *s;

    int i, n, tmp;

    if (osversion)

        return osversion;

    if (qemu_uname_release && *qemu_uname_release) {

        s = qemu_uname_release;

    } else {

        if (sys_uname(&buf))

            return 0;

        s = buf.release;

    }

    tmp = 0;

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

        n = 0;

        while (*s >= '0' && *s <= '9') {

            n *= 10;

            n += *s - '0';

            s++;

        }

        tmp = (tmp << 8) + n;

        if (*s == '.')

            s++;

    }

    osversion = tmp;

    return osversion;

}


static int colo_packet_compare_common(Packet *ppkt, Packet *spkt)

{

    trace_colo_compare_ip_info(ppkt->size, inet_ntoa(ppkt->ip->ip_src),

                               inet_ntoa(ppkt->ip->ip_dst), spkt->size,

                               inet_ntoa(spkt->ip->ip_src),

                               inet_ntoa(spkt->ip->ip_dst));

    if (ppkt->size == spkt->size) {

        return memcmp(ppkt->data, spkt->data, spkt->size);

    } else {

        trace_colo_compare_main("Net packet size are not the same");

        return -1;

    }

}


static int gdb_handle_packet(GDBState *s, const char *line_buf)

{

    CPUState *env;

    const char *p;

    int ch, reg_size, type, res, thread;

    char buf[MAX_PACKET_LENGTH];

    uint8_t mem_buf[MAX_PACKET_LENGTH];

    uint8_t *registers;

    target_ulong addr, len;

#ifdef DEBUG_GDB

    printf("command='%s'\n", line_buf);

#endif

    p = line_buf;

    ch = *p++;

    switch(ch) {

    case '?':

        /* TODO: Make this return the correct value for user-mode.  */

        snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,

                 s->c_cpu->cpu_index+1);

        put_packet(s, buf);

        /* Remove all the breakpoints when this query is issued,

         * because gdb is doing and initial connect and the state

         * should be cleaned up.

         */

        gdb_breakpoint_remove_all();

        break;

    case 'c':

        if (*p != '\0') {

            addr = strtoull(p, (char **)&p, 16);

#if defined(TARGET_I386)

            s->c_cpu->eip = addr;

#elif defined (TARGET_PPC)

            s->c_cpu->nip = addr;

#elif defined (TARGET_SPARC)

            s->c_cpu->pc = addr;

            s->c_cpu->npc = addr + 4;

#elif defined (TARGET_ARM)

            s->c_cpu->regs[15] = addr;

#elif defined (TARGET_SH4)

            s->c_cpu->pc = addr;

#elif defined (TARGET_MIPS)

            s->c_cpu->active_tc.PC = addr;

#elif defined (TARGET_CRIS)

            s->c_cpu->pc = addr;

#elif defined (TARGET_ALPHA)

            s->c_cpu->pc = addr;

#endif

        }

        s->signal = 0;

        gdb_continue(s);

	return RS_IDLE;

    case 'C':

        s->signal = gdb_signal_to_target (strtoul(p, (char **)&p, 16));

        if (s->signal == -1)

            s->signal = 0;

        gdb_continue(s);

        return RS_IDLE;

    case 'k':

        /* Kill the target */

        fprintf(stderr, "\nQEMU: Terminated via GDBstub\n");

        exit(0);

    case 'D':

        /* Detach packet */

        gdb_breakpoint_remove_all();

        gdb_continue(s);

        put_packet(s, "OK");

        break;

    case 's':

        if (*p != '\0') {

            addr = strtoull(p, (char **)&p, 16);

#if defined(TARGET_I386)

            s->c_cpu->eip = addr;

#elif defined (TARGET_PPC)

            s->c_cpu->nip = addr;

#elif defined (TARGET_SPARC)

            s->c_cpu->pc = addr;

            s->c_cpu->npc = addr + 4;

#elif defined (TARGET_ARM)

            s->c_cpu->regs[15] = addr;

#elif defined (TARGET_SH4)

            s->c_cpu->pc = addr;

#elif defined (TARGET_MIPS)

            s->c_cpu->active_tc.PC = addr;

#elif defined (TARGET_CRIS)

            s->c_cpu->pc = addr;

#elif defined (TARGET_ALPHA)

            s->c_cpu->pc = addr;

#endif

        }

        cpu_single_step(s->c_cpu, sstep_flags);

        gdb_continue(s);

	return RS_IDLE;

    case 'F':

        {

            target_ulong ret;

            target_ulong err;

            ret = strtoull(p, (char **)&p, 16);

            if (*p == ',') {

                p++;

                err = strtoull(p, (char **)&p, 16);

            } else {

                err = 0;

            }

            if (*p == ',')

                p++;

            type = *p;

            if (gdb_current_syscall_cb)

                gdb_current_syscall_cb(s->c_cpu, ret, err);

            if (type == 'C') {

                put_packet(s, "T02");

            } else {

                gdb_continue(s);

            }

        }

        break;

    case 'g':

        len = 0;

        for (addr = 0; addr < num_g_regs; addr++) {

            reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);

            len += reg_size;

        }

        memtohex(buf, mem_buf, len);

        put_packet(s, buf);

        break;

    case 'G':

        registers = mem_buf;

        len = strlen(p) / 2;

        hextomem((uint8_t *)registers, p, len);

        for (addr = 0; addr < num_g_regs && len > 0; addr++) {

            reg_size = gdb_write_register(s->g_cpu, registers, addr);

            len -= reg_size;

            registers += reg_size;

        }

        put_packet(s, "OK");

        break;

    case 'm':

        addr = strtoull(p, (char **)&p, 16);

        if (*p == ',')

            p++;

        len = strtoull(p, NULL, 16);

        if (cpu_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 0) != 0) {

            put_packet (s, "E14");

        } else {

            memtohex(buf, mem_buf, len);

            put_packet(s, buf);

        }

        break;

    case 'M':

        addr = strtoull(p, (char **)&p, 16);

        if (*p == ',')

            p++;

        len = strtoull(p, (char **)&p, 16);

        if (*p == ':')

            p++;

        hextomem(mem_buf, p, len);

        if (cpu_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 1) != 0)

            put_packet(s, "E14");

        else

            put_packet(s, "OK");

        break;

    case 'p':

        /* Older gdb are really dumb, and don't use 'g' if 'p' is avaialable.

           This works, but can be very slow.  Anything new enough to

           understand XML also knows how to use this properly.  */

        if (!gdb_has_xml)

            goto unknown_command;

        addr = strtoull(p, (char **)&p, 16);

        reg_size = gdb_read_register(s->g_cpu, mem_buf, addr);

        if (reg_size) {

            memtohex(buf, mem_buf, reg_size);

            put_packet(s, buf);

        } else {

            put_packet(s, "E14");

        }

        break;

    case 'P':

        if (!gdb_has_xml)

            goto unknown_command;

        addr = strtoull(p, (char **)&p, 16);

        if (*p == '=')

            p++;

        reg_size = strlen(p) / 2;

        hextomem(mem_buf, p, reg_size);

        gdb_write_register(s->g_cpu, mem_buf, addr);

        put_packet(s, "OK");

        break;

    case 'Z':

    case 'z':

        type = strtoul(p, (char **)&p, 16);

        if (*p == ',')

            p++;

        addr = strtoull(p, (char **)&p, 16);

        if (*p == ',')

            p++;

        len = strtoull(p, (char **)&p, 16);

        if (ch == 'Z')

            res = gdb_breakpoint_insert(addr, len, type);

        else

            res = gdb_breakpoint_remove(addr, len, type);

        if (res >= 0)

             put_packet(s, "OK");

        else if (res == -ENOSYS)

            put_packet(s, "");

        else

            put_packet(s, "E22");

        break;

    case 'H':

        type = *p++;

        thread = strtoull(p, (char **)&p, 16);

        if (thread == -1 || thread == 0) {

            put_packet(s, "OK");

            break;

        }

        for (env = first_cpu; env != NULL; env = env->next_cpu)

            if (env->cpu_index + 1 == thread)

                break;

        if (env == NULL) {

            put_packet(s, "E22");

            break;

        }

        switch (type) {

        case 'c':

            s->c_cpu = env;

            put_packet(s, "OK");

            break;

        case 'g':

            s->g_cpu = env;

            put_packet(s, "OK");

            break;

        default:

             put_packet(s, "E22");

             break;

        }

        break;

    case 'T':

        thread = strtoull(p, (char **)&p, 16);

#ifndef CONFIG_USER_ONLY

        if (thread > 0 && thread < smp_cpus + 1)

#else

        if (thread == 1)

#endif

             put_packet(s, "OK");

        else

            put_packet(s, "E22");

        break;

    case 'q':

    case 'Q':

        /* parse any 'q' packets here */

        if (!strcmp(p,"qemu.sstepbits")) {

            /* Query Breakpoint bit definitions */

            snprintf(buf, sizeof(buf), "ENABLE=%x,NOIRQ=%x,NOTIMER=%x",

                     SSTEP_ENABLE,

                     SSTEP_NOIRQ,

                     SSTEP_NOTIMER);

            put_packet(s, buf);

            break;

        } else if (strncmp(p,"qemu.sstep",10) == 0) {

            /* Display or change the sstep_flags */

            p += 10;

            if (*p != '=') {

                /* Display current setting */

                snprintf(buf, sizeof(buf), "0x%x", sstep_flags);

                put_packet(s, buf);

                break;

            }

            p++;

            type = strtoul(p, (char **)&p, 16);

            sstep_flags = type;

            put_packet(s, "OK");

            break;

        } else if (strcmp(p,"C") == 0) {

            /* "Current thread" remains vague in the spec, so always return

             *  the first CPU (gdb returns the first thread). */

            put_packet(s, "QC1");

            break;

        } else if (strcmp(p,"fThreadInfo") == 0) {

            s->query_cpu = first_cpu;

            goto report_cpuinfo;

        } else if (strcmp(p,"sThreadInfo") == 0) {

        report_cpuinfo:

            if (s->query_cpu) {

                snprintf(buf, sizeof(buf), "m%x", s->query_cpu->cpu_index+1);

                put_packet(s, buf);

                s->query_cpu = s->query_cpu->next_cpu;

            } else

                put_packet(s, "l");

            break;

        } else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {

            thread = strtoull(p+16, (char **)&p, 16);

            for (env = first_cpu; env != NULL; env = env->next_cpu)

                if (env->cpu_index + 1 == thread) {

                    len = snprintf((char *)mem_buf, sizeof(mem_buf),

                                   "CPU#%d [%s]", env->cpu_index,

                                   env->halted ? "halted " : "running");

                    memtohex(buf, mem_buf, len);

                    put_packet(s, buf);

                    break;

                }

            break;

        }

#ifdef CONFIG_LINUX_USER

        else if (strncmp(p, "Offsets", 7) == 0) {

            TaskState *ts = s->c_cpu->opaque;

            snprintf(buf, sizeof(buf),

                     "Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx

                     ";Bss=" TARGET_ABI_FMT_lx,

                     ts->info->code_offset,

                     ts->info->data_offset,

                     ts->info->data_offset);

            put_packet(s, buf);

            break;

        }

#endif

        if (strncmp(p, "Supported", 9) == 0) {

            snprintf(buf, sizeof(buf), "PacketSize=%x", MAX_PACKET_LENGTH);

#ifdef GDB_CORE_XML

            strcat(buf, ";qXfer:features:read+");

#endif

            put_packet(s, buf);

            break;

        }

#ifdef GDB_CORE_XML

        if (strncmp(p, "Xfer:features:read:", 19) == 0) {

            const char *xml;

            target_ulong total_len;

            gdb_has_xml = 1;

            p += 19;

            xml = get_feature_xml(p, &p);

            if (!xml) {

                snprintf(buf, sizeof(buf), "E00");

                put_packet(s, buf);

                break;

            }

            if (*p == ':')

                p++;

            addr = strtoul(p, (char **)&p, 16);

            if (*p == ',')

                p++;

            len = strtoul(p, (char **)&p, 16);

            total_len = strlen(xml);

            if (addr > total_len) {

                snprintf(buf, sizeof(buf), "E00");

                put_packet(s, buf);

                break;

            }

            if (len > (MAX_PACKET_LENGTH - 5) / 2)

                len = (MAX_PACKET_LENGTH - 5) / 2;

            if (len < total_len - addr) {

                buf[0] = 'm';

                len = memtox(buf + 1, xml + addr, len);

            } else {

                buf[0] = 'l';

                len = memtox(buf + 1, xml + addr, total_len - addr);

            }

            put_packet_binary(s, buf, len + 1);

            break;

        }

#endif

        /* Unrecognised 'q' command.  */

        goto unknown_command;

    default:

    unknown_command:

        /* put empty packet */

        buf[0] = '\0';

        put_packet(s, buf);

        break;

    }

    return RS_IDLE;

}


static void s390_memory_init(ram_addr_t mem_size)

{

    MemoryRegion *sysmem = get_system_memory();

    MemoryRegion *ram = g_new(MemoryRegion, 1);

    /* allocate RAM for core */

    memory_region_allocate_system_memory(ram, NULL, "s390.ram", mem_size);

    memory_region_add_subregion(sysmem, 0, ram);

    /* Initialize storage key device */

    s390_skeys_init();

    /* Initialize storage attributes device */

    s390_stattrib_init();

}


static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){

    AVIContext *avi = s->priv_data;

    AVIOContext *pb = s->pb;

    int longs_pre_entry= avio_rl16(pb);

    int index_sub_type = avio_r8(pb);

    int index_type     = avio_r8(pb);

    int entries_in_use = avio_rl32(pb);

    int chunk_id       = avio_rl32(pb);

    int64_t base       = avio_rl64(pb);

    int stream_id= 10*((chunk_id&0xFF) - '0') + (((chunk_id>>8)&0xFF) - '0');

    AVStream *st;

    AVIStream *ast;

    int i;

    int64_t last_pos= -1;

    int64_t filesize= avio_size(s->pb);

    av_dlog(s, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n",

            longs_pre_entry,index_type, entries_in_use, chunk_id, base);

    if(stream_id >= s->nb_streams || stream_id < 0)

        return -1;

    st= s->streams[stream_id];

    ast = st->priv_data;

    if(index_sub_type)

        return -1;

    avio_rl32(pb);

    if(index_type && longs_pre_entry != 2)

        return -1;

    if(index_type>1)

        return -1;

    if(filesize > 0 && base >= filesize){

        av_log(s, AV_LOG_ERROR, "ODML index invalid\n");

        if(base>>32 == (base & 0xFFFFFFFF) && (base & 0xFFFFFFFF) < filesize && filesize <= 0xFFFFFFFF)

            base &= 0xFFFFFFFF;

        else

            return -1;

    }

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

        if(index_type){

            int64_t pos= avio_rl32(pb) + base - 8;

            int len    = avio_rl32(pb);

            int key= len >= 0;

            len &= 0x7FFFFFFF;

            av_dlog(s, "pos:%"PRId64", len:%X\n", pos, len);

            if(pb->eof_reached)

                return -1;

            if(last_pos == pos || pos == base - 8)

                avi->non_interleaved= 1;

            if(last_pos != pos && (len || !ast->sample_size))

                av_add_index_entry(st, pos, ast->cum_len, len, 0, key ? AVINDEX_KEYFRAME : 0);

            ast->cum_len += get_duration(ast, len);

            last_pos= pos;

        }else{

            int64_t offset, pos;

            int duration;

            offset = avio_rl64(pb);

            avio_rl32(pb);       /* size */

            duration = avio_rl32(pb);

            if(pb->eof_reached)

                return -1;

            pos = avio_tell(pb);

            if(avi->odml_depth > MAX_ODML_DEPTH){

                av_log(s, AV_LOG_ERROR, "Too deeply nested ODML indexes\n");

                return -1;

            }

            avio_seek(pb, offset+8, SEEK_SET);

            avi->odml_depth++;

            read_braindead_odml_indx(s, frame_num);

            avi->odml_depth--;

            frame_num += duration;

            avio_seek(pb, pos, SEEK_SET);

        }

    }

    avi->index_loaded=1;

    return 0;

}


static void qapi_dealloc_start_list(Visitor *v, const char *name, Error **errp)

{

    QapiDeallocVisitor *qov = to_qov(v);

    qapi_dealloc_push(qov, NULL);

}


int event_notifier_set_handler(EventNotifier *e,

                               EventNotifierHandler *handler)

{

    return qemu_set_fd_handler(e->fd, (IOHandler *)handler, NULL, e);

}


static ObjectClass *alpha_cpu_class_by_name(const char *cpu_model)

{

    ObjectClass *oc = NULL;

    char *typename;

    int i;

    if (cpu_model == NULL) {

        return NULL;

    }

    oc = object_class_by_name(cpu_model);

    if (oc != NULL && object_class_dynamic_cast(oc, TYPE_ALPHA_CPU) != NULL &&

        !object_class_is_abstract(oc)) {

        return oc;

    }

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

        if (strcmp(cpu_model, alpha_cpu_aliases[i].alias) == 0) {

            oc = object_class_by_name(alpha_cpu_aliases[i].typename);

            assert(oc != NULL && !object_class_is_abstract(oc));

            return oc;

        }

    }

    typename = g_strdup_printf("%s-" TYPE_ALPHA_CPU, cpu_model);

    oc = object_class_by_name(typename);

    g_free(typename);

    if (oc != NULL && object_class_is_abstract(oc)) {

        oc = NULL;

    }

    return oc;

}


void qmp_migrate(const char *uri, bool has_blk, bool blk,

                 bool has_inc, bool inc, bool has_detach, bool detach,

                 Error **errp)

{

    Error *local_err = NULL;

    MigrationState *s = migrate_get_current();

    MigrationParams params;

    const char *p;

    params.blk = has_blk && blk;

    params.shared = has_inc && inc;

    if (migration_is_setup_or_active(s->state) ||

        s->state == MIGRATION_STATUS_CANCELLING) {

        error_setg(errp, QERR_MIGRATION_ACTIVE);

        return;

    }

    if (runstate_check(RUN_STATE_INMIGRATE)) {

        error_setg(errp, "Guest is waiting for an incoming migration");

        return;

    }

    if (migration_is_blocked(errp)) {

        return;

    }

    s = migrate_init(&params);

    if (strstart(uri, "tcp:", &p)) {

        tcp_start_outgoing_migration(s, p, &local_err);

#ifdef CONFIG_RDMA

    } else if (strstart(uri, "rdma:", &p)) {

        rdma_start_outgoing_migration(s, p, &local_err);

#endif

    } else if (strstart(uri, "exec:", &p)) {

        exec_start_outgoing_migration(s, p, &local_err);

    } else if (strstart(uri, "unix:", &p)) {

        unix_start_outgoing_migration(s, p, &local_err);

    } else if (strstart(uri, "fd:", &p)) {

        fd_start_outgoing_migration(s, p, &local_err);

    } else {

        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "uri",

                   "a valid migration protocol");

        migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,

                          MIGRATION_STATUS_FAILED);

        return;

    }

    if (local_err) {

        migrate_fd_error(s, local_err);

        error_propagate(errp, local_err);

        return;

    }

}


static void imx_avic_write(void *opaque, target_phys_addr_t offset,

                          uint64_t val, unsigned size)

{

    IMXAVICState *s = (IMXAVICState *)opaque;

    /* Vector Registers not yet supported */

    if (offset >= 0x100 && offset <= 0x2fc) {

        IPRINTF("imx_avic_write to vector register %d ignored\n",

                (unsigned int)((offset - 0x100) >> 2));

        return;

    }

    DPRINTF("imx_avic_write(0x%x) = %x\n",

            (unsigned int)offset>>2, (unsigned int)val);

    switch (offset >> 2) {

    case 0: /* Interrupt Control Register, INTCNTL */

        s->intcntl = val & (ABFEN | NIDIS | FIDIS | NIAD | FIAD | NM);

        if (s->intcntl & ABFEN) {

            s->intcntl &= ~(val & ABFLAG);

        }

        break;

    case 1: /* Normal Interrupt Mask Register, NIMASK */

        s->intmask = val & 0x1f;

        break;

    case 2: /* Interrupt Enable Number Register, INTENNUM */

        DPRINTF("enable(%d)\n", (int)val);

        val &= 0x3f;

        s->enabled |= (1ULL << val);

        break;

    case 3: /* Interrupt Disable Number Register, INTDISNUM */

        DPRINTF("disable(%d)\n", (int)val);

        val &= 0x3f;

        s->enabled &= ~(1ULL << val);

        break;

    case 4: /* Interrupt Enable Number Register High */

        s->enabled = (s->enabled & 0xffffffffULL) | (val << 32);

        break;

    case 5: /* Interrupt Enable Number Register Low */

        s->enabled = (s->enabled & 0xffffffff00000000ULL) | val;

        break;

    case 6: /* Interrupt Type Register High */

        s->is_fiq = (s->is_fiq & 0xffffffffULL) | (val << 32);

        break;

    case 7: /* Interrupt Type Register Low */

        s->is_fiq = (s->is_fiq & 0xffffffff00000000ULL) | val;

        break;

    case 8: /* Normal Interrupt Priority Register 7 */

    case 9: /* Normal Interrupt Priority Register 6 */

    case 10:/* Normal Interrupt Priority Register 5 */

    case 11:/* Normal Interrupt Priority Register 4 */

    case 12:/* Normal Interrupt Priority Register 3 */

    case 13:/* Normal Interrupt Priority Register 2 */

    case 14:/* Normal Interrupt Priority Register 1 */

    case 15:/* Normal Interrupt Priority Register 0 */

        s->prio[15-(offset>>2)] = val;

        break;

        /* Read-only registers, writes ignored */

    case 16:/* Normal Interrupt Vector and Status register */

    case 17:/* Fast Interrupt vector and status register */

    case 18:/* Interrupt source register high */

    case 19:/* Interrupt source register low */

        return;

    case 20:/* Interrupt Force Register high */

        s->pending = (s->pending & 0xffffffffULL) | (val << 32);

        break;

    case 21:/* Interrupt Force Register low */

        s->pending = (s->pending & 0xffffffff00000000ULL) | val;

        break;

    case 22:/* Normal Interrupt Pending Register High */

    case 23:/* Normal Interrupt Pending Register Low */

    case 24: /* Fast Interrupt Pending Register High  */

    case 25: /* Fast Interrupt Pending Register Low  */

        return;

    default:

        IPRINTF("imx_avic_write: Bad offset %x\n", (int)offset);

    }

    imx_avic_update(s);

}


QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exists)

{

    QemuOpts *opts = NULL;

    if (id) {

        opts = qemu_opts_find(list, id);

        if (opts != NULL) {

            if (fail_if_exists) {

                fprintf(stderr, "tried to create id \"%s\" twice for \"%s\"\n",

                        id, list->name);

                return NULL;

            } else {

                return opts;

            }

        }

    }

    opts = qemu_mallocz(sizeof(*opts));

    if (id) {

        opts->id = qemu_strdup(id);

    }

    opts->list = list;

    TAILQ_INIT(&opts->head);

    TAILQ_INSERT_TAIL(&list->head, opts, next);

    return opts;

}


static void tco_timer_expired(void *opaque)

{

    TCOIORegs *tr = opaque;

    ICH9LPCPMRegs *pm = container_of(tr, ICH9LPCPMRegs, tco_regs);

    ICH9LPCState *lpc = container_of(pm, ICH9LPCState, pm);

    uint32_t gcs = pci_get_long(lpc->chip_config + ICH9_CC_GCS);

    tr->tco.rld = 0;

    tr->tco.sts1 |= TCO_TIMEOUT;

    if (++tr->timeouts_no == 2) {

        tr->tco.sts2 |= TCO_SECOND_TO_STS;

        tr->tco.sts2 |= TCO_BOOT_STS;

        tr->timeouts_no = 0;

        if (!(gcs & ICH9_CC_GCS_NO_REBOOT)) {

            watchdog_perform_action();

            tco_timer_stop(tr);

            return;

        }

    }

    if (pm->smi_en & ICH9_PMIO_SMI_EN_TCO_EN) {

        ich9_generate_smi();

    } else {

        ich9_generate_nmi();

    }

    tr->tco.rld = tr->tco.tmr;

    tco_timer_reload(tr);

}


static void access_with_adjusted_size(hwaddr addr,

                                      uint64_t *value,

                                      unsigned size,

                                      unsigned access_size_min,

                                      unsigned access_size_max,

                                      void (*access)(MemoryRegion *mr,

                                                     hwaddr addr,

                                                     uint64_t *value,

                                                     unsigned size,

                                                     unsigned shift,

                                                     uint64_t mask),

                                      MemoryRegion *mr)

{

    uint64_t access_mask;

    unsigned access_size;

    unsigned i;

    if (!access_size_min) {

        access_size_min = 1;

    }

    if (!access_size_max) {

        access_size_max = 4;

    }

    /* FIXME: support unaligned access? */

    access_size = MAX(MIN(size, access_size_max), access_size_min);

    access_mask = -1ULL >> (64 - access_size * 8);

    for (i = 0; i < size; i += access_size) {

#ifdef TARGET_WORDS_BIGENDIAN

        access(mr, addr + i, value, access_size,

               (size - access_size - i) * 8, access_mask);

#else

        access(mr, addr + i, value, access_size, i * 8, access_mask);

#endif

    }

}


static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)

{

    SCSIRequest *req = &r->req;

    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);

    uint32_t nb_sectors = scsi_data_cdb_length(r->req.cmd.buf);

    WriteSameCBData *data;

    uint8_t *buf;

    int i;

    /* Fail if PBDATA=1 or LBDATA=1 or ANCHOR=1.  */

    if (nb_sectors == 0 || (req->cmd.buf[1] & 0x16)) {

        scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));

        return;

    }

    if (bdrv_is_read_only(s->qdev.conf.bs)) {

        scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));

        return;

    }

    if (!check_lba_range(s, r->req.cmd.lba, nb_sectors)) {

        scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));

        return;

    }

    if (buffer_is_zero(inbuf, s->qdev.blocksize)) {

        int flags = (req->cmd.buf[1] & 0x8) ? BDRV_REQ_MAY_UNMAP : 0;

        /* The request is used as the AIO opaque value, so add a ref.  */

        scsi_req_ref(&r->req);

        block_acct_start(bdrv_get_stats(s->qdev.conf.bs), &r->acct,

                         nb_sectors * s->qdev.blocksize,

                        BLOCK_ACCT_WRITE);

        r->req.aiocb = bdrv_aio_write_zeroes(s->qdev.conf.bs,

                                             r->req.cmd.lba * (s->qdev.blocksize / 512),

                                             nb_sectors * (s->qdev.blocksize / 512),

                                             flags, scsi_aio_complete, r);

        return;

    }

    data = g_new0(WriteSameCBData, 1);

    data->r = r;

    data->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);

    data->nb_sectors = nb_sectors * (s->qdev.blocksize / 512);

    data->iov.iov_len = MIN(data->nb_sectors * 512, SCSI_WRITE_SAME_MAX);

    data->iov.iov_base = buf = qemu_blockalign(s->qdev.conf.bs, data->iov.iov_len);

    qemu_iovec_init_external(&data->qiov, &data->iov, 1);

    for (i = 0; i < data->iov.iov_len; i += s->qdev.blocksize) {

        memcpy(&buf[i], inbuf, s->qdev.blocksize);

    }

    scsi_req_ref(&r->req);

    block_acct_start(bdrv_get_stats(s->qdev.conf.bs), &r->acct,

                     data->iov.iov_len, BLOCK_ACCT_WRITE);

    r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, data->sector,

                                   &data->qiov, data->iov.iov_len / 512,

                                   scsi_write_same_complete, data);

}


static int kvm_put_msr_feature_control(X86CPU *cpu)

{

    struct {

        struct kvm_msrs info;

        struct kvm_msr_entry entry;

    } msr_data;

    kvm_msr_entry_set(&msr_data.entry, MSR_IA32_FEATURE_CONTROL,

                      cpu->env.msr_ia32_feature_control);

    msr_data.info.nmsrs = 1;

    return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data);

}


static void ppc_prep_init (int ram_size, int vga_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 = NULL, *envs[MAX_CPUS];

    char buf[1024];

    nvram_t nvram;

    m48t59_t *m48t59;

    int PPC_io_memory;

    int linux_boot, i, nb_nics1, bios_size;

    unsigned long bios_offset;

    uint32_t kernel_base, kernel_size, initrd_base, initrd_size;

    PCIBus *pci_bus;

    qemu_irq *i8259;

    int ppc_boot_device;

    sysctrl = qemu_mallocz(sizeof(sysctrl_t));

    if (sysctrl == NULL)

        return;

    linux_boot = (kernel_filename != NULL);

    /* init CPUs */

    if (cpu_model == NULL)

        cpu_model = "default";

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

        env = cpu_init(cpu_model);

        if (!env) {

            fprintf(stderr, "Unable to find PowerPC CPU definition\n");

            exit(1);

        }

        /* Set time-base frequency to 100 Mhz */

        cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);

        qemu_register_reset(&cpu_ppc_reset, env);

        register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);

        envs[i] = env;

    }

    /* allocate RAM */

    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);

    /* allocate and load BIOS */

    bios_offset = ram_size + vga_ram_size;

    if (bios_name == NULL)

        bios_name = BIOS_FILENAME;

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

    bios_size = load_image(buf, phys_ram_base + bios_offset);

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

        cpu_abort(env, "qemu: could not load PPC PREP bios '%s'\n", buf);

        exit(1);

    }

    if (env->nip < 0xFFF80000 && bios_size < 0x00100000) {

        cpu_abort(env, "PowerPC 601 / 620 / 970 need a 1MB BIOS\n");

    }

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

    cpu_register_physical_memory((uint32_t)(-bios_size),

                                 bios_size, bios_offset | IO_MEM_ROM);

    if (linux_boot) {

        kernel_base = KERNEL_LOAD_ADDR;

        /* now we can load the kernel */

        kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);

        if (kernel_size < 0) {

            cpu_abort(env, "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(initrd_filename,

                                     phys_ram_base + initrd_base);

            if (initrd_size < 0) {

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

                          initrd_filename);

                exit(1);

            }

        } else {

            initrd_base = 0;

            initrd_size = 0;

        }

        ppc_boot_device = 'm';

    } else {

        kernel_base = 0;

        kernel_size = 0;

        initrd_base = 0;

        initrd_size = 0;

        ppc_boot_device = '\0';

        /* For now, OHW cannot boot from the network. */

        for (i = 0; boot_device[i] != '\0'; i++) {

            if (boot_device[i] >= 'a' && boot_device[i] <= 'f') {

                ppc_boot_device = boot_device[i];

                break;

            }

        }

        if (ppc_boot_device == '\0') {

            fprintf(stderr, "No valid boot device for Mac99 machine\n");

            exit(1);

        }

    }

    isa_mem_base = 0xc0000000;

    if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {

        cpu_abort(env, "Only 6xx bus is supported on PREP machine\n");

        exit(1);

    }

    i8259 = i8259_init(first_cpu->irq_inputs[PPC6xx_INPUT_INT]);

    pci_bus = pci_prep_init(i8259);

    //    pci_bus = i440fx_init();

    /* Register 8 MB of ISA IO space (needed for non-contiguous map) */

    PPC_io_memory = cpu_register_io_memory(0, PPC_prep_io_read,

                                           PPC_prep_io_write, sysctrl);

    cpu_register_physical_memory(0x80000000, 0x00800000, PPC_io_memory);

    /* init basic PC hardware */

    pci_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size,

                 vga_ram_size, 0, 0);

    //    openpic = openpic_init(0x00000000, 0xF0000000, 1);

    //    pit = pit_init(0x40, i8259[0]);

    rtc_init(0x70, i8259[8]);

    serial_init(0x3f8, i8259[4], serial_hds[0]);

    nb_nics1 = nb_nics;

    if (nb_nics1 > NE2000_NB_MAX)

        nb_nics1 = NE2000_NB_MAX;

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

        if (nd_table[i].model == NULL

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

            isa_ne2000_init(ne2000_io[i], i8259[ne2000_irq[i]], &nd_table[i]);

        } else {

            pci_nic_init(pci_bus, &nd_table[i], -1);

        }

    }

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

        isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]],

                     bs_table[2 * i], bs_table[2 * i + 1]);

    }

    i8042_init(i8259[1], i8259[12], 0x60);

    DMA_init(1);

    //    AUD_init();

    //    SB16_init();

    fdctrl_init(i8259[6], 2, 0, 0x3f0, fd_table);

    /* Register speaker port */

    register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);

    register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);

    /* Register fake IO ports for PREP */

    sysctrl->reset_irq = first_cpu->irq_inputs[PPC6xx_INPUT_HRESET];

    register_ioport_read(0x398, 2, 1, &PREP_io_read, sysctrl);

    register_ioport_write(0x398, 2, 1, &PREP_io_write, sysctrl);

    /* System control ports */

    register_ioport_read(0x0092, 0x01, 1, &PREP_io_800_readb, sysctrl);

    register_ioport_write(0x0092, 0x01, 1, &PREP_io_800_writeb, sysctrl);

    register_ioport_read(0x0800, 0x52, 1, &PREP_io_800_readb, sysctrl);

    register_ioport_write(0x0800, 0x52, 1, &PREP_io_800_writeb, sysctrl);

    /* PCI intack location */

    PPC_io_memory = cpu_register_io_memory(0, PPC_intack_read,

                                           PPC_intack_write, NULL);

    cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory);

    /* PowerPC control and status register group */

#if 0

    PPC_io_memory = cpu_register_io_memory(0, PPC_XCSR_read, PPC_XCSR_write,

                                           NULL);

    cpu_register_physical_memory(0xFEFF0000, 0x1000, PPC_io_memory);

#endif

    if (usb_enabled) {

        usb_ohci_init_pci(pci_bus, 3, -1);

    }

    m48t59 = m48t59_init(i8259[8], 0, 0x0074, NVRAM_SIZE, 59);

    if (m48t59 == NULL)

        return;

    sysctrl->nvram = m48t59;

    /* Initialise NVRAM */

    nvram.opaque = m48t59;

    nvram.read_fn = &m48t59_read;

    nvram.write_fn = &m48t59_write;

    PPC_NVRAM_set_params(&nvram, NVRAM_SIZE, "PREP", ram_size, ppc_boot_device,

                         kernel_base, kernel_size,

                         kernel_cmdline,

                         initrd_base, initrd_size,

                         /* XXX: need an option to load a NVRAM image */

                         0,

                         graphic_width, graphic_height, graphic_depth);

    /* Special port to get debug messages from Open-Firmware */

    register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL);

}


static void mpeg1_skip_picture(MpegEncContext *s, int pict_num)

{

    assert(s->codec_id == CODEC_ID_MPEG1VIDEO); // mpeg2 can do these repeat things

    /* mpeg1 picture header */

    put_header(s, PICTURE_START_CODE);

    /* temporal reference */

    put_bits(&s->pb, 10, pict_num & 0x3ff);

    put_bits(&s->pb, 3, P_TYPE);

    put_bits(&s->pb, 16, 0xffff); /* non constant bit rate */

    put_bits(&s->pb, 1, 1); /* integer coordinates */

    put_bits(&s->pb, 3, 1); /* forward_f_code */

    put_bits(&s->pb, 1, 0); /* extra bit picture */

    /* only one slice */

    put_header(s, SLICE_MIN_START_CODE);

    put_bits(&s->pb, 5, 1); /* quantizer scale */

    put_bits(&s->pb, 1, 0); /* slice extra information */

    encode_mb_skip_run(s, 0);

    /* empty macroblock */

    put_bits(&s->pb, 3, 1); /* motion only */

    /* zero motion x & y */

    put_bits(&s->pb, 1, 1);

    put_bits(&s->pb, 1, 1);

    /* output a number of empty slice */

    encode_mb_skip_run(s, s->mb_width * s->mb_height - 2);

    /* empty macroblock */

    put_bits(&s->pb, 3, 1); /* motion only */

    /* zero motion x & y */

    put_bits(&s->pb, 1, 1);

    put_bits(&s->pb, 1, 1);

}


static int ehci_process_itd(EHCIState *ehci,

                            EHCIitd *itd,

                            uint32_t addr)

{

    USBDevice *dev;

    USBEndpoint *ep;

    uint32_t i, len, pid, dir, devaddr, endp;

    uint32_t pg, off, ptr1, ptr2, max, mult;

    ehci->periodic_sched_active = PERIODIC_ACTIVE;

    dir =(itd->bufptr[1] & ITD_BUFPTR_DIRECTION);

    devaddr = get_field(itd->bufptr[0], ITD_BUFPTR_DEVADDR);

    endp = get_field(itd->bufptr[0], ITD_BUFPTR_EP);

    max = get_field(itd->bufptr[1], ITD_BUFPTR_MAXPKT);

    mult = get_field(itd->bufptr[2], ITD_BUFPTR_MULT);

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

        if (itd->transact[i] & ITD_XACT_ACTIVE) {

            pg   = get_field(itd->transact[i], ITD_XACT_PGSEL);

            off  = itd->transact[i] & ITD_XACT_OFFSET_MASK;

            ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);

            ptr2 = (itd->bufptr[pg+1] & ITD_BUFPTR_MASK);

            len  = get_field(itd->transact[i], ITD_XACT_LENGTH);

            if (len > max * mult) {

                len = max * mult;

            }

            if (len > BUFF_SIZE) {

                return -1;

            }

            qemu_sglist_init(&ehci->isgl, DEVICE(ehci), 2, ehci->as);

            if (off + len > 4096) {

                /* transfer crosses page border */

                uint32_t len2 = off + len - 4096;

                uint32_t len1 = len - len2;

                qemu_sglist_add(&ehci->isgl, ptr1 + off, len1);

                qemu_sglist_add(&ehci->isgl, ptr2, len2);

            } else {

                qemu_sglist_add(&ehci->isgl, ptr1 + off, len);

            }

            pid = dir ? USB_TOKEN_IN : USB_TOKEN_OUT;

            dev = ehci_find_device(ehci, devaddr);

            ep = usb_ep_get(dev, pid, endp);

            if (ep && ep->type == USB_ENDPOINT_XFER_ISOC) {

                usb_packet_setup(&ehci->ipacket, pid, ep, 0, addr, false,

                                 (itd->transact[i] & ITD_XACT_IOC) != 0);

                usb_packet_map(&ehci->ipacket, &ehci->isgl);

                usb_handle_packet(dev, &ehci->ipacket);

                usb_packet_unmap(&ehci->ipacket, &ehci->isgl);

            } else {

                DPRINTF("ISOCH: attempt to addess non-iso endpoint\n");

                ehci->ipacket.status = USB_RET_NAK;

                ehci->ipacket.actual_length = 0;

            }

            qemu_sglist_destroy(&ehci->isgl);

            switch (ehci->ipacket.status) {

            case USB_RET_SUCCESS:

                break;

            default:

                fprintf(stderr, "Unexpected iso usb result: %d\n",

                        ehci->ipacket.status);

                /* Fall through */

            case USB_RET_IOERROR:

            case USB_RET_NODEV:

                /* 3.3.2: XACTERR is only allowed on IN transactions */

                if (dir) {

                    itd->transact[i] |= ITD_XACT_XACTERR;

                    ehci_raise_irq(ehci, USBSTS_ERRINT);

                }

                break;

            case USB_RET_BABBLE:

                itd->transact[i] |= ITD_XACT_BABBLE;

                ehci_raise_irq(ehci, USBSTS_ERRINT);

                break;

            case USB_RET_NAK:

                /* no data for us, so do a zero-length transfer */

                ehci->ipacket.actual_length = 0;

                break;

            }

            if (!dir) {

                set_field(&itd->transact[i], len - ehci->ipacket.actual_length,

                          ITD_XACT_LENGTH); /* OUT */

            } else {

                set_field(&itd->transact[i], ehci->ipacket.actual_length,

                          ITD_XACT_LENGTH); /* IN */

            }

            if (itd->transact[i] & ITD_XACT_IOC) {

                ehci_raise_irq(ehci, USBSTS_INT);

            }

            itd->transact[i] &= ~ITD_XACT_ACTIVE;

        }

    }

    return 0;

}


uint64_t helper_fctid (uint64_t arg)

{

    CPU_DoubleU farg;

    farg.ll = arg;

    if (unlikely(float64_is_signaling_nan(farg.d))) {

        /* sNaN conversion */

        farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI);

    } else if (unlikely(float64_is_nan(farg.d) || float64_is_infinity(farg.d))) {

        /* qNan / infinity conversion */

        farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);

    } else {

        farg.ll = float64_to_int64(farg.d, &env->fp_status);

    }

    return farg.ll;

}


static void pc_q35_init(MachineState *machine)

{

    PCMachineState *pcms = PC_MACHINE(machine);

    Q35PCIHost *q35_host;

    PCIHostState *phb;

    PCIBus *host_bus;

    PCIDevice *lpc;

    BusState *idebus[MAX_SATA_PORTS];

    ISADevice *rtc_state;

    MemoryRegion *pci_memory;

    MemoryRegion *rom_memory;

    MemoryRegion *ram_memory;

    GSIState *gsi_state;

    ISABus *isa_bus;

    int pci_enabled = 1;

    qemu_irq *gsi;

    qemu_irq *i8259;

    int i;

    ICH9LPCState *ich9_lpc;

    PCIDevice *ahci;

    DeviceState *icc_bridge;

    PcGuestInfo *guest_info;

    ram_addr_t lowmem;

    DriveInfo *hd[MAX_SATA_PORTS];

    MachineClass *mc = MACHINE_GET_CLASS(machine);

    /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory

     * and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping

     * also known as MMCFG).

     * If it doesn't, we need to split it in chunks below and above 4G.

     * In any case, try to make sure that guest addresses aligned at

     * 1G boundaries get mapped to host addresses aligned at 1G boundaries.

     * For old machine types, use whatever split we used historically to avoid

     * breaking migration.

     */

    if (machine->ram_size >= 0xb0000000) {

        lowmem = gigabyte_align ? 0x80000000 : 0xb0000000;

    } else {

        lowmem = 0xb0000000;

    }

    /* Handle the machine opt max-ram-below-4g.  It is basically doing

     * min(qemu limit, user limit).

     */

    if (lowmem > pcms->max_ram_below_4g) {

        lowmem = pcms->max_ram_below_4g;

        if (machine->ram_size - lowmem > lowmem &&

            lowmem & ((1ULL << 30) - 1)) {

            error_report("Warning: Large machine and max_ram_below_4g(%"PRIu64

                         ") not a multiple of 1G; possible bad performance.",

                         pcms->max_ram_below_4g);

        }

    }

    if (machine->ram_size >= lowmem) {

        pcms->above_4g_mem_size = machine->ram_size - lowmem;

        pcms->below_4g_mem_size = lowmem;

    } else {

        pcms->above_4g_mem_size = 0;

        pcms->below_4g_mem_size = machine->ram_size;

    }

    if (xen_enabled() && xen_hvm_init(pcms, &ram_memory) != 0) {

        fprintf(stderr, "xen hardware virtual machine initialisation failed\n");

        exit(1);

    }

    icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE);

    object_property_add_child(qdev_get_machine(), "icc-bridge",

                              OBJECT(icc_bridge), NULL);

    pc_cpus_init(machine->cpu_model, icc_bridge);

    pc_acpi_init("q35-acpi-dsdt.aml");

    kvmclock_create();

    /* pci enabled */

    if (pci_enabled) {

        pci_memory = g_new(MemoryRegion, 1);

        memory_region_init(pci_memory, NULL, "pci", UINT64_MAX);

        rom_memory = pci_memory;

    } else {

        pci_memory = NULL;

        rom_memory = get_system_memory();

    }

    guest_info = pc_guest_info_init(pcms);

    guest_info->isapc_ram_fw = false;

    guest_info->has_acpi_build = has_acpi_build;

    guest_info->has_reserved_memory = has_reserved_memory;

    guest_info->rsdp_in_ram = rsdp_in_ram;

    /* Migration was not supported in 2.0 for Q35, so do not bother

     * with this hack (see hw/i386/acpi-build.c).

     */

    guest_info->legacy_acpi_table_size = 0;

    if (smbios_defaults) {

        /* These values are guest ABI, do not change */

        smbios_set_defaults("QEMU", "Standard PC (Q35 + ICH9, 2009)",

                            mc->name, smbios_legacy_mode, smbios_uuid_encoded,

                            SMBIOS_ENTRY_POINT_21);

    }

    /* allocate ram and load rom/bios */

    if (!xen_enabled()) {

        pc_memory_init(pcms, get_system_memory(),

                       rom_memory, &ram_memory, guest_info);

    }

    /* irq lines */

    gsi_state = g_malloc0(sizeof(*gsi_state));

    if (kvm_irqchip_in_kernel()) {

        kvm_pc_setup_irq_routing(pci_enabled);

        gsi = qemu_allocate_irqs(kvm_pc_gsi_handler, gsi_state,

                                 GSI_NUM_PINS);

    } else {

        gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);

    }

    /* create pci host bus */

    q35_host = Q35_HOST_DEVICE(qdev_create(NULL, TYPE_Q35_HOST_DEVICE));

    object_property_add_child(qdev_get_machine(), "q35", OBJECT(q35_host), NULL);

    q35_host->mch.ram_memory = ram_memory;

    q35_host->mch.pci_address_space = pci_memory;

    q35_host->mch.system_memory = get_system_memory();

    q35_host->mch.address_space_io = get_system_io();

    q35_host->mch.below_4g_mem_size = pcms->below_4g_mem_size;

    q35_host->mch.above_4g_mem_size = pcms->above_4g_mem_size;

    q35_host->mch.guest_info = guest_info;

    /* pci */

    qdev_init_nofail(DEVICE(q35_host));

    phb = PCI_HOST_BRIDGE(q35_host);

    host_bus = phb->bus;

    /* create ISA bus */

    lpc = pci_create_simple_multifunction(host_bus, PCI_DEVFN(ICH9_LPC_DEV,

                                          ICH9_LPC_FUNC), true,

                                          TYPE_ICH9_LPC_DEVICE);

    object_property_add_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,

                             TYPE_HOTPLUG_HANDLER,

                             (Object **)&pcms->acpi_dev,

                             object_property_allow_set_link,

                             OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);

    object_property_set_link(OBJECT(machine), OBJECT(lpc),

                             PC_MACHINE_ACPI_DEVICE_PROP, &error_abort);

    ich9_lpc = ICH9_LPC_DEVICE(lpc);

    ich9_lpc->pic = gsi;

    ich9_lpc->ioapic = gsi_state->ioapic_irq;

    pci_bus_irqs(host_bus, ich9_lpc_set_irq, ich9_lpc_map_irq, ich9_lpc,

                 ICH9_LPC_NB_PIRQS);

    pci_bus_set_route_irq_fn(host_bus, ich9_route_intx_pin_to_irq);

    isa_bus = ich9_lpc->isa_bus;

    /*end early*/

    isa_bus_irqs(isa_bus, gsi);

    if (kvm_irqchip_in_kernel()) {

        i8259 = kvm_i8259_init(isa_bus);

    } else if (xen_enabled()) {

        i8259 = xen_interrupt_controller_init();

    } else {

        i8259 = i8259_init(isa_bus, pc_allocate_cpu_irq());

    }

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

        gsi_state->i8259_irq[i] = i8259[i];

    }

    if (pci_enabled) {

        ioapic_init_gsi(gsi_state, "q35");

    }

    qdev_init_nofail(icc_bridge);

    pc_register_ferr_irq(gsi[13]);

    assert(pcms->vmport != ON_OFF_AUTO_MAX);

    if (pcms->vmport == ON_OFF_AUTO_AUTO) {

        pcms->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON;

    }

    /* init basic PC hardware */

    pc_basic_device_init(isa_bus, gsi, &rtc_state, !mc->no_floppy,

                         (pcms->vmport != ON_OFF_AUTO_ON), 0xff0104);

    /* connect pm stuff to lpc */

    ich9_lpc_pm_init(lpc, pc_machine_is_smm_enabled(pcms), !mc->no_tco);

    /* ahci and SATA device, for q35 1 ahci controller is built-in */

    ahci = pci_create_simple_multifunction(host_bus,

                                           PCI_DEVFN(ICH9_SATA1_DEV,

                                                     ICH9_SATA1_FUNC),

                                           true, "ich9-ahci");

    idebus[0] = qdev_get_child_bus(&ahci->qdev, "ide.0");

    idebus[1] = qdev_get_child_bus(&ahci->qdev, "ide.1");

    g_assert(MAX_SATA_PORTS == ICH_AHCI(ahci)->ahci.ports);

    ide_drive_get(hd, ICH_AHCI(ahci)->ahci.ports);

    ahci_ide_create_devs(ahci, hd);

    if (usb_enabled()) {

        /* Should we create 6 UHCI according to ich9 spec? */

        ehci_create_ich9_with_companions(host_bus, 0x1d);

    }

    /* TODO: Populate SPD eeprom data.  */

    smbus_eeprom_init(ich9_smb_init(host_bus,

                                    PCI_DEVFN(ICH9_SMB_DEV, ICH9_SMB_FUNC),

                                    0xb100),

                      8, NULL, 0);

    pc_cmos_init(pcms, idebus[0], idebus[1], rtc_state);

    /* the rest devices to which pci devfn is automatically assigned */

    pc_vga_init(isa_bus, host_bus);

    pc_nic_init(isa_bus, host_bus);

    if (pci_enabled) {

        pc_pci_device_init(host_bus);

    }

}


static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr)

{

    M48t59State *NVRAM = opaque;

    uint32_t retval;

    retval = m48t59_read(NVRAM, addr) << 24;

    retval |= m48t59_read(NVRAM, addr + 1) << 16;

    retval |= m48t59_read(NVRAM, addr + 2) << 8;

    retval |= m48t59_read(NVRAM, addr + 3);

    return retval;

}


static void tcg_out_label(TCGContext *s, int label_index, tcg_insn_unit *ptr)

{

    TCGLabel *l = &s->labels[label_index];

    intptr_t value = (intptr_t)ptr;

    TCGRelocation *r;

    assert(!l->has_value);

    for (r = l->u.first_reloc; r != NULL; r = r->next) {

        patch_reloc(r->ptr, r->type, value, r->addend);

    }

    l->has_value = 1;

    l->u.value_ptr = ptr;

}


static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)

{

    CharDriverState *chr;

    MuxDriver *d;

    chr = g_malloc0(sizeof(CharDriverState));

    d = g_malloc0(sizeof(MuxDriver));

    chr->opaque = d;

    d->drv = drv;

    d->focus = -1;

    chr->chr_write = mux_chr_write;

    chr->chr_update_read_handler = mux_chr_update_read_handler;

    chr->chr_accept_input = mux_chr_accept_input;

    /* Frontend guest-open / -close notification is not support with muxes */

    chr->chr_set_fe_open = NULL;

    /* only default to opened state if we've realized the initial

     * set of muxes

     */

    chr->explicit_be_open = muxes_realized ? 0 : 1;

    chr->is_mux = 1;

    return chr;

}


static int xen_domain_watcher(void)

{

    int qemu_running = 1;

    int fd[2], i, n, rc;

    char byte;

    if (pipe(fd) != 0) {

        qemu_log("%s: Huh? pipe error: %s\n", __FUNCTION__, strerror(errno));

        return -1;

    }

    if (fork() != 0)

        return 0; /* not child */

    /* close all file handles, except stdio/out/err,

     * our watch pipe and the xen interface handle */

    n = getdtablesize();

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

        if (i == fd[0])

            continue;

        if (i == xen_xc)

            continue;

        close(i);

    }

    /* ignore term signals */

    signal(SIGINT,  SIG_IGN);

    signal(SIGTERM, SIG_IGN);

    /* wait for qemu exiting */

    while (qemu_running) {

        rc = read(fd[0], &byte, 1);

        switch (rc) {

        case -1:

            if (errno == EINTR)

                continue;

            qemu_log("%s: Huh? read error: %s\n", __FUNCTION__, strerror(errno));

            qemu_running = 0;

            break;

        case 0:

            /* EOF -> qemu exited */

            qemu_running = 0;

            break;

        default:

            qemu_log("%s: Huh? data on the watch pipe?\n", __FUNCTION__);

            break;

        }

    }

    /* cleanup */

    qemu_log("%s: destroy domain %d\n", __FUNCTION__, xen_domid);

    xc_domain_destroy(xen_xc, xen_domid);

    _exit(0);

}


static int vnc_update_client(VncState *vs, int has_dirty, bool sync)

{

    if (vs->need_update && vs->csock != -1) {

        VncDisplay *vd = vs->vd;

        VncJob *job;

        int y;

        int height;

        int n = 0;

        if (vs->output.offset && !vs->audio_cap && !vs->force_update)

            /* kernel send buffers are full -> drop frames to throttle */

            return 0;

        if (!has_dirty && !vs->audio_cap && !vs->force_update)

            return 0;

        /*

         * Send screen updates to the vnc client using the server

         * surface and server dirty map.  guest surface updates

         * happening in parallel don't disturb us, the next pass will

         * send them to the client.

         */

        job = vnc_job_new(vs);

        height = MIN(pixman_image_get_height(vd->server), vs->client_height);

        y = 0;

        for (;;) {

            int x, h;

            unsigned long x2;

            unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,

                                                 height * VNC_DIRTY_BPL(vs),

                                                 y * VNC_DIRTY_BPL(vs));

            if (offset == height * VNC_DIRTY_BPL(vs)) {

                /* no more dirty bits */

                break;

            }

            y = offset / VNC_DIRTY_BPL(vs);

            x = offset % VNC_DIRTY_BPL(vs);

            x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],

                                    VNC_DIRTY_BPL(vs), x);

            bitmap_clear(vs->dirty[y], x, x2 - x);

            h = find_and_clear_dirty_height(vs, y, x, x2, height);

            n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,

                                  (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);

        }

        vnc_job_push(job);

        vs->force_update = 0;

        return n;

    }

    if (vs->csock == -1) {

        vnc_disconnect_finish(vs);

    } else if (sync) {

        vnc_jobs_join(vs);

    }

    return 0;

}


static int input_init(struct XenDevice *xendev)

{

    struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);

    if (!in->c.ds) {

        xen_be_printf(xendev, 1, "ds not set (yet)\n");

	return -1;

    }

    xenstore_write_be_int(xendev, "feature-abs-pointer", 1);

    return 0;

}


static int start_auth_vnc(VncState *vs)

{

    make_challenge(vs);

    /* Send client a 'random' challenge */

    vnc_write(vs, vs->challenge, sizeof(vs->challenge));

    vnc_flush(vs);

    vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));

    return 0;

}


static void io_region_del(MemoryListener *listener,

                          MemoryRegionSection *section)

{

    isa_unassign_ioport(section->offset_within_address_space,

                        int128_get64(section->size));

}