@@ -279,6 +279,28 @@ static QemuOptsList qemu_option_rom_opts = {
},
};
+static QemuOptsList qemu_remote_opts = {
+ .name = "remote",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_remote_opts.head),
+ .desc = {
+ {
+ .name = "rid",
+ .type = QEMU_OPT_NUMBER,
+ .help = "id of the remote process"
+ },{
+ .name = "socket",
+ .type = QEMU_OPT_NUMBER,
+ .help = "Socket for remote",
+ },{
+ .name = "command",
+ .type = QEMU_OPT_STRING,
+ .help = "command to run",
+ },
+ { /* end of list */ }
+ },
+};
+
+
static QemuOptsList qemu_machine_opts = {
.name = "machine",
.implied_opt_name = "type",
@@ -346,6 +368,87 @@ static QemuOptsList qemu_boot_opts = {
},
};
+#if defined(CONFIG_MPQEMU)
+static int device_remote_add(void *opaque, QemuOpts *opts, Error **errp)
+{
+ unsigned int rid = *(unsigned int *)opaque;
+ const char *opt_rid = NULL;
+ struct remote_process *p = NULL;;
+
+ opt_rid = qemu_opt_get(opts, "rid");
+ if (!opt_rid) {
+ return 0;
+ }
+
+ p = get_remote_process_rid(rid);
+ if (!p) {
+ return -EINVAL;
+ }
+
+ if (atoi(opt_rid) == rid) {
+ qemu_opt_set(opts, "command", p->command, errp);
+ rdevice_init_func(opaque, opts, errp);
+ qemu_opts_del(opts);
+ }
+ return 0;
+}
+
+static int parse_remote(void *opaque, QemuOpts *opts, Error **errp)
+{
+ int rid;
+ int socket;
+ char *c_sock;
+ const char *command = NULL;
+ struct remote_process r_proc;
+
+ rid = atoi(qemu_opt_get(opts, "rid"));
+ if (rid < 0) {
+ error_setg(errp, "rid is required.");
+ return -1;
+ }
+ if (get_remote_process_rid(rid)) {
+ error_setg(errp, "There is already process with rid %d", rid);
+ goto cont_devices;
+ }
+
+ c_sock = (char *)qemu_opt_get(opts, "socket");
+ if (c_sock) {
+ socket = atoi(c_sock);
+ } else {
+ socket = -1;
+ }
+
+ command = qemu_opt_get(opts, "command");
+
+ if (socket <= STDERR_FILENO && socket != -1) {
+ socket = -1;
+ }
+
+ if (!command && socket < 0) {
+ error_setg(errp, "No correct socket or command defined for remote.");
+ return -1;
+ }
+
+ if (rid < 0) {
+ error_setg(errp, "id option is required and must be non-negative");
+ return -1;
+ }
+ r_proc.rid = rid;
+ r_proc.socket = socket;
+ r_proc.command = g_strdup(command);
+ remote_process_register(&r_proc);
+
+ cont_devices:
+ if (qemu_opts_foreach(qemu_find_opts("device"), device_remote_add,
+ &rid, NULL)) {
+ error_setg(errp, "Could not process some of the remote devices.");
+ }
+
+ return 0;
+}
+
+#endif
+
static QemuOptsList qemu_add_fd_opts = {
.name = "add-fd",
.head = QTAILQ_HEAD_INITIALIZER(qemu_add_fd_opts.head),
@@ -2861,6 +2964,7 @@ int main(int argc, char **argv, char **envp)
qemu_add_opts(&qemu_icount_opts);
qemu_add_opts(&qemu_semihosting_config_opts);
qemu_add_opts(&qemu_fw_cfg_opts);
+ qemu_add_opts(&qemu_remote_opts);
module_call_init(MODULE_INIT_OPTS);
runstate_init();
@@ -3697,6 +3801,14 @@ int main(int argc, char **argv, char **envp)
exit(1);
#endif
break;
+ case QEMU_OPTION_remote:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("remote"),
+ optarg, false);
+ if (!opts) {
+ exit(1);
+ }
+ break;
+
case QEMU_OPTION_object:
opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
optarg, true);
@@ -4297,6 +4409,11 @@ int main(int argc, char **argv, char **envp)
qemu_opts_foreach(qemu_find_opts("device"),
device_init_func, NULL, &error_fatal);
+#ifdef CONFIG_MPQEMU
+ qemu_opts_foreach(qemu_find_opts("remote"),
+ parse_remote, NULL, &error_fatal);
+#endif
+
cpu_synchronize_all_post_init();
rom_reset_order_override();