static int ide_drive_initfn(IDEDevice *dev) { IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus); IDEState *s = bus->ifs + dev->unit; const char *serial; DriveInfo *dinfo; serial = dev->serial; if (!serial) { /* try to fall back to value set with legacy -drive serial=... */ dinfo = drive_get_by_blockdev(dev->conf.bs); if (*dinfo->serial) { serial = dinfo->serial; } } if (ide_init_drive(s, dev->conf.bs, dev->version, serial) < 0) { return -1; } if (!dev->version) { dev->version = qemu_strdup(s->version); } if (!dev->serial) { dev->serial = qemu_strdup(s->drive_serial_str); } add_boot_device_path(dev->conf.bootindex, &dev->qdev, dev->unit ? "/disk@1" : "/disk@0"); return 0; }
void qdev_add_property_string(QEMUDeviceClass *dc, const char *name, const char *def) { QEMUDeviceProperty *p = qemu_mallocz(sizeof(*p)); p->name = qemu_strdup(name); p->type = QDEV_PROP_STRING; if (def) p->value.string = qemu_strdup(def); p->next = dc->properties; dc->properties = p; }
static void find_properties(QEMUDevice *dev) { const struct fdt_property *p; QEMUDeviceProperty *dp; int len; for (dp = dev->properties; dp; dp = dp->next) { p = fdt_get_property(dev->dt, dev->node_offset, dp->name, &len); if (!p) continue; switch (dp->type) { case QDEV_PROP_INT: if (len != 4) { invalid_devtree(dev, "Bad integer property"); break; } dp->value.i = fdt32_to_cpu(*(uint32_t *)p->data); break; case QDEV_PROP_STRING: if (len == 0 || p->data[len - 1]) { invalid_devtree(dev, "Bad string property"); break; } if (dp->value.string) qemu_free(dp->value.string); dp->value.string = qemu_strdup((const char *)p->data); break; } } }
static QEMUDeviceProperty *qdev_copy_properties(QEMUDeviceProperty *src) { QEMUDeviceProperty *first; QEMUDeviceProperty **p; QEMUDeviceProperty *dest; first = NULL; p = &first; while (src) { dest = qemu_mallocz(sizeof(*dest)); dest->name = src->name; dest->type = src->type; switch (src->type) { case QDEV_PROP_INT: dest->value.i = src->value.i; break; case QDEV_PROP_STRING: if (src->value.string) dest->value.string = qemu_strdup(src->value.string); break; } src = src->next; *p = dest; p = &dest->next; } return first; }
static int vnc_auth_sasl_check_access(VncState *vs) { const void *val; int err; int allow; err = sasl_getprop(vs->sasl.conn, SASL_USERNAME, &val); if (err != SASL_OK) { VNC_DEBUG("cannot query SASL username on connection %d (%s), denying access\n", err, sasl_errstring(err, NULL, NULL)); return -1; } if (val == NULL) { VNC_DEBUG("no client username was found, denying access\n"); return -1; } VNC_DEBUG("SASL client username %s\n", (const char *)val); vs->sasl.username = qemu_strdup((const char*)val); if (vs->vd->sasl.acl == NULL) { VNC_DEBUG("no ACL activated, allowing access\n"); return 0; } allow = qemu_acl_party_is_allowed(vs->vd->sasl.acl, vs->sasl.username); VNC_DEBUG("SASL client %s %s by ACL\n", vs->sasl.username, allow ? "allowed" : "denied"); return allow ? 0 : -1; }
static int vmc_initfn(VirtIOSerialDevice *dev) { VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port); const char** psubtype = spice_server_char_device_recognized_subtypes(); const char *subtype = NULL; if (!using_spice) { return -1; } dprintf(svc, 1, "%s\n", __func__); if (svc->subtype == NULL) { svc->subtype = strdup("vdagent"); } for(;*psubtype != NULL; ++psubtype) { if (strcmp(svc->subtype, *psubtype) == 0) { subtype = *psubtype; break; } } if (subtype == NULL) { fprintf(stderr, "spice-vmc: unsupported subtype\n"); vmc_print_optional_subtypes(); return -1; } port->name = qemu_strdup(VMC_GUEST_DEVICE_NAME); svc->vmstate = qemu_add_vm_change_state_handler (vmc_change_state_handler, svc); svc->sin.subtype = svc->subtype; virtio_serial_open(port); return 0; }
void qdev_add_property_int(QEMUDeviceClass *dc, const char *name, int def) { QEMUDeviceProperty *p = qemu_mallocz(sizeof(*p)); p->name = qemu_strdup(name); p->type = QDEV_PROP_INT; p->value.i = def; p->next = dc->properties; dc->properties = p; }
void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init) { SysBusDeviceInfo *info; info = qemu_mallocz(sizeof(*info)); info->qdev.name = qemu_strdup(name); info->qdev.size = size; info->init = init; sysbus_register_withprop(info); }
static QDictEntry *alloc_entry(const char *key, QObject *value) { QDictEntry *entry; entry = qemu_mallocz(sizeof(*entry)); entry->key = qemu_strdup(key); entry->value = value; return entry; }
void configure_alarms(char const *opt) { int i; int cur = 0; int count = ARRAY_SIZE(alarm_timers) - 1; char *arg; char *name; struct qemu_alarm_timer tmp; if (!strcmp(opt, "?")) { show_available_alarms(); exit(0); } arg = qemu_strdup(opt); /* Reorder the array */ name = strtok(arg, ","); while (name) { for (i = 0; i < count && alarm_timers[i].name; i++) { if (!strcmp(alarm_timers[i].name, name)) break; } if (i == count) { fprintf(stderr, "Unknown clock %s\n", name); goto next; } if (i < cur) /* Ignore */ goto next; /* Swap */ tmp = alarm_timers[i]; alarm_timers[i] = alarm_timers[cur]; alarm_timers[cur] = tmp; cur++; next: name = strtok(NULL, ","); } qemu_free(arg); if (cur) { /* Disable remaining timers */ for (i = cur; i < count; i++) alarm_timers[i].name = NULL; } else { show_available_alarms(); exit(1); } }
QEMUDeviceClass *qdev_new(const char *name, QDEVCreateFn create, int nirq) { QEMUDeviceClass *dc = qemu_mallocz(sizeof(*dc)); dc->num_irqs = nirq; dc->create = create; dc->name = qemu_strdup(name); dc->next = all_dc; all_dc = dc; return dc; }
static void qmp_input_type_str(Visitor *v, char **obj, const char *name, Error **errp) { QmpInputVisitor *qiv = to_qiv(v); const QObject *qobj = qmp_input_get_object(qiv, name); if (!qobj || qobject_type(qobj) != QTYPE_QSTRING) { error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "string"); return; } *obj = qemu_strdup(qstring_get_str(qobject_to_qstring(qobj))); }
static int qemu_rbd_set_conf(rados_t cluster, const char *conf) { char *p, *buf; char name[RBD_MAX_CONF_NAME_SIZE]; char value[RBD_MAX_CONF_VAL_SIZE]; int ret = 0; buf = qemu_strdup(conf); p = buf; while (p) { ret = qemu_rbd_next_tok(name, sizeof(name), p, '=', "conf option name", &p); if (ret < 0) { break; } if (!p) { error_report("conf option %s has no value", name); ret = -EINVAL; break; } ret = qemu_rbd_next_tok(value, sizeof(value), p, ':', "conf option value", &p); if (ret < 0) { break; } if (strcmp(name, "conf")) { ret = rados_conf_set(cluster, name, value); if (ret < 0) { error_report("invalid conf option %s", name); ret = -EINVAL; break; } } else { ret = rados_conf_read_file(cluster, value); if (ret < 0) { error_report("error reading conf file %s", value); break; } } } qemu_free(buf); return ret; }
static int qemu_rbd_parsename(const char *filename, char *pool, int pool_len, char *snap, int snap_len, char *name, int name_len, char *conf, int conf_len) { const char *start; char *p, *buf; int ret; if (!strstart(filename, "rbd:", &start)) { return -EINVAL; } buf = qemu_strdup(start); p = buf; *snap = '\0'; *conf = '\0'; ret = qemu_rbd_next_tok(pool, pool_len, p, '/', "pool name", &p); if (ret < 0 || !p) { ret = -EINVAL; goto done; } if (strchr(p, '@')) { ret = qemu_rbd_next_tok(name, name_len, p, '@', "object name", &p); if (ret < 0) { goto done; } ret = qemu_rbd_next_tok(snap, snap_len, p, ':', "snap name", &p); } else { ret = qemu_rbd_next_tok(name, name_len, p, ':', "object name", &p); } if (ret < 0 || !p) { goto done; } ret = qemu_rbd_next_tok(conf, conf_len, p, '\0', "configuration", &p); done: qemu_free(buf); return ret; }
static int local_rename(FsContext *ctx, const char *oldpath, const char *newpath) { char *tmp; int err; tmp = qemu_strdup(rpath(ctx, oldpath)); err = rename(tmp, rpath(ctx, newpath)); if (err == -1) { int serrno = errno; qemu_free(tmp); errno = serrno; } else { qemu_free(tmp); } return err; }
/* Look for support files in the same directory as the executable. */ char *os_find_datadir(const char *argv0) { char *p; char buf[MAX_PATH]; DWORD len; len = GetModuleFileName(NULL, buf, sizeof(buf) - 1); if (len == 0) { return NULL; } buf[len] = 0; p = buf + len - 1; while (p != buf && *p != '\\') p--; *p = 0; if (access(buf, R_OK) == 0) { return qemu_strdup(buf); } return NULL; }
static int local_link(FsContext *ctx, const char *oldpath, const char *newpath) { char *tmp = qemu_strdup(rpath(ctx, oldpath)); int err, serrno = 0; if (tmp == NULL) { return -ENOMEM; } err = link(tmp, rpath(ctx, newpath)); if (err == -1) { serrno = errno; } qemu_free(tmp); if (err == -1) { errno = serrno; } return err; }
static int qemu_rbd_open(BlockDriverState *bs, const char *filename, int flags) { BDRVRBDState *s = bs->opaque; char pool[RBD_MAX_POOL_NAME_SIZE]; char snap_buf[RBD_MAX_SNAP_NAME_SIZE]; char conf[RBD_MAX_CONF_SIZE]; int r; if (qemu_rbd_parsename(filename, pool, sizeof(pool), snap_buf, sizeof(snap_buf), s->name, sizeof(s->name), conf, sizeof(conf)) < 0) { return -EINVAL; } s->snap = NULL; if (snap_buf[0] != '\0') { s->snap = qemu_strdup(snap_buf); } r = rados_create(&s->cluster, NULL); if (r < 0) { error_report("error initializing"); return r; } if (strstr(conf, "conf=") == NULL) { r = rados_conf_read_file(s->cluster, NULL); if (r < 0) { error_report("error reading config file"); rados_shutdown(s->cluster); return r; } } if (conf[0] != '\0') { r = qemu_rbd_set_conf(s->cluster, conf); if (r < 0) { error_report("error setting config options"); rados_shutdown(s->cluster); return r; } } r = rados_connect(s->cluster); if (r < 0) { error_report("error connecting"); rados_shutdown(s->cluster); return r; } r = rados_ioctx_create(s->cluster, pool, &s->io_ctx); if (r < 0) { error_report("error opening pool %s", pool); rados_shutdown(s->cluster); return r; } r = rbd_open(s->io_ctx, s->name, &s->image, s->snap); if (r < 0) { error_report("error reading header from %s", s->name); rados_ioctx_destroy(s->io_ctx); rados_shutdown(s->cluster); return r; } bs->read_only = (s->snap != NULL); s->event_reader_pos = 0; r = qemu_pipe(s->fds); if (r < 0) { error_report("error opening eventfd"); goto failed; } fcntl(s->fds[0], F_SETFL, O_NONBLOCK); fcntl(s->fds[1], F_SETFL, O_NONBLOCK); qemu_aio_set_fd_handler(s->fds[RBD_FD_READ], qemu_rbd_aio_event_reader, NULL, qemu_rbd_aio_flush_cb, NULL, s); return 0; failed: rbd_close(s->image); rados_ioctx_destroy(s->io_ctx); rados_shutdown(s->cluster); return r; }
VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf) { V9fsState *s; int i, len; struct stat stat; FsTypeEntry *fse; s = (V9fsState *)virtio_common_init("virtio-9p", VIRTIO_ID_9P, sizeof(struct virtio_9p_config)+ MAX_TAG_LEN, sizeof(V9fsState)); /* initialize pdu allocator */ QLIST_INIT(&s->free_list); for (i = 0; i < (MAX_REQ - 1); i++) { QLIST_INSERT_HEAD(&s->free_list, &s->pdus[i], next); } s->vq = virtio_add_queue(&s->vdev, MAX_REQ, handle_9p_output); fse = get_fsdev_fsentry(conf->fsdev_id); if (!fse) { /* We don't have a fsdev identified by fsdev_id */ fprintf(stderr, "Virtio-9p device couldn't find fsdev with the " "id = %s\n", conf->fsdev_id ? conf->fsdev_id : "NULL"); exit(1); } if (!fse->path || !conf->tag) { /* we haven't specified a mount_tag or the path */ fprintf(stderr, "fsdev with id %s needs path " "and Virtio-9p device needs mount_tag arguments\n", conf->fsdev_id); exit(1); } if (!strcmp(fse->security_model, "passthrough")) { /* Files on the Fileserver set to client user credentials */ s->ctx.fs_sm = SM_PASSTHROUGH; s->ctx.xops = passthrough_xattr_ops; } else if (!strcmp(fse->security_model, "mapped")) { /* Files on the fileserver are set to QEMU credentials. * Client user credentials are saved in extended attributes. */ s->ctx.fs_sm = SM_MAPPED; s->ctx.xops = mapped_xattr_ops; } else if (!strcmp(fse->security_model, "none")) { /* * Files on the fileserver are set to QEMU credentials. */ s->ctx.fs_sm = SM_NONE; s->ctx.xops = none_xattr_ops; } else { fprintf(stderr, "Default to security_model=none. You may want" " enable advanced security model using " "security option:\n\t security_model=passthrough\n\t " "security_model=mapped\n"); s->ctx.fs_sm = SM_NONE; s->ctx.xops = none_xattr_ops; } if (lstat(fse->path, &stat)) { fprintf(stderr, "share path %s does not exist\n", fse->path); exit(1); } else if (!S_ISDIR(stat.st_mode)) { fprintf(stderr, "share path %s is not a directory\n", fse->path); exit(1); } s->ctx.fs_root = qemu_strdup(fse->path); len = strlen(conf->tag); if (len > MAX_TAG_LEN) { len = MAX_TAG_LEN; } /* s->tag is non-NULL terminated string */ s->tag = qemu_malloc(len); memcpy(s->tag, conf->tag, len); s->tag_len = len; s->ctx.uid = -1; s->ops = fse->ops; s->vdev.get_features = virtio_9p_get_features; s->config_size = sizeof(struct virtio_9p_config) + s->tag_len; s->vdev.get_config = virtio_9p_get_config; return &s->vdev; }
/* if no id is provided, a new one is constructed */ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) { BDRVQcowState *s = bs->opaque; QCowSnapshot *snapshots1, sn1, *sn = &sn1; int i, ret; uint64_t *l1_table = NULL; memset(sn, 0, sizeof(*sn)); if (sn_info->id_str[0] == '\0') { /* compute a new id */ find_new_snapshot_id(bs, sn_info->id_str, sizeof(sn_info->id_str)); } /* check that the ID is unique */ if (find_snapshot_by_id(bs, sn_info->id_str) >= 0) return -ENOENT; sn->id_str = qemu_strdup(sn_info->id_str); if (!sn->id_str) goto fail; sn->name = qemu_strdup(sn_info->name); if (!sn->name) goto fail; sn->vm_state_size = sn_info->vm_state_size; sn->date_sec = sn_info->date_sec; sn->date_nsec = sn_info->date_nsec; sn->vm_clock_nsec = sn_info->vm_clock_nsec; ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1); if (ret < 0) goto fail; /* create the L1 table of the snapshot */ sn->l1_table_offset = qcow2_alloc_clusters(bs, s->l1_size * sizeof(uint64_t)); sn->l1_size = s->l1_size; l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t)); for(i = 0; i < s->l1_size; i++) { l1_table[i] = cpu_to_be64(s->l1_table[i]); } if (bdrv_pwrite(s->hd, sn->l1_table_offset, l1_table, s->l1_size * sizeof(uint64_t)) != (s->l1_size * sizeof(uint64_t))) goto fail; qemu_free(l1_table); l1_table = NULL; snapshots1 = qemu_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot)); if (s->snapshots) { memcpy(snapshots1, s->snapshots, s->nb_snapshots * sizeof(QCowSnapshot)); qemu_free(s->snapshots); } s->snapshots = snapshots1; s->snapshots[s->nb_snapshots++] = *sn; if (qcow_write_snapshots(bs) < 0) goto fail; #ifdef DEBUG_ALLOC qcow2_check_refcounts(bs); #endif return 0; fail: qemu_free(sn->name); qemu_free(l1_table); return -1; }
static void *spapr_create_fdt_skel(const char *cpu_model, target_phys_addr_t initrd_base, target_phys_addr_t initrd_size, const char *boot_device, const char *kernel_cmdline, long hash_shift) { void *fdt; CPUState *env; uint64_t mem_reg_property[] = { 0, cpu_to_be64(ram_size) }; uint32_t start_prop = cpu_to_be32(initrd_base); uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size); uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)}; char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt" "\0hcall-tce\0hcall-vio\0hcall-splpar"; uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)}; int i; char *modelname; #define _FDT(exp) \ do { \ int ret = (exp); \ if (ret < 0) { \ fprintf(stderr, "qemu: error creating device tree: %s: %s\n", \ #exp, fdt_strerror(ret)); \ exit(1); \ } \ } while (0) fdt = qemu_mallocz(FDT_MAX_SIZE); _FDT((fdt_create(fdt, FDT_MAX_SIZE))); _FDT((fdt_finish_reservemap(fdt))); /* Root node */ _FDT((fdt_begin_node(fdt, ""))); _FDT((fdt_property_string(fdt, "device_type", "chrp"))); _FDT((fdt_property_string(fdt, "model", "qemu,emulated-pSeries-LPAR"))); _FDT((fdt_property_cell(fdt, "#address-cells", 0x2))); _FDT((fdt_property_cell(fdt, "#size-cells", 0x2))); /* /chosen */ _FDT((fdt_begin_node(fdt, "chosen"))); _FDT((fdt_property_string(fdt, "bootargs", kernel_cmdline))); _FDT((fdt_property(fdt, "linux,initrd-start", &start_prop, sizeof(start_prop)))); _FDT((fdt_property(fdt, "linux,initrd-end", &end_prop, sizeof(end_prop)))); _FDT((fdt_property_string(fdt, "qemu,boot-device", boot_device))); _FDT((fdt_end_node(fdt))); /* memory node */ _FDT((fdt_begin_node(fdt, "memory@0"))); _FDT((fdt_property_string(fdt, "device_type", "memory"))); _FDT((fdt_property(fdt, "reg", mem_reg_property, sizeof(mem_reg_property)))); _FDT((fdt_end_node(fdt))); /* cpus */ _FDT((fdt_begin_node(fdt, "cpus"))); _FDT((fdt_property_cell(fdt, "#address-cells", 0x1))); _FDT((fdt_property_cell(fdt, "#size-cells", 0x0))); modelname = qemu_strdup(cpu_model); for (i = 0; i < strlen(modelname); i++) { modelname[i] = toupper(modelname[i]); } for (env = first_cpu; env != NULL; env = env->next_cpu) { int index = env->cpu_index; uint32_t gserver_prop[] = {cpu_to_be32(index), 0}; /* HACK! */ char *nodename; uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40), 0xffffffff, 0xffffffff}; if (asprintf(&nodename, "%s@%x", modelname, index) < 0) { fprintf(stderr, "Allocation failure\n"); exit(1); } _FDT((fdt_begin_node(fdt, nodename))); free(nodename); _FDT((fdt_property_cell(fdt, "reg", index))); _FDT((fdt_property_string(fdt, "device_type", "cpu"))); _FDT((fdt_property_cell(fdt, "cpu-version", env->spr[SPR_PVR]))); _FDT((fdt_property_cell(fdt, "dcache-block-size", env->dcache_line_size))); _FDT((fdt_property_cell(fdt, "icache-block-size", env->icache_line_size))); _FDT((fdt_property_cell(fdt, "timebase-frequency", TIMEBASE_FREQ))); /* Hardcode CPU frequency for now. It's kind of arbitrary on * full emu, for kvm we should copy it from the host */ _FDT((fdt_property_cell(fdt, "clock-frequency", 1000000000))); _FDT((fdt_property_cell(fdt, "ibm,slb-size", env->slb_nr))); _FDT((fdt_property(fdt, "ibm,pft-size", pft_size_prop, sizeof(pft_size_prop)))); _FDT((fdt_property_string(fdt, "status", "okay"))); _FDT((fdt_property(fdt, "64-bit", NULL, 0))); _FDT((fdt_property_cell(fdt, "ibm,ppc-interrupt-server#s", index))); _FDT((fdt_property(fdt, "ibm,ppc-interrupt-gserver#s", gserver_prop, sizeof(gserver_prop)))); if (env->mmu_model & POWERPC_MMU_1TSEG) { _FDT((fdt_property(fdt, "ibm,processor-segment-sizes", segs, sizeof(segs)))); } _FDT((fdt_end_node(fdt))); } qemu_free(modelname); _FDT((fdt_end_node(fdt))); /* RTAS */ _FDT((fdt_begin_node(fdt, "rtas"))); _FDT((fdt_property(fdt, "ibm,hypertas-functions", hypertas_prop, sizeof(hypertas_prop)))); _FDT((fdt_end_node(fdt))); /* interrupt controller */ _FDT((fdt_begin_node(fdt, "interrupt-controller@0"))); _FDT((fdt_property_string(fdt, "device_type", "PowerPC-External-Interrupt-Presentation"))); _FDT((fdt_property_string(fdt, "compatible", "IBM,ppc-xicp"))); _FDT((fdt_property_cell(fdt, "reg", 0))); _FDT((fdt_property(fdt, "interrupt-controller", NULL, 0))); _FDT((fdt_property(fdt, "ibm,interrupt-server-ranges", interrupt_server_ranges_prop, sizeof(interrupt_server_ranges_prop)))); _FDT((fdt_end_node(fdt))); /* vdevice */ _FDT((fdt_begin_node(fdt, "vdevice"))); _FDT((fdt_property_string(fdt, "device_type", "vdevice"))); _FDT((fdt_property_string(fdt, "compatible", "IBM,vdevice"))); _FDT((fdt_property_cell(fdt, "#address-cells", 0x1))); _FDT((fdt_property_cell(fdt, "#size-cells", 0x0))); _FDT((fdt_property_cell(fdt, "#interrupt-cells", 0x2))); _FDT((fdt_property(fdt, "interrupt-controller", NULL, 0))); _FDT((fdt_end_node(fdt))); _FDT((fdt_end_node(fdt))); /* close root node */ _FDT((fdt_finish(fdt))); return fdt; }
/* pSeries LPAR / sPAPR hardware init */ static void ppc_spapr_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { CPUState *env; int i; ram_addr_t ram_offset; uint32_t initrd_base; long kernel_size, initrd_size, fw_size; long pteg_shift = 17; char *filename; int irq = 16; spapr = qemu_malloc(sizeof(*spapr)); cpu_ppc_hypercall = emulate_spapr_hypercall; /* We place the device tree just below either the top of RAM, or * 2GB, so that it can be processed with 32-bit code if * necessary */ spapr->fdt_addr = MIN(ram_size, 0x80000000) - FDT_MAX_SIZE; spapr->rtas_addr = spapr->fdt_addr - RTAS_MAX_SIZE; /* init CPUs */ if (cpu_model == NULL) { cpu_model = "POWER7"; } 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 512 MHz */ cpu_ppc_tb_init(env, TIMEBASE_FREQ); qemu_register_reset((QEMUResetHandler *)&cpu_reset, env); env->hreset_vector = 0x60; env->hreset_excp_prefix = 0; env->gpr[3] = env->cpu_index; } /* allocate RAM */ ram_offset = qemu_ram_alloc(NULL, "ppc_spapr.ram", ram_size); cpu_register_physical_memory(0, ram_size, ram_offset); /* allocate hash page table. For now we always make this 16mb, * later we should probably make it scale to the size of guest * RAM */ spapr->htab_size = 1ULL << (pteg_shift + 7); spapr->htab = qemu_malloc(spapr->htab_size); for (env = first_cpu; env != NULL; env = env->next_cpu) { env->external_htab = spapr->htab; env->htab_base = -1; env->htab_mask = spapr->htab_size - 1; } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin"); spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr, ram_size - spapr->rtas_addr); if (spapr->rtas_size < 0) { hw_error("qemu: could not load LPAR rtas '%s'\n", filename); exit(1); } qemu_free(filename); /* Set up Interrupt Controller */ spapr->icp = xics_system_init(XICS_IRQS); /* Set up VIO bus */ spapr->vio_bus = spapr_vio_bus_init(); for (i = 0; i < MAX_SERIAL_PORTS; i++, irq++) { if (serial_hds[i]) { spapr_vty_create(spapr->vio_bus, i, serial_hds[i], xics_find_qirq(spapr->icp, irq), irq); } } for (i = 0; i < nb_nics; i++, irq++) { NICInfo *nd = &nd_table[i]; if (!nd->model) { nd->model = qemu_strdup("ibmveth"); } if (strcmp(nd->model, "ibmveth") == 0) { spapr_vlan_create(spapr->vio_bus, 0x1000 + i, nd, xics_find_qirq(spapr->icp, irq), irq); } else { fprintf(stderr, "pSeries (sPAPR) platform does not support " "NIC model '%s' (only ibmveth is supported)\n", nd->model); exit(1); } } for (i = 0; i <= drive_get_max_bus(IF_SCSI); i++) { spapr_vscsi_create(spapr->vio_bus, 0x2000 + i, xics_find_qirq(spapr->icp, irq), irq); irq++; } if (kernel_filename) { uint64_t lowaddr = 0; kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0); if (kernel_size < 0) { kernel_size = load_image_targphys(kernel_filename, KERNEL_LOAD_ADDR, ram_size - KERNEL_LOAD_ADDR); } 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; } spapr->entry_point = KERNEL_LOAD_ADDR; } else { if (ram_size < (MIN_RAM_SLOF << 20)) { fprintf(stderr, "qemu: pSeries SLOF firmware requires >= " "%ldM guest RAM\n", MIN_RAM_SLOF); exit(1); } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "slof.bin"); fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE); if (fw_size < 0) { hw_error("qemu: could not load LPAR rtas '%s'\n", filename); exit(1); } qemu_free(filename); spapr->entry_point = 0x100; initrd_base = 0; initrd_size = 0; /* SLOF will startup the secondary CPUs using RTAS, rather than expecting a kexec() style entry */ for (env = first_cpu; env != NULL; env = env->next_cpu) { env->halted = 1; } } /* Prepare the device tree */ spapr->fdt_skel = spapr_create_fdt_skel(cpu_model, initrd_base, initrd_size, boot_device, kernel_cmdline, pteg_shift + 7); assert(spapr->fdt_skel != NULL); qemu_register_reset(spapr_reset, spapr); }
/* PC hardware initialisation */ static void s390_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { CPUState *env = NULL; ram_addr_t ram_addr; ram_addr_t kernel_size = 0; ram_addr_t initrd_offset; ram_addr_t initrd_size = 0; int i; /* XXX we only work on KVM for now */ if (!kvm_enabled()) { fprintf(stderr, "The S390 target only works with KVM enabled\n"); exit(1); } /* get a BUS */ s390_bus = s390_virtio_bus_init(&ram_size); /* allocate RAM */ ram_addr = qemu_ram_alloc(NULL, "s390.ram", ram_size); cpu_register_physical_memory(0, ram_size, ram_addr); /* init CPUs */ if (cpu_model == NULL) { cpu_model = "host"; } ipi_states = qemu_malloc(sizeof(CPUState *) * smp_cpus); for (i = 0; i < smp_cpus; i++) { CPUState *tmp_env; tmp_env = cpu_init(cpu_model); if (!env) { env = tmp_env; } ipi_states[i] = tmp_env; tmp_env->halted = 1; tmp_env->exception_index = EXCP_HLT; } env->halted = 0; env->exception_index = 0; if (kernel_filename) { kernel_size = load_image(kernel_filename, qemu_get_ram_ptr(0)); if (lduw_phys(KERN_IMAGE_START) != 0x0dd0) { fprintf(stderr, "Specified image is not an s390 boot image\n"); exit(1); } env->psw.addr = KERN_IMAGE_START; env->psw.mask = 0x0000000180000000ULL; } else { ram_addr_t bios_size = 0; char *bios_filename; /* Load zipl bootloader */ if (bios_name == NULL) { bios_name = ZIPL_FILENAME; } bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); bios_size = load_image(bios_filename, qemu_get_ram_ptr(ZIPL_LOAD_ADDR)); qemu_free(bios_filename); if ((long)bios_size < 0) { hw_error("could not load bootloader '%s'\n", bios_name); } if (bios_size > 4096) { hw_error("stage1 bootloader is > 4k\n"); } env->psw.addr = ZIPL_START; env->psw.mask = 0x0000000180000000ULL; } if (initrd_filename) { initrd_offset = INITRD_START; while (kernel_size + 0x100000 > initrd_offset) { initrd_offset += 0x100000; } initrd_size = load_image(initrd_filename, qemu_get_ram_ptr(initrd_offset)); stq_phys(INITRD_PARM_START, initrd_offset); stq_phys(INITRD_PARM_SIZE, initrd_size); } if (kernel_cmdline) { cpu_physical_memory_rw(KERN_PARM_AREA, (uint8_t *)kernel_cmdline, strlen(kernel_cmdline), 1); } /* Create VirtIO network adapters */ for(i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; DeviceState *dev; if (!nd->model) { nd->model = qemu_strdup("virtio"); } if (strcmp(nd->model, "virtio")) { fprintf(stderr, "S390 only supports VirtIO nics\n"); exit(1); } dev = qdev_create((BusState *)s390_bus, "virtio-net-s390"); qdev_set_nic_properties(dev, nd); qdev_init_nofail(dev); } /* Create VirtIO disk drives */ for(i = 0; i < MAX_BLK_DEVS; i++) { DriveInfo *dinfo; DeviceState *dev; dinfo = drive_get(IF_IDE, 0, i); if (!dinfo) { continue; } dev = qdev_create((BusState *)s390_bus, "virtio-blk-s390"); qdev_prop_set_drive_nofail(dev, "drive", dinfo->bdrv); qdev_init_nofail(dev); } }
static int nbd_open(BlockDriverState *bs, const char* filename, int flags) { BDRVNBDState *s = bs->opaque; uint32_t nbdflags; char *file; char *name; const char *host; const char *unixpath; int sock; off_t size; size_t blocksize; int ret; int err = -EINVAL; file = qemu_strdup(filename); name = strstr(file, EN_OPTSTR); if (name) { if (name[strlen(EN_OPTSTR)] == 0) { goto out; } name[0] = 0; name += strlen(EN_OPTSTR); } if (!strstart(file, "nbd:", &host)) { goto out; } if (strstart(host, "unix:", &unixpath)) { if (unixpath[0] != '/') { goto out; } sock = unix_socket_outgoing(unixpath); } else { uint16_t port = NBD_DEFAULT_PORT; char *p, *r; char hostname[128]; pstrcpy(hostname, 128, host); p = strchr(hostname, ':'); if (p != NULL) { *p = '\0'; p++; port = strtol(p, &r, 0); if (r == p) { goto out; } } else if (name == NULL) { goto out; } sock = tcp_socket_outgoing(hostname, port); } if (sock == -1) { err = -errno; goto out; } ret = nbd_receive_negotiate(sock, name, &nbdflags, &size, &blocksize); if (ret == -1) { err = -errno; goto out; } s->sock = sock; s->size = size; s->blocksize = blocksize; err = 0; out: qemu_free(file); return err; }
int wav_start_capture (CaptureState *s, const char *path, int freq, int bits, int nchannels) { WAVState *wav; uint8_t hdr[] = { 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00 }; audsettings_t as; struct audio_capture_ops ops; int stereo, bits16, shift; CaptureVoiceOut *cap; if (bits != 8 && bits != 16) { term_printf ("incorrect bit count %d, must be 8 or 16\n", bits); return -1; } if (nchannels != 1 && nchannels != 2) { term_printf ("incorrect channel count %d, must be 1 or 2\n", nchannels); return -1; } stereo = nchannels == 2; bits16 = bits == 16; as.freq = freq; as.nchannels = 1 << stereo; as.fmt = bits16 ? AUD_FMT_S16 : AUD_FMT_U8; as.endianness = 0; ops.notify = wav_notify; ops.capture = wav_capture; ops.destroy = wav_destroy; wav = qemu_mallocz (sizeof (*wav)); if (!wav) { term_printf ("Could not allocate memory for wav capture (%zu bytes)", sizeof (*wav)); return -1; } shift = bits16 + stereo; hdr[34] = bits16 ? 0x10 : 0x08; le_store (hdr + 22, as.nchannels, 2); le_store (hdr + 24, freq, 4); le_store (hdr + 28, freq << shift, 4); le_store (hdr + 32, 1 << shift, 2); wav->f = qemu_fopen_file (path, "wb"); if (!wav->f) { term_printf ("Failed to open wave file `%s'\nReason: %s\n", path, strerror (errno)); qemu_free (wav); return -1; } wav->path = qemu_strdup (path); wav->bits = bits; wav->nchannels = nchannels; wav->freq = freq; qemu_put_buffer (wav->f, hdr, sizeof (hdr)); cap = AUD_add_capture (NULL, &as, &ops, wav); if (!cap) { term_printf ("Failed to add audio capture\n"); qemu_free (wav->path); qemu_fclose (wav->f); qemu_free (wav); return -1; } wav->cap = cap; s->opaque = wav; s->ops = wav_capture_ops; return 0; }
void events_dev_init(uint32_t base, qemu_irq irq) { events_state *s; int iomemtype; AndroidHwConfig* config = android_hw; s = (events_state *) qemu_mallocz(sizeof(events_state)); /* now set the events capability bits depending on hardware configuration */ /* apparently, the EV_SYN array is used to indicate which other * event classes to consider. */ /* configure EV_KEY array * * All Android devices must have the following keys: * KEY_HOME, KEY_BACK, KEY_SEND (Call), KEY_END (EndCall), * KEY_SOFT1 (Menu), VOLUME_UP, VOLUME_DOWN * * Note that previous models also had a KEY_SOFT2, * and a KEY_POWER which we still support here. * * Newer models have a KEY_SEARCH key, which we always * enable here. * * A Dpad will send: KEY_DOWN / UP / LEFT / RIGHT / CENTER * * The KEY_CAMERA button isn't very useful if there is no camera. * * BTN_MOUSE is sent when the trackball is pressed * BTN_TOUCH is sent when the touchscreen is pressed */ events_set_bit (s, EV_SYN, EV_KEY ); events_set_bit(s, EV_KEY, KEY_HOME); events_set_bit(s, EV_KEY, KEY_BACK); events_set_bit(s, EV_KEY, KEY_SEND); events_set_bit(s, EV_KEY, KEY_END); events_set_bit(s, EV_KEY, KEY_SOFT1); events_set_bit(s, EV_KEY, KEY_VOLUMEUP); events_set_bit(s, EV_KEY, KEY_VOLUMEDOWN); events_set_bit(s, EV_KEY, KEY_SOFT2); events_set_bit(s, EV_KEY, KEY_POWER); events_set_bit(s, EV_KEY, KEY_SEARCH); if (config->hw_dPad) { events_set_bit(s, EV_KEY, KEY_DOWN); events_set_bit(s, EV_KEY, KEY_UP); events_set_bit(s, EV_KEY, KEY_LEFT); events_set_bit(s, EV_KEY, KEY_RIGHT); events_set_bit(s, EV_KEY, KEY_CENTER); } if (config->hw_trackBall) { events_set_bit(s, EV_KEY, BTN_MOUSE); } if (androidHwConfig_isScreenTouch(config)) { events_set_bit(s, EV_KEY, BTN_TOUCH); } if (strcmp(config->hw_camera_back, "none") || strcmp(config->hw_camera_front, "none")) { /* Camera emulation is enabled. */ events_set_bit(s, EV_KEY, KEY_CAMERA); } if (config->hw_keyboard) { /* since we want to implement Unicode reverse-mapping * allow any kind of key, even those not available on * the skin. * * the previous code did set the [1..0x1ff] range, but * we don't want to enable certain bits in the middle * of the range that are registered for mouse/trackball/joystick * events. * * see "linux_keycodes.h" for the list of events codes. */ events_set_bits(s, EV_KEY, 1, 0xff); events_set_bits(s, EV_KEY, 0x160, 0x1ff); /* If there is a keyboard, but no DPad, we need to clear the * corresponding bits. Doing this is simpler than trying to exclude * the DPad values from the ranges above. */ if (!config->hw_dPad) { events_clr_bit(s, EV_KEY, KEY_DOWN); events_clr_bit(s, EV_KEY, KEY_UP); events_clr_bit(s, EV_KEY, KEY_LEFT); events_clr_bit(s, EV_KEY, KEY_RIGHT); events_clr_bit(s, EV_KEY, KEY_CENTER); } } /* configure EV_REL array * * EV_REL events are sent when the trackball is moved */ if (config->hw_trackBall) { events_set_bit (s, EV_SYN, EV_REL ); events_set_bits(s, EV_REL, REL_X, REL_Y); } /* configure EV_ABS array. * * EV_ABS events are sent when the touchscreen is pressed */ if (!androidHwConfig_isScreenNoTouch(config)) { ABSEntry* abs_values; events_set_bit (s, EV_SYN, EV_ABS ); events_set_bits(s, EV_ABS, ABS_X, ABS_Z); /* Allocate the absinfo to report the min/max bounds for each * absolute dimension. The array must contain 3, or ABS_MAX tuples * of (min,max,fuzz,flat) 32-bit values. * * min and max are the bounds * fuzz corresponds to the device's fuziness, we set it to 0 * flat corresponds to the flat position for JOEYDEV devices, * we also set it to 0. * * There is no need to save/restore this array in a snapshot * since the values only depend on the hardware configuration. */ s->abs_info_count = androidHwConfig_isScreenMultiTouch(config) ? ABS_MAX * 4 : 3 * 4; const int abs_size = sizeof(uint32_t) * s->abs_info_count; s->abs_info = malloc(abs_size); memset(s->abs_info, 0, abs_size); abs_values = (ABSEntry*)s->abs_info; abs_values[ABS_X].max = config->hw_lcd_width-1; abs_values[ABS_Y].max = config->hw_lcd_height-1; abs_values[ABS_Z].max = 1; if (androidHwConfig_isScreenMultiTouch(config)) { /* * Setup multitouch. */ events_set_bit(s, EV_ABS, ABS_MT_SLOT); events_set_bit(s, EV_ABS, ABS_MT_POSITION_X); events_set_bit(s, EV_ABS, ABS_MT_POSITION_Y); events_set_bit(s, EV_ABS, ABS_MT_TRACKING_ID); events_set_bit(s, EV_ABS, ABS_MT_TOUCH_MAJOR); events_set_bit(s, EV_ABS, ABS_MT_PRESSURE); abs_values[ABS_MT_SLOT].max = multitouch_get_max_slot(); abs_values[ABS_MT_TRACKING_ID].max = abs_values[ABS_MT_SLOT].max + 1; abs_values[ABS_MT_POSITION_X].max = abs_values[ABS_X].max; abs_values[ABS_MT_POSITION_Y].max = abs_values[ABS_Y].max; abs_values[ABS_MT_TOUCH_MAJOR].max = 0x7fffffff; // TODO: Make it less random abs_values[ABS_MT_PRESSURE].max = 0x100; // TODO: Make it less random } } /* configure EV_SW array * * EV_SW events are sent to indicate that the keyboard lid * was closed or opened (done when we switch layouts through * KP-7 or KP-9). * * We only support this when hw.keyboard.lid is true. */ if (config->hw_keyboard && config->hw_keyboard_lid) { events_set_bit(s, EV_SYN, EV_SW); events_set_bit(s, EV_SW, 0); } iomemtype = cpu_register_io_memory(events_readfn, events_writefn, s); cpu_register_physical_memory(base, 0xfff, iomemtype); qemu_add_kbd_event_handler(events_put_keycode, s); qemu_add_mouse_event_handler(events_put_mouse, s, 1, "goldfish-events"); s->base = base; s->irq = irq; s->first = 0; s->last = 0; s->state = STATE_INIT; s->name = qemu_strdup(config->hw_keyboard_charmap); /* This function migh fire buffered events to the device, so * ensure that it is called after initialization is complete */ user_event_register_generic(s, events_put_generic); register_savevm( "events_state", 0, EVENTS_STATE_SAVE_VERSION, events_state_save, events_state_load, s ); }
void add_completion(const char *str) { if (nb_completions < NB_COMPLETIONS_MAX) { completions[nb_completions++] = qemu_strdup(str); } }
static void mips_jazz_init (ram_addr_t ram_size, const char *cpu_model, enum jazz_model_e jazz_model) { char *filename; int bios_size, n; CPUState *env; qemu_irq *rc4030, *i8259; rc4030_dma *dmas; void* rc4030_opaque; int s_rtc, s_dma_dummy; NICInfo *nd; PITState *pit; DriveInfo *fds[MAX_FD]; qemu_irq esp_reset; ram_addr_t ram_offset; ram_addr_t bios_offset; /* init CPUs */ if (cpu_model == NULL) { #ifdef TARGET_MIPS64 cpu_model = "R4000"; #else /* FIXME: All wrong, this maybe should be R3000 for the older JAZZs. */ cpu_model = "24Kf"; #endif } env = cpu_init(cpu_model); if (!env) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } qemu_register_reset(main_cpu_reset, env); /* allocate RAM */ ram_offset = qemu_ram_alloc(ram_size); cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM); bios_offset = qemu_ram_alloc(MAGNUM_BIOS_SIZE); cpu_register_physical_memory(0x1fc00000LL, MAGNUM_BIOS_SIZE, bios_offset | IO_MEM_ROM); cpu_register_physical_memory(0xfff00000LL, MAGNUM_BIOS_SIZE, bios_offset | IO_MEM_ROM); /* load the BIOS image. */ if (bios_name == NULL) bios_name = BIOS_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { bios_size = load_image_targphys(filename, 0xfff00000LL, MAGNUM_BIOS_SIZE); qemu_free(filename); } else { bios_size = -1; } if (bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE) { fprintf(stderr, "qemu: Could not load MIPS bios '%s'\n", bios_name); exit(1); } /* Init CPU internal devices */ cpu_mips_irq_init_cpu(env); cpu_mips_clock_init(env); /* Chipset */ rc4030_opaque = rc4030_init(env->irq[6], env->irq[3], &rc4030, &dmas); s_dma_dummy = cpu_register_io_memory(dma_dummy_read, dma_dummy_write, NULL); cpu_register_physical_memory(0x8000d000, 0x00001000, s_dma_dummy); /* ISA devices */ i8259 = i8259_init(env->irq[4]); isa_bus_new(NULL); isa_bus_irqs(i8259); DMA_init(0); pit = pit_init(0x40, i8259[0]); pcspk_init(pit); /* ISA IO space at 0x90000000 */ isa_mmio_init(0x90000000, 0x01000000); isa_mem_base = 0x11000000; /* Video card */ switch (jazz_model) { case JAZZ_MAGNUM: g364fb_mm_init(0x40000000, 0x60000000, 0, rc4030[3]); break; case JAZZ_PICA61: isa_vga_mm_init(0x40000000, 0x60000000, 0); break; default: break; } /* Network controller */ for (n = 0; n < nb_nics; n++) { nd = &nd_table[n]; if (!nd->model) nd->model = qemu_strdup("dp83932"); if (strcmp(nd->model, "dp83932") == 0) { dp83932_init(nd, 0x80001000, 2, rc4030[4], rc4030_opaque, rc4030_dma_memory_rw); break; } else if (strcmp(nd->model, "?") == 0) { fprintf(stderr, "qemu: Supported NICs: dp83932\n"); exit(1); } else { fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model); exit(1); } } /* SCSI adapter */ esp_init(0x80002000, 0, rc4030_dma_read, rc4030_dma_write, dmas[0], rc4030[5], &esp_reset); /* Floppy */ if (drive_get_max_bus(IF_FLOPPY) >= MAX_FD) { fprintf(stderr, "qemu: too many floppy drives\n"); exit(1); } for (n = 0; n < MAX_FD; n++) { fds[n] = drive_get(IF_FLOPPY, 0, n); } fdctrl_init_sysbus(rc4030[1], 0, 0x80003000, fds); /* Real time clock */ rtc_init(1980); s_rtc = cpu_register_io_memory(rtc_read, rtc_write, NULL); cpu_register_physical_memory(0x80004000, 0x00001000, s_rtc); /* Keyboard (i8042) */ i8042_mm_init(rc4030[6], rc4030[7], 0x80005000, 0x1000, 0x1); /* Serial ports */ if (serial_hds[0]) serial_mm_init(0x80006000, 0, rc4030[8], 8000000/16, serial_hds[0], 1); if (serial_hds[1]) serial_mm_init(0x80007000, 0, rc4030[9], 8000000/16, serial_hds[1], 1); /* Parallel port */ if (parallel_hds[0]) parallel_mm_init(0x80008000, 0, rc4030[0], parallel_hds[0]); /* Sound card */ /* FIXME: missing Jazz sound at 0x8000c000, rc4030[2] */ #ifdef HAS_AUDIO audio_init(i8259); #endif /* NVRAM: Unprotected at 0x9000, Protected at 0xa000, Read only at 0xb000 */ ds1225y_init(0x80009000, "nvram"); /* LED indicator */ jazz_led_init(0x8000f000); }
void readline_add_completion(ReadLineState *rs, const char *str) { if (rs->nb_completions < READLINE_MAX_COMPLETIONS) { rs->completions[rs->nb_completions++] = qemu_strdup(str); } }