diff mbox series

[10/16] mcd: Implement runstate control

Message ID 20250310150510.200607-11-mario.fleischmann@lauterbach.com (mailing list archive)
State New
Headers show
Series Add Multi-Core Debug (MCD) API support | expand

Commit Message

Mario Fleischmann March 10, 2025, 3:05 p.m. UTC
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(-)
diff mbox series

Patch

diff --git a/mcd/mcdserver.c b/mcd/mcdserver.c
index f0cda23981..9e46ea5fa5 100644
--- a/mcd/mcdserver.c
+++ b/mcd/mcdserver.c
@@ -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;
 }
 
diff --git a/mcd/mcdstub_qapi.c b/mcd/mcdstub_qapi.c
index 6aa72b025c..635f95181b 100644
--- a/mcd/mcdstub_qapi.c
+++ b/mcd/mcdstub_qapi.c
@@ -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;
+}
diff --git a/qapi/mcd.json b/qapi/mcd.json
index 936016de45..c8b82e7f82 100644
--- a/qapi/mcd.json
+++ b/qapi/mcd.json
@@ -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' }