|
@@ -93,6 +93,7 @@
|
|
|
#include "qemu/config-file.h"
|
|
|
#include "qemu/qemu-options.h"
|
|
|
#include "qemu/main-loop.h"
|
|
|
+#include "hw/cxl/cxl.h"
|
|
|
#ifdef CONFIG_VIRTFS
|
|
|
#include "fsdev/qemu-fsdev.h"
|
|
|
#endif
|
|
@@ -118,6 +119,7 @@
|
|
|
#include "qapi/qapi-events-run-state.h"
|
|
|
#include "qapi/qapi-visit-block-core.h"
|
|
|
#include "qapi/qapi-visit-compat.h"
|
|
|
+#include "qapi/qapi-visit-machine.h"
|
|
|
#include "qapi/qapi-visit-ui.h"
|
|
|
#include "qapi/qapi-commands-block-core.h"
|
|
|
#include "qapi/qapi-commands-migration.h"
|
|
@@ -143,6 +145,12 @@ typedef struct BlockdevOptionsQueueEntry {
|
|
|
|
|
|
typedef QSIMPLEQ_HEAD(, BlockdevOptionsQueueEntry) BlockdevOptionsQueue;
|
|
|
|
|
|
+typedef struct CXLFMWOptionQueueEntry {
|
|
|
+ CXLFixedMemoryWindowOptions *opts;
|
|
|
+ Location loc;
|
|
|
+ QSIMPLEQ_ENTRY(CXLFMWOptionQueueEntry) entry;
|
|
|
+} CXLFMWOptionQueueEntry;
|
|
|
+
|
|
|
typedef struct ObjectOption {
|
|
|
ObjectOptions *opts;
|
|
|
QTAILQ_ENTRY(ObjectOption) next;
|
|
@@ -169,6 +177,8 @@ static int snapshot;
|
|
|
static bool preconfig_requested;
|
|
|
static QemuPluginList plugin_list = QTAILQ_HEAD_INITIALIZER(plugin_list);
|
|
|
static BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
|
|
|
+static QSIMPLEQ_HEAD(, CXLFMWOptionQueueEntry) CXLFMW_opts =
|
|
|
+ QSIMPLEQ_HEAD_INITIALIZER(CXLFMW_opts);
|
|
|
static bool nographic = false;
|
|
|
static int mem_prealloc; /* force preallocation of physical target memory */
|
|
|
static const char *vga_model = NULL;
|
|
@@ -1153,6 +1163,24 @@ static void parse_display(const char *p)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void parse_cxl_fixed_memory_window(const char *optarg)
|
|
|
+{
|
|
|
+ CXLFMWOptionQueueEntry *cfmws_entry;
|
|
|
+ Visitor *v;
|
|
|
+
|
|
|
+ v = qobject_input_visitor_new_str(optarg, "cxl-fixed-memory-window",
|
|
|
+ &error_fatal);
|
|
|
+ cfmws_entry = g_new(CXLFMWOptionQueueEntry, 1);
|
|
|
+ visit_type_CXLFixedMemoryWindowOptions(v, NULL, &cfmws_entry->opts,
|
|
|
+ &error_fatal);
|
|
|
+ if (!cfmws_entry->opts) {
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ visit_free(v);
|
|
|
+ loc_save(&cfmws_entry->loc);
|
|
|
+ QSIMPLEQ_INSERT_TAIL(&CXLFMW_opts, cfmws_entry, entry);
|
|
|
+}
|
|
|
+
|
|
|
static inline bool nonempty_str(const char *str)
|
|
|
{
|
|
|
return str && *str;
|
|
@@ -2015,6 +2043,20 @@ static void qemu_create_late_backends(void)
|
|
|
qemu_semihosting_console_init();
|
|
|
}
|
|
|
|
|
|
+static void cxl_set_opts(void)
|
|
|
+{
|
|
|
+ while (!QSIMPLEQ_EMPTY(&CXLFMW_opts)) {
|
|
|
+ CXLFMWOptionQueueEntry *cfmws_entry = QSIMPLEQ_FIRST(&CXLFMW_opts);
|
|
|
+
|
|
|
+ loc_restore(&cfmws_entry->loc);
|
|
|
+ QSIMPLEQ_REMOVE_HEAD(&CXLFMW_opts, entry);
|
|
|
+ cxl_fixed_memory_window_config(current_machine, cfmws_entry->opts,
|
|
|
+ &error_fatal);
|
|
|
+ qapi_free_CXLFixedMemoryWindowOptions(cfmws_entry->opts);
|
|
|
+ g_free(cfmws_entry);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void qemu_resolve_machine_memdev(void)
|
|
|
{
|
|
|
if (ram_memdev_id) {
|
|
@@ -2661,6 +2703,7 @@ void qmp_x_exit_preconfig(Error **errp)
|
|
|
|
|
|
qemu_init_board();
|
|
|
qemu_create_cli_devices();
|
|
|
+ cxl_fixed_memory_window_link_targets(errp);
|
|
|
qemu_machine_creation_done();
|
|
|
|
|
|
if (loadvm) {
|
|
@@ -2841,6 +2884,9 @@ void qemu_init(int argc, char **argv, char **envp)
|
|
|
exit(1);
|
|
|
}
|
|
|
break;
|
|
|
+ case QEMU_OPTION_cxl_fixed_memory_window:
|
|
|
+ parse_cxl_fixed_memory_window(optarg);
|
|
|
+ break;
|
|
|
case QEMU_OPTION_display:
|
|
|
parse_display(optarg);
|
|
|
break;
|
|
@@ -3652,6 +3698,7 @@ void qemu_init(int argc, char **argv, char **envp)
|
|
|
|
|
|
qemu_resolve_machine_memdev();
|
|
|
parse_numa_opts(current_machine);
|
|
|
+ cxl_set_opts();
|
|
|
|
|
|
if (vmstate_dump_file) {
|
|
|
/* dump and exit */
|