Currently, only global stop is implemented Signed-off-by: Mario Fleischmann <mario.fleischm...@lauterbach.com> --- mcd/mcdserver.c | 74 +++++++++++++++++++++++++++++++-- mcd/mcdstub_qapi.c | 52 +++++++++++++++++++++++ qapi/mcd.json | 100 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 222 insertions(+), 4 deletions(-)
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' } -- 2.34.1