@@ -77,3 +77,51 @@ MCDServerInfo *marshal_mcd_server_info(const mcd_server_info_st *server_info)
return marshal;
}
+
+MCDCoreConInfo *marshal_mcd_core_con_info(const mcd_core_con_info_st *con_info)
+{
+ MCDCoreConInfo *marshal = g_malloc0(sizeof(*marshal));
+
+ *marshal = (MCDCoreConInfo) {
+ .host = g_strdup(con_info->host),
+ .server_port = con_info->server_port,
+ .server_key = g_strdup(con_info->server_key),
+ .system_key = g_strdup(con_info->system_key),
+ .device_key = g_strdup(con_info->device_key),
+ .system = g_strdup(con_info->system),
+ .system_instance = g_strdup(con_info->system_instance),
+ .acc_hw = g_strdup(con_info->acc_hw),
+ .device_type = con_info->device_type,
+ .device = g_strdup(con_info->device),
+ .device_id = con_info->device_id,
+ .core = g_strdup(con_info->core),
+ .core_type = con_info->core_type,
+ .core_id = con_info->core_id,
+ };
+
+ return marshal;
+}
+
+mcd_core_con_info_st unmarshal_mcd_core_con_info(MCDCoreConInfo *con_info)
+{
+ mcd_core_con_info_st unmarshal = {
+ .server_port = con_info->server_port,
+ .device_type = con_info->device_type,
+ .device_id = con_info->device_id,
+ .core_type = con_info->core_type,
+ .core_id = con_info->core_id,
+ };
+
+ strncpy(unmarshal.host, con_info->host, MCD_HOSTNAME_LEN - 1);
+ strncpy(unmarshal.server_key, con_info->server_key, MCD_KEY_LEN - 1);
+ strncpy(unmarshal.system_key, con_info->system_key, MCD_KEY_LEN - 1);
+ strncpy(unmarshal.device_key, con_info->device_key, MCD_KEY_LEN - 1);
+ strncpy(unmarshal.system, con_info->system, MCD_UNIQUE_NAME_LEN - 1);
+ strncpy(unmarshal.system_instance, con_info->system_instance,
+ MCD_UNIQUE_NAME_LEN - 1);
+ strncpy(unmarshal.acc_hw, con_info->acc_hw, MCD_UNIQUE_NAME_LEN - 1);
+ strncpy(unmarshal.device, con_info->device, MCD_UNIQUE_NAME_LEN - 1);
+ strncpy(unmarshal.core, con_info->core, MCD_UNIQUE_NAME_LEN - 1);
+
+ return unmarshal;
+}
@@ -23,6 +23,10 @@ MCDErrorInfo *marshal_mcd_error_info(const mcd_error_info_st *error_info);
MCDServerInfo *marshal_mcd_server_info(const mcd_server_info_st *server_info);
+MCDCoreConInfo *marshal_mcd_core_con_info(const mcd_core_con_info_st *con_info);
+
mcd_api_version_st unmarshal_mcd_api_version(MCDAPIVersion *api_version);
+mcd_core_con_info_st unmarshal_mcd_core_con_info(MCDCoreConInfo *con_info);
+
#endif /* LIBMCD_QAPI_H */
@@ -9,7 +9,9 @@
*/
#include "qemu/osdep.h"
+#include "qemu/cutils.h"
#include "mcd_api.h"
+#include "hw/boards.h"
static const mcd_error_info_st MCD_ERROR_NOT_IMPLEMENTED = {
.return_status = MCD_RET_ACT_HANDLE_ERROR,
@@ -25,6 +27,13 @@ static const mcd_error_info_st MCD_ERROR_INVALID_NULL_PARAM = {
.error_str = "null was invalidly passed as a parameter",
};
+static const mcd_error_info_st MCD_ERROR_SERVER_NOT_OPEN = {
+ .return_status = MCD_RET_ACT_HANDLE_ERROR,
+ .error_code = MCD_ERR_CONNECTION,
+ .error_events = MCD_ERR_EVT_NONE,
+ .error_str = "server is not open",
+};
+
static const mcd_error_info_st MCD_ERROR_NONE = {
.return_status = MCD_RET_ACT_NONE,
.error_code = MCD_ERR_NONE,
@@ -40,15 +49,21 @@ static mcd_error_info_st custom_mcd_error;
*
* @last_error: Error info of most recent executed function.
* @open_server: Open server instance as allocated in mcd_open_server_f().
+ * @system_key: System key as provided in mcd_open_server_f()
+ * @cores: Internal core information database.
*/
typedef struct mcdserver_state {
const mcd_error_info_st *last_error;
mcd_server_st *open_server;
+ char system_key[MCD_KEY_LEN];
+ GArray *cores;
} mcdserver_state;
static mcdserver_state g_server_state = {
.last_error = &MCD_ERROR_NONE,
.open_server = NULL,
+ .system_key = "",
+ .cores = NULL,
};
mcd_return_et mcd_initialize_f(const mcd_api_version_st *version_req,
@@ -153,6 +168,8 @@ mcd_return_et mcd_open_server_f(const char *system_key,
const char *config_string,
mcd_server_st **server)
{
+ CPUState *cpu;
+
if (g_server_state.open_server) {
custom_mcd_error = (mcd_error_info_st) {
.return_status = MCD_RET_ACT_HANDLE_ERROR,
@@ -178,6 +195,23 @@ mcd_return_et mcd_open_server_f(const char *system_key,
*server = g_server_state.open_server;
+ if (system_key) {
+ pstrcpy(g_server_state.system_key, MCD_KEY_LEN, system_key);
+ }
+
+ /* update the internal core information data base */
+ g_server_state.cores = g_array_new(false, true,
+ sizeof(mcd_core_con_info_st));
+ CPU_FOREACH(cpu) {
+ ObjectClass *oc = object_get_class(OBJECT(cpu));
+ const char *cpu_model = object_class_get_name(oc);
+ mcd_core_con_info_st info = {
+ .core_id = g_server_state.cores->len,
+ };
+ pstrcpy(info.core, MCD_UNIQUE_NAME_LEN, cpu_model);
+ g_array_append_val(g_server_state.cores, info);
+ }
+
g_server_state.last_error = &MCD_ERROR_NONE;
return g_server_state.last_error->return_status;
}
@@ -206,8 +240,10 @@ mcd_return_et mcd_close_server_f(const mcd_server_st *server)
return g_server_state.last_error->return_status;
}
+ g_array_free(g_server_state.cores, true);
g_free(g_server_state.open_server);
g_server_state.open_server = NULL;
+ g_server_state.system_key[0] = '\0';
g_server_state.last_error = &MCD_ERROR_NONE;
return g_server_state.last_error->return_status;
@@ -231,7 +267,45 @@ mcd_return_et mcd_qry_server_config_f(const mcd_server_st *server,
mcd_return_et mcd_qry_systems_f(uint32_t start_index, uint32_t *num_systems,
mcd_core_con_info_st *system_con_info)
{
- g_server_state.last_error = &MCD_ERROR_NOT_IMPLEMENTED;
+ if (!num_systems) {
+ g_server_state.last_error = &MCD_ERROR_INVALID_NULL_PARAM;
+ return g_server_state.last_error->return_status;
+ }
+
+ if (*num_systems == 0) {
+ *num_systems = 1;
+ g_server_state.last_error = &MCD_ERROR_NONE;
+ return g_server_state.last_error->return_status;
+ }
+
+ if (start_index >= 1) {
+ custom_mcd_error = (mcd_error_info_st) {
+ .return_status = MCD_RET_ACT_HANDLE_ERROR,
+ .error_code = MCD_ERR_PARAM,
+ .error_events = MCD_ERR_EVT_NONE,
+ .error_str = "QEMU only emulates one system",
+ };
+ g_server_state.last_error = &custom_mcd_error;
+ return g_server_state.last_error->return_status;
+ }
+
+ /* num_systems != 0 => return system information */
+
+ if (!system_con_info) {
+ g_server_state.last_error = &MCD_ERROR_INVALID_NULL_PARAM;
+ return g_server_state.last_error->return_status;
+ }
+
+ *system_con_info = (mcd_core_con_info_st) {};
+ pstrcpy(system_con_info->system, MCD_UNIQUE_NAME_LEN, g_get_prgname());
+ pstrcpy(system_con_info->system_key, MCD_KEY_LEN,
+ g_server_state.system_key);
+ snprintf(system_con_info->system_instance, MCD_UNIQUE_NAME_LEN ,
+ "Process ID: %d", (int) getpid());
+
+ *num_systems = 1;
+
+ g_server_state.last_error = &MCD_ERROR_NONE;
return g_server_state.last_error->return_status;
}
@@ -239,7 +313,41 @@ mcd_return_et mcd_qry_devices_f(const mcd_core_con_info_st *system_con_info,
uint32_t start_index, uint32_t *num_devices,
mcd_core_con_info_st *device_con_info)
{
- g_server_state.last_error = &MCD_ERROR_NOT_IMPLEMENTED;
+ MachineClass *mc = MACHINE_GET_CLASS(current_machine);
+
+ if (!system_con_info || !num_devices) {
+ g_server_state.last_error = &MCD_ERROR_INVALID_NULL_PARAM;
+ return g_server_state.last_error->return_status;
+ }
+
+ if (*num_devices == 0) {
+ *num_devices = 1;
+ g_server_state.last_error = &MCD_ERROR_NONE;
+ return g_server_state.last_error->return_status;
+ }
+
+ if (start_index >= 1) {
+ custom_mcd_error = (mcd_error_info_st) {
+ .return_status = MCD_RET_ACT_HANDLE_ERROR,
+ .error_code = MCD_ERR_PARAM,
+ .error_events = MCD_ERR_EVT_NONE,
+ .error_str = "QEMU only emulates one machine",
+ };
+ g_server_state.last_error = &custom_mcd_error;
+ return g_server_state.last_error->return_status;
+ }
+
+ if (!device_con_info) {
+ g_server_state.last_error = &MCD_ERROR_INVALID_NULL_PARAM;
+ return g_server_state.last_error->return_status;
+ }
+
+ *device_con_info = *system_con_info;
+ pstrcpy(device_con_info->device, MCD_UNIQUE_NAME_LEN, mc->name);
+
+ *num_devices = 1;
+
+ g_server_state.last_error = &MCD_ERROR_NONE;
return g_server_state.last_error->return_status;
}
@@ -247,7 +355,58 @@ mcd_return_et mcd_qry_cores_f(const mcd_core_con_info_st *connection_info,
uint32_t start_index, uint32_t *num_cores,
mcd_core_con_info_st *core_con_info)
{
- g_server_state.last_error = &MCD_ERROR_NOT_IMPLEMENTED;
+ uint32_t i;
+
+ if (!g_server_state.open_server) {
+ g_server_state.last_error = &MCD_ERROR_SERVER_NOT_OPEN;
+ return g_server_state.last_error->return_status;
+ }
+
+ if (!connection_info || !num_cores) {
+ g_server_state.last_error = &MCD_ERROR_INVALID_NULL_PARAM;
+ return g_server_state.last_error->return_status;
+ }
+
+ /* array is allocated during core database update in mcd_server_open_f */
+ g_assert(g_server_state.cores);
+
+ if (*num_cores == 0) {
+ *num_cores = g_server_state.cores->len;
+ g_server_state.last_error = &MCD_ERROR_NONE;
+ return g_server_state.last_error->return_status;
+ }
+
+ if (start_index >= g_server_state.cores->len) {
+ custom_mcd_error = (mcd_error_info_st) {
+ .return_status = MCD_RET_ACT_HANDLE_ERROR,
+ .error_code = MCD_ERR_PARAM,
+ .error_events = MCD_ERR_EVT_NONE,
+ .error_str = "start_index exceeds the number of cores",
+ };
+ g_server_state.last_error = &custom_mcd_error;
+ return g_server_state.last_error->return_status;
+ }
+
+ if (!core_con_info) {
+ g_server_state.last_error = &MCD_ERROR_INVALID_NULL_PARAM;
+ return g_server_state.last_error->return_status;
+ }
+
+ for (i = 0;
+ i < *num_cores && start_index + i < g_server_state.cores->len;
+ i++) {
+
+ mcd_core_con_info_st *info = &g_array_index(g_server_state.cores,
+ mcd_core_con_info_st,
+ start_index + i);
+ core_con_info[i] = *connection_info;
+ core_con_info[i].core_id = info->core_id;
+ pstrcpy(core_con_info[i].core, MCD_UNIQUE_NAME_LEN, info->core);
+ }
+
+ *num_cores = i;
+
+ g_server_state.last_error = &MCD_ERROR_NONE;
return g_server_state.last_error->return_status;
}
@@ -136,6 +136,122 @@ MCDCloseServerResult *qmp_mcd_close_server(uint32_t server_uid, Error **errp)
return result;
}
+MCDQrySystemsResult *qmp_mcd_qry_systems(uint32_t start_index,
+ uint32_t num_systems, Error **errp)
+{
+ MCDCoreConInfoList **tailp;
+ MCDCoreConInfo *info;
+ mcd_core_con_info_st *system_con_info = NULL;
+ bool query_num_only = num_systems == 0;
+ MCDQrySystemsResult *result = g_malloc0(sizeof(*result));
+
+ if (!query_num_only) {
+ system_con_info = g_malloc0(num_systems * sizeof(*system_con_info));
+ }
+
+ result->return_status = mcd_qry_systems_f(start_index, &num_systems,
+ system_con_info);
+
+ if (result->return_status == MCD_RET_ACT_NONE) {
+ result->has_num_systems = true;
+ result->num_systems = num_systems;
+ if (!query_num_only) {
+ result->has_system_con_info = true;
+ tailp = &(result->system_con_info);
+ for (uint32_t i = 0; i < num_systems; i++) {
+ info = marshal_mcd_core_con_info(system_con_info + i);
+ QAPI_LIST_APPEND(tailp, info);
+ }
+ }
+ }
+
+ if (!query_num_only) {
+ g_free(system_con_info);
+ }
+
+ return result;
+}
+
+MCDQryDevicesResult *qmp_mcd_qry_devices(MCDCoreConInfo *system_con_info,
+ uint32_t start_index,
+ uint32_t num_devices, Error **errp)
+{
+ MCDCoreConInfoList **tailp;
+ MCDCoreConInfo *info;
+ mcd_core_con_info_st *device_con_info = NULL;
+ bool query_num_only = num_devices == 0;
+ MCDQryDevicesResult *result = g_malloc0(sizeof(*result));
+ mcd_core_con_info_st system_con_info_unmarshalled =
+ unmarshal_mcd_core_con_info(system_con_info);
+
+ if (!query_num_only) {
+ device_con_info = g_malloc0(num_devices * sizeof(*device_con_info));
+ }
+
+ result->return_status = mcd_qry_devices_f(&system_con_info_unmarshalled,
+ start_index, &num_devices,
+ device_con_info);
+
+ if (result->return_status == MCD_RET_ACT_NONE) {
+ result->has_num_devices = true;
+ result->num_devices = num_devices;
+ if (!query_num_only) {
+ result->has_device_con_info = true;
+ tailp = &(result->device_con_info);
+ for (uint32_t i = 0; i < num_devices; i++) {
+ info = marshal_mcd_core_con_info(device_con_info + i);
+ QAPI_LIST_APPEND(tailp, info);
+ }
+ }
+ }
+
+ if (!query_num_only) {
+ g_free(device_con_info);
+ }
+
+ return result;
+}
+
+MCDQryCoresResult *qmp_mcd_qry_cores(MCDCoreConInfo *connection_info,
+ uint32_t start_index, uint32_t num_cores,
+ Error **errp)
+{
+ MCDCoreConInfoList **tailp;
+ MCDCoreConInfo *info;
+ mcd_core_con_info_st *core_con_info = NULL;
+ bool query_num_only = num_cores == 0;
+ MCDQryCoresResult *result = g_malloc0(sizeof(*result));
+ mcd_core_con_info_st connection_info_unmarshalled =
+ unmarshal_mcd_core_con_info(connection_info);
+
+ if (!query_num_only) {
+ core_con_info = g_malloc0(num_cores * sizeof(*core_con_info));
+ }
+
+ result->return_status = mcd_qry_cores_f(&connection_info_unmarshalled,
+ start_index, &num_cores,
+ core_con_info);
+
+ if (result->return_status == MCD_RET_ACT_NONE) {
+ result->has_num_cores = true;
+ result->num_cores = num_cores;
+ if (!query_num_only) {
+ result->has_core_con_info = true;
+ tailp = &(result->core_con_info);
+ for (uint32_t i = 0; i < num_cores; i++) {
+ info = marshal_mcd_core_con_info(core_con_info + i);
+ QAPI_LIST_APPEND(tailp, info);
+ }
+ }
+ }
+
+ if (!query_num_only) {
+ g_free(core_con_info);
+ }
+
+ return result;
+}
+
MCDErrorInfo *qmp_mcd_qry_error_info(Error **errp)
{
MCDErrorInfo *result;
@@ -91,6 +91,62 @@
'acc-hw' : 'str' } }
+##
+# @MCDCoreConInfo:
+#
+# Structure type containing the core connection information.
+#
+# @host: String containing the IP host name.
+# @server-port: Port number of the server.
+# @server-key: String containing the server key as provided by
+# mcd_open_server_f().
+# @system-key: String containing the system key as provided by
+# mcd_open_server_f().
+# @device-key: String containing the device key, optional for
+# mcd_open_core_f().
+# @system: String containing the system name. Predefined value is
+# "Real HW" for physical devices. Note that in case of "Real
+# HW" the @acc-hw always needs to be defined.
+# @system-instance: String containing the unique system instance identifier.
+# Allows to differentiate between several system instances
+# with the same name. A typical use case is a simulator where
+# different instances can be distinguished by their process
+# ID. (For example @system-instance could be: "Process ID:
+# 1234")
+# @acc-hw: String containing the unique device access hardware name.
+# @device-type: Device type identifier (IEEE 1149.1 device ID)
+# @device: String containing the system unique device instance name.
+# For Real HW this is usually the sales name of the device.
+# If the access hardware operates a multi device target
+# system (e.g. over IEEE1149.7), this device string can
+# contain an index to differentiate between several devices
+# of the same type.
+# @device-id: Unique device ID.
+# @core: String containing the device unique core name.
+# @core-type: Core type identifier (taken from ELF predefined
+# architecture)
+# @core-id: Unique core ID representing the core version.
+#
+# Since: 9.1
+##
+{ 'struct': 'MCDCoreConInfo',
+ 'data': {
+ 'host' : 'str',
+ 'server-port' : 'uint32',
+ 'server-key' : 'str',
+ 'system-key' : 'str',
+ 'device-key' : 'str',
+ 'system' : 'str',
+ 'system-instance': 'str',
+ 'acc-hw' : 'str',
+ 'device-type' : 'uint32',
+ 'device' : 'str',
+ 'device-id' : 'uint32',
+ 'core' : 'str',
+ 'core-type' : 'uint32',
+ 'core-id' : 'uint32' } }
+
+
##
# == Target Initialization API
##
@@ -353,6 +409,306 @@
'returns': 'MCDCloseServerResult' }
+##
+# == Target System Features API
+##
+
+
+##
+# @MCDQrySystemsResult:
+#
+# Return value of @mcd-qry-systems.
+#
+# @return-status: Return code.
+# @num-systems: The number of systems the core connection info was returned
+# for. In case the input value of @num-systems is '0', this is
+# the number of all available systems.
+# @system-con-info: Core connection information of the requested systems.
+#
+# Since: 9.1
+##
+{ 'struct': 'MCDQrySystemsResult',
+ 'data': {
+ 'return-status' : 'uint32',
+ '*num-systems' : 'uint32',
+ '*system-con-info': [ 'MCDCoreConInfo' ] }}
+
+
+##
+# @mcd-qry-systems:
+#
+# Function querying the core connection information of a specified number of
+# systems.
+#
+# @start-index: Start index of the queried systems. This refers to an
+# internal list of the target side implementation.
+# @num-systems: The number of queried systems starting from the defined
+# @start-index. If it is set to '0', no core connection
+# information is returned but the number of available systems.
+#
+# Returns: @MCDQrySystemsResult
+#
+# Since: 9.1
+#
+# .. qmp-example::
+#
+# -> { "execute": "mcd-qry-systems",
+# "arguments": { "start-index": 0,
+# "num-systems": 1 } }
+# <- {
+# "return": {
+# "num-systems": 1,
+# "system-con-info": [
+# {
+# "core-id": 0,
+# "device": "",
+# "device-id": 0,
+# "device-key": "",
+# "system": "qemu-system-aarch64",
+# "core": "",
+# "host": "",
+# "system-key": "",
+# "system-instance": "Process ID: 21591",
+# "acc-hw": "",
+# "core-type": 0,
+# "device-type": 0,
+# "server-key": "",
+# "server-port": 0
+# }
+# ],
+# "return-status": 0
+# }
+# }
+##
+{ 'command': 'mcd-qry-systems',
+ 'data': {
+ 'start-index': 'uint32',
+ 'num-systems': 'uint32' },
+ 'returns': 'MCDQrySystemsResult' }
+
+
+##
+# @MCDQryDevicesResult:
+#
+# Return value of @mcd-qry-devices.
+#
+# @return-status: Return code.
+# @num-devices: The number of devices the core connection information was
+# returned for. In case the input value of @num-devices is
+# '0', this is the number of all available devices for the
+# selected system.
+# @device-con-info: Core connection information of the requested devices.
+#
+# Since: 9.1
+##
+{ 'struct': 'MCDQryDevicesResult',
+ 'data': {
+ 'return-status' : 'uint32',
+ '*num-devices' : 'uint32',
+ '*device-con-info': [ 'MCDCoreConInfo' ] }}
+
+
+##
+# @mcd-qry-devices:
+#
+# Function querying the core connection information of a specified number of
+# devices of a system.
+#
+# @system-con-info: Core connection information of the system the devices
+# are queried from.
+# @start-index: Start index of the requested devices. This refers to
+# an internal list of the target side implementation.
+# @num-devices: The number of queried devices (e.g. simulated on or
+# connected to this host computer) starting from the defined
+# @start-index. If it is set to '0', no core connection
+# information is returned but the number of all available
+# devices.
+#
+# Returns: @MCDQryDevicesResult
+#
+# Since: 9.1
+#
+# .. qmp-example::
+#
+# -> { "execute": "mcd-qry-devices",
+# "arguments": {
+# "start-index": 0,
+# "num-devices": 1,
+# "system-con-info": {
+# "core-id": 0,
+# "device": "",
+# "device-id": 0,
+# "device-key": "",
+# "system": "qemu-system-aarch64",
+# "core": "",
+# "host": "",
+# "system-key": "",
+# "system-instance": "",
+# "acc-hw": "",
+# "core-type": 0,
+# "device-type": 0,
+# "server-key": "",
+# "server-port": 0 } } }
+# <- {
+# "return": {
+# "return-status": 0,
+# "num-devices": 1,
+# "device-con-info": [
+# {
+# "core-id": 0,
+# "device": "virt-10.0",
+# "device-id": 0,
+# "device-key": "",
+# "system": "qemu-system-aarch64",
+# "core": "",
+# "host": "",
+# "system-key": "",
+# "system-instance": "",
+# "acc-hw": "",
+# "core-type": 0,
+# "device-type": 0,
+# "server-key": "",
+# "server-port": 0
+# }
+# ]
+# }
+# }
+##
+{ 'command': 'mcd-qry-devices',
+ 'data': {
+ 'system-con-info': 'MCDCoreConInfo',
+ 'start-index' : 'uint32',
+ 'num-devices' : 'uint32' },
+ 'returns': 'MCDQryDevicesResult' }
+
+
+##
+# @MCDQryCoresResult:
+#
+# Return value of @mcd-qry-cores.
+#
+# @return-status: Return code.
+#
+# @num-cores: The number of cores the core connection information
+# is returned for. In case the input value of @num-cores is '0',
+# this is the number of all available cores for the selected
+# system or device.
+# @core-con-info: Core connection information of the requested cores.
+#
+# Since: 9.1
+##
+{ 'struct': 'MCDQryCoresResult',
+ 'data': {
+ 'return-status' : 'uint32',
+ '*num-cores' : 'uint32',
+ '*core-con-info': [ 'MCDCoreConInfo' ] }}
+
+
+##
+# @mcd-qry-cores:
+#
+# Function querying the core connection information of a specified number of
+# cores of a system/device.
+#
+# @connection-info: Core connection information of the system or device
+# the cores are queried from.
+# @start-index: Start index of the requested cores. This refers to an
+# internal list of the target side implementation.
+# @num-cores: The number of queried cores starting from the defined
+# @start-index. If it is set to '0', no core connection
+# information is returned but the number of all available
+# cores.
+#
+# Returns: @MCDQryCoresResult
+#
+# Since: 9.1
+#
+# .. qmp-example::
+# :title: Multicore
+#
+# -> { "execute": "mcd-qry-cores",
+# "arguments": {
+# "start-index": 0,
+# "num-cores": 3,
+# "connection-info": {
+# "core-id": 0,
+# "device": "virt-10.0",
+# "device-id": 0,
+# "device-key": "",
+# "system": "",
+# "core": "",
+# "host": "",
+# "system-key": "qemu-system-aarch64",
+# "system-instance": "",
+# "acc-hw": "",
+# "core-type": 0,
+# "device-type": 0,
+# "server-key": "",
+# "server-port": 0 } } }
+# <- {
+# "return": {
+# "num-cores": 3,
+# "core-con-info": [
+# {
+# "core-id": 0,
+# "device": "virt-10.0",
+# "device-id": 0,
+# "device-key": "",
+# "system": "",
+# "core": "cortex-a53-arm-cpu",
+# "host": "",
+# "system-key": "qemu-system-aarch64",
+# "system-instance": "",
+# "acc-hw": "",
+# "core-type": 0,
+# "device-type": 0,
+# "server-key": "",
+# "server-port": 0
+# },
+# {
+# "core-id": 1,
+# "device": "virt-10.0",
+# "device-id": 0,
+# "device-key": "",
+# "system": "",
+# "core": "cortex-a53-arm-cpu",
+# "host": "",
+# "system-key": "qemu-system-aarch64",
+# "system-instance": "",
+# "acc-hw": "",
+# "core-type": 0,
+# "device-type": 0,
+# "server-key": "",
+# "server-port": 0
+# },
+# {
+# "core-id": 2,
+# "device": "virt-10.0",
+# "device-id": 0,
+# "device-key": "",
+# "system": "",
+# "core": "cortex-a53-arm-cpu",
+# "host": "",
+# "system-key": "qemu-system-aarch64",
+# "system-instance": "",
+# "acc-hw": "",
+# "core-type": 0,
+# "device-type": 0,
+# "server-key": "",
+# "server-port": 0
+# }
+# ],
+# "return-status": 0
+# }
+# }
+##
+{ 'command': 'mcd-qry-cores',
+ 'data': {
+ 'connection-info': 'MCDCoreConInfo',
+ 'start-index' : 'uint32',
+ 'num-cores' : 'uint32' },
+ 'returns': 'MCDQryCoresResult' }
+
##
# == Core Connection API
##
@@ -87,6 +87,12 @@ MCDErrorInfo *qtest_mcd_qry_error_info(QTestState *qts)
return unmarshal;
}
+void qtest_mcd_exit(QTestState *qts)
+{
+ QDict *resp = qtest_qmp(qts, "{'execute': 'mcd-exit' }");
+ qobject_unref(resp);
+}
+
MCDQryServersResult *qtest_mcd_qry_servers(QTestState *qts,
q_obj_mcd_qry_servers_arg *args)
{
@@ -146,3 +152,63 @@ MCDCloseServerResult *qtest_mcd_close_server(QTestState *qts,
return unmarshal;
}
+
+MCDQrySystemsResult *qtest_mcd_qry_systems(QTestState *qts,
+ q_obj_mcd_qry_systems_arg *args)
+{
+ Visitor *v;
+ QObject *marshal;
+ QDict *arg, *resp;
+ QObject *ret;
+ bool ok;
+ MCDQrySystemsResult *unmarshal;
+
+ MARSHAL_ARGS(q_obj_mcd_qry_systems_arg);
+
+ resp = qtest_qmp(qts, "{'execute': 'mcd-qry-systems',"
+ "'arguments': %p}", arg);
+
+ UNMARSHAL_RESULT(MCDQrySystemsResult);
+
+ return unmarshal;
+}
+
+MCDQryDevicesResult *qtest_mcd_qry_devices(QTestState *qts,
+ q_obj_mcd_qry_devices_arg *args)
+{
+ Visitor *v;
+ QObject *marshal;
+ QDict *arg, *resp;
+ QObject *ret;
+ bool ok;
+ MCDQryDevicesResult *unmarshal;
+
+ MARSHAL_ARGS(q_obj_mcd_qry_devices_arg);
+
+ resp = qtest_qmp(qts, "{'execute': 'mcd-qry-devices',"
+ "'arguments': %p}", arg);
+
+ UNMARSHAL_RESULT(MCDQryDevicesResult);
+
+ return unmarshal;
+}
+
+MCDQryCoresResult *qtest_mcd_qry_cores(QTestState *qts,
+ q_obj_mcd_qry_cores_arg *args)
+{
+ Visitor *v;
+ QObject *marshal;
+ QDict *arg, *resp;
+ QObject *ret;
+ bool ok;
+ MCDQryCoresResult *unmarshal;
+
+ MARSHAL_ARGS(q_obj_mcd_qry_cores_arg);
+
+ resp = qtest_qmp(qts, "{'execute': 'mcd-qry-cores',"
+ "'arguments': %p}", arg);
+
+ UNMARSHAL_RESULT(MCDQryCoresResult);
+
+ return unmarshal;
+}
@@ -20,6 +20,8 @@ MCDInitializeResult *qtest_mcd_initialize(QTestState *qts,
MCDErrorInfo *qtest_mcd_qry_error_info(QTestState *qts);
+void qtest_mcd_exit(QTestState *qts);
+
MCDQryServersResult *qtest_mcd_qry_servers(QTestState *qts,
q_obj_mcd_qry_servers_arg *args);
@@ -29,4 +31,13 @@ MCDOpenServerResult *qtest_mcd_open_server(QTestState *qts,
MCDCloseServerResult *qtest_mcd_close_server(QTestState *qts,
q_obj_mcd_close_server_arg *args);
+MCDQrySystemsResult *qtest_mcd_qry_systems(QTestState *qts,
+ q_obj_mcd_qry_systems_arg *args);
+
+MCDQryDevicesResult *qtest_mcd_qry_devices(QTestState *qts,
+ q_obj_mcd_qry_devices_arg *args);
+
+MCDQryCoresResult *qtest_mcd_qry_cores(QTestState *qts,
+ q_obj_mcd_qry_cores_arg *args);
+
#endif /* LIBMCD_TEST_H */
@@ -176,6 +176,88 @@ static void test_open_server(void)
qtest_quit(qts);
}
+static void test_qry_cores(void)
+{
+ QTestState *qts = qtest_init(QEMU_EXTRA_ARGS);
+
+ char empty_string[] = "";
+
+ q_obj_mcd_open_server_arg open_server_args = {
+ .system_key = empty_string,
+ .config_string = empty_string,
+ };
+
+ q_obj_mcd_qry_systems_arg qry_systems_args = {
+ .start_index = 0,
+ .num_systems = 1,
+ };
+
+ q_obj_mcd_qry_devices_arg qry_devices_args = {
+ .start_index = 0,
+ .num_devices = 1,
+ };
+
+ q_obj_mcd_qry_cores_arg qry_cores_args = {
+ .start_index = 0,
+ /* first, only query the number of cores */
+ .num_cores = 0,
+ };
+
+ MCDOpenServerResult *open_server_result;
+ MCDQrySystemsResult *qry_systems_result;
+ MCDQryDevicesResult *qry_devices_result;
+ MCDQryCoresResult *qry_cores_result;
+
+ open_server_result = qtest_mcd_open_server(qts, &open_server_args);
+ g_assert(open_server_result->return_status == MCD_RET_ACT_NONE);
+ g_assert(open_server_result->has_server_uid);
+ qapi_free_MCDOpenServerResult(open_server_result);
+
+ qry_systems_result = qtest_mcd_qry_systems(qts, &qry_systems_args);
+ g_assert(qry_systems_result->return_status == MCD_RET_ACT_NONE);
+ g_assert(qry_systems_result->has_system_con_info);
+
+ qry_devices_args.system_con_info =
+ qry_systems_result->system_con_info->value;
+
+ qry_devices_result = qtest_mcd_qry_devices(qts, &qry_devices_args);
+ g_assert(qry_devices_result->return_status == MCD_RET_ACT_NONE);
+ g_assert(qry_devices_result->has_device_con_info);
+ qapi_free_MCDQrySystemsResult(qry_systems_result);
+
+ qry_cores_args.connection_info =
+ qry_devices_result->device_con_info->value;
+
+ qry_cores_result = qtest_mcd_qry_cores(qts, &qry_cores_args);
+ g_assert(qry_cores_result->return_status == MCD_RET_ACT_NONE);
+ g_assert(qry_cores_result->has_num_cores);
+ g_assert(qry_cores_result->num_cores > 0);
+ qry_cores_args.num_cores = qry_cores_result->num_cores;
+ qapi_free_MCDQryCoresResult(qry_cores_result);
+ qry_cores_result = qtest_mcd_qry_cores(qts, &qry_cores_args);
+ qapi_free_MCDQryDevicesResult(qry_devices_result);
+
+ if (verbose) {
+ MCDCoreConInfoList *core_head = qry_cores_result->core_con_info;
+ for (uint32_t c = 0; c < qry_cores_result->num_cores; c++) {
+ MCDCoreConInfo *core_con = core_head->value;
+ if (verbose) {
+ fprintf(stderr, "[INFO]\tSystem: %s\n"
+ "\tDevice: %s\n"
+ "\tCore: %s (#%d)\n",
+ core_con->system,
+ core_con->device,
+ core_con->core, core_con->core_id);
+ }
+ core_head = core_head->next;
+ }
+ }
+
+ qapi_free_MCDQryCoresResult(qry_cores_result);
+ qtest_mcd_exit(qts);
+ qtest_quit(qts);
+}
+
int main(int argc, char *argv[])
{
char *v_env = getenv("V");
@@ -185,5 +267,6 @@ int main(int argc, char *argv[])
qtest_add_func("mcd/initialize", test_initialize);
qtest_add_func("mcd/qry-servers", test_qry_servers);
qtest_add_func("mcd/open-server", test_open_server);
+ qtest_add_func("mcd/qry-cores", test_qry_cores);
return g_test_run();
}
In MCD, the target system is divided into system, devices and cores: [ system ] 1-* [ devices ] 1-* [cores] This commit implements the necessary functions to query information about the target system. Signed-off-by: Mario Fleischmann <mario.fleischmann@lauterbach.com> --- mcd/libmcd_qapi.c | 48 +++++ mcd/libmcd_qapi.h | 4 + mcd/mcdserver.c | 165 +++++++++++++++++- mcd/mcdstub_qapi.c | 116 +++++++++++++ qapi/mcd.json | 356 ++++++++++++++++++++++++++++++++++++++ tests/qtest/libmcd-test.c | 66 +++++++ tests/qtest/libmcd-test.h | 11 ++ tests/qtest/mcd-test.c | 83 +++++++++ 8 files changed, 846 insertions(+), 3 deletions(-)