@@ -14,6 +14,8 @@
#include "hw/boards.h"
#include "exec/tswap.h"
#include "exec/gdbstub.h"
+#include "hw/core/cpu.h"
+#include "system/runstate.h"
/* Custom memory space type */
static const mcd_mem_type_et MCD_MEM_SPACE_IS_SECURE = 0x00010000;
@@ -1087,13 +1089,53 @@ mcd_return_et mcd_execute_txlist_f(const mcd_core_st *core,
mcd_return_et mcd_run_f(const mcd_core_st *core, bool global)
{
- g_server_state.last_error = &MCD_ERROR_NOT_IMPLEMENTED;
- return g_server_state.last_error->return_status;
+ mcdcore_state *core_state;
+
+ if (g_server_state.cores->len > 1 && global) {
+ vm_start();
+ g_server_state.last_error = &MCD_ERROR_NONE;
+ return g_server_state.last_error->return_status;
+ }
+
+ if (!core) {
+ g_server_state.last_error = &MCD_ERROR_INVALID_NULL_PARAM;
+ return g_server_state.last_error->return_status;
+ }
+
+ core_state = find_core(core->core_con_info);
+ if (!core_state || core_state->open_core != core) {
+ g_server_state.last_error = &MCD_ERROR_UNKNOWN_CORE;
+ return g_server_state.last_error->return_status;
+ }
+
+ if (!runstate_needs_reset() && !runstate_is_running() &&
+ !vm_prepare_start(false)) {
+ cpu_resume(core_state->cpu);
+ qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
+ }
+
+ core_state->last_error = &MCD_ERROR_NONE;
+ return core_state->last_error->return_status;
}
mcd_return_et mcd_stop_f(const mcd_core_st *core, bool global)
{
- g_server_state.last_error = &MCD_ERROR_NOT_IMPLEMENTED;
+ if (g_server_state.cores->len > 1 && !global) {
+ g_server_state.custom_error = (mcd_error_info_st) {
+ .return_status = MCD_RET_ACT_HANDLE_ERROR,
+ .error_code = MCD_ERR_FN_UNIMPLEMENTED,
+ .error_events = MCD_ERR_EVT_NONE,
+ .error_str = "core-specific stop not implemented",
+ };
+ g_server_state.last_error = &g_server_state.custom_error;
+ return g_server_state.last_error->return_status;
+ }
+
+ if (runstate_is_running()) {
+ vm_stop(RUN_STATE_DEBUG);
+ }
+
+ g_server_state.last_error = &MCD_ERROR_NONE;
return g_server_state.last_error->return_status;
}
@@ -1120,7 +1162,31 @@ mcd_return_et mcd_step_f(const mcd_core_st *core, bool global,
mcd_return_et mcd_set_global_f(const mcd_core_st *core, bool enable)
{
- g_server_state.last_error = &MCD_ERROR_NOT_IMPLEMENTED;
+ mcdcore_state *core_state;
+
+ if (!core) {
+ g_server_state.last_error = &MCD_ERROR_INVALID_NULL_PARAM;
+ return g_server_state.last_error->return_status;
+ }
+
+ core_state = find_core(core->core_con_info);
+ if (!core_state || core_state->open_core != core) {
+ g_server_state.last_error = &MCD_ERROR_UNKNOWN_CORE;
+ return g_server_state.last_error->return_status;
+ }
+
+ if (!enable) {
+ core_state->custom_error = (mcd_error_info_st) {
+ .return_status = MCD_RET_ACT_HANDLE_ERROR,
+ .error_code = MCD_ERR_GENERAL,
+ .error_events = MCD_ERR_EVT_NONE,
+ .error_str = "global stop activities cannot be disabled",
+ };
+ core_state->last_error = &core_state->custom_error;
+ return core_state->last_error->return_status;
+ }
+
+ g_server_state.last_error = &MCD_ERROR_NONE;
return g_server_state.last_error->return_status;
}
@@ -505,3 +505,55 @@ MCDQryRegMapResult *qmp_mcd_qry_reg_map(uint32_t core_uid,
g_stub_state.on_error_ask_server = true;
return result;
}
+
+MCDRunResult *qmp_mcd_run(uint32_t core_uid, bool global, Error **errp)
+{
+ MCDRunResult *result = g_malloc0(sizeof(*result));
+ mcd_core_st *core = NULL;
+
+ result->return_status = retrieve_open_core(core_uid, &core);
+ if (result->return_status != MCD_RET_ACT_NONE) {
+ g_stub_state.on_error_ask_server = false;
+ return result;
+ }
+
+ result->return_status = mcd_run_f(core, global);
+
+ g_stub_state.on_error_ask_server = true;
+ return result;
+}
+
+MCDStopResult *qmp_mcd_stop(uint32_t core_uid, bool global, Error **errp)
+{
+ MCDStopResult *result = g_malloc0(sizeof(*result));
+ mcd_core_st *core = NULL;
+
+ result->return_status = retrieve_open_core(core_uid, &core);
+ if (result->return_status != MCD_RET_ACT_NONE) {
+ g_stub_state.on_error_ask_server = false;
+ return result;
+ }
+
+ result->return_status = mcd_stop_f(core, global);
+
+ g_stub_state.on_error_ask_server = true;
+ return result;
+}
+
+MCDSetGlobalResult *qmp_mcd_set_global(uint32_t core_uid, bool enable,
+ Error **errp)
+{
+ MCDSetGlobalResult *result = g_malloc0(sizeof(*result));
+ mcd_core_st *core = NULL;
+
+ result->return_status = retrieve_open_core(core_uid, &core);
+ if (result->return_status != MCD_RET_ACT_NONE) {
+ g_stub_state.on_error_ask_server = false;
+ return result;
+ }
+
+ result->return_status = mcd_set_global_f(core, enable);
+
+ g_stub_state.on_error_ask_server = true;
+ return result;
+}
@@ -1373,3 +1373,103 @@
'start-index': 'uint32',
'num-regs': 'uint32' },
'returns': 'MCDQryRegMapResult' }
+
+
+##
+# == Target Execution Control API
+##
+
+
+##
+# @MCDRunResult:
+#
+# Return value of @MCDRunResult.
+#
+# @return-status: Return code.
+#
+# Since: 9.1
+##
+{ 'struct': 'MCDRunResult', 'data': { 'return-status': 'uint32' } }
+
+
+##
+# @mcd-run:
+#
+# Function starting execution on a particular core.
+#
+# @core-uid: Unique identifier of the open core as returned by @mcd-open-core.
+# @global: Set to "TRUE" if all cores of a system shall start execution.
+# Otherwise, starting execution of selected core only.
+#
+# Returns: @MCDRunResult
+#
+# Since: 9.1
+##
+{ 'command': 'mcd-run',
+ 'data': {
+ 'core-uid': 'uint32',
+ 'global' : 'bool' },
+ 'returns': 'MCDRunResult' }
+
+
+##
+# @MCDStopResult:
+#
+# Return value of @mcd-stop.
+#
+# @return-status: Return code.
+#
+# Since: 9.1
+##
+{ 'struct': 'MCDStopResult', 'data': { 'return-status': 'uint32' } }
+
+
+##
+# @mcd-stop:
+#
+# Function stopping execution on a particular core.
+#
+# @core-uid: Unique identifier of the open core as returned by @mcd-open-core.
+# @global: Set to "TRUE" if all cores of a system shall stop execution.
+# Otherwise, stopping execution of selected core only.
+#
+# Returns: @MCDStopResult
+#
+# Since: 9.1
+##
+{ 'command': 'mcd-stop',
+ 'data': {
+ 'core-uid': 'uint32',
+ 'global' : 'bool' },
+ 'returns': 'MCDStopResult' }
+
+##
+# @MCDSetGlobalResult:
+#
+# Return value of @mcd-set-global.
+#
+# @return-status: Return code.
+#
+# Since: 9.1
+##
+{ 'struct': 'MCDSetGlobalResult', 'data': { 'return-status': 'uint32' } }
+
+
+##
+# @mcd-set-global:
+#
+# Function enabling/disabling global stop and run activities on this core.
+#
+# @core-uid: Unique identifier of the open core as returned by @mcd-open-core.
+# @enable: Set to "TRUE" if this core should perform global run or stop
+# activities.
+#
+# Returns: @MCDSetGlobalResult
+#
+# Since: 9.1
+##
+{ 'command': 'mcd-set-global',
+ 'data': {
+ 'core-uid': 'uint32',
+ 'enable' : 'bool' },
+ 'returns': 'MCDSetGlobalResult' }
Currently, only global stop is implemented Signed-off-by: Mario Fleischmann <mario.fleischmann@lauterbach.com> --- mcd/mcdserver.c | 74 +++++++++++++++++++++++++++++++-- mcd/mcdstub_qapi.c | 52 +++++++++++++++++++++++ qapi/mcd.json | 100 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 222 insertions(+), 4 deletions(-)