diff options
Diffstat (limited to 'module/scmi_apcore')
-rw-r--r-- | module/scmi_apcore/doc/scmi_apcore.md | 153 | ||||
-rw-r--r-- | module/scmi_apcore/include/internal/scmi_apcore.h | 71 | ||||
-rw-r--r-- | module/scmi_apcore/include/mod_scmi_apcore.h | 75 | ||||
-rw-r--r-- | module/scmi_apcore/src/Makefile | 11 | ||||
-rw-r--r-- | module/scmi_apcore/src/mod_scmi_apcore.c | 432 |
5 files changed, 742 insertions, 0 deletions
diff --git a/module/scmi_apcore/doc/scmi_apcore.md b/module/scmi_apcore/doc/scmi_apcore.md new file mode 100644 index 00000000..9af53a93 --- /dev/null +++ b/module/scmi_apcore/doc/scmi_apcore.md @@ -0,0 +1,153 @@ +SCMI AP Core Configuration Protocol v1.0 +======================================== + +Protocol Overview {#scmi_apcore_protocol_overview} +================= + +This protocol is an extension of the [Arm System Control and Management +Interface (SCMI)] +(http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/index.html). + +The goal of this protocol is for the SCP to provide an interface to the AP +firmware that supports changing the configuration of one or more AP cores. +For example, one of the supported commands allows programming of the AP core +address and is used when AP firmware is unable to program the reset address +directly. + +The protocol identifier used for this protocol (0x90) is within the range that +the SCMI specification provides for platform-specific extensions (0x80 - 0xFF). +For further information on protocol identifiers refer to section 4.1.2 of the +SCMI specification. + +Protocol Commands {#scmi_apcore_protocol} +================= + +Protocol Version {#scmi_apcore_protocol_version} +---------------- + +On success, this command returns the version of the protocol. For this version +of the specification the return value must be 0x10000, which corresponds to 1.0. + +message_id: 0x0<br> +protocol_id: 0x90 + +This command is mandatory. + +Return values: +* int32 status + * See section 4.1.4 of the SCMI specification for status code + definitions +* uint32 version + * For this version of the specification the return value must be 0x10000 + +Protocol Attributes {#scmi_apcore_protocol_attributes} +------------------- + +This command returns the implementation details associated with this protocol. + +message_id: 0x1<br> +protocol_id: 0x90 + +This command is mandatory. + +Return values: +* int32 status + * See section 4.1.4 of the SCMI specification for status code + definitions +* uint32 attributes + * Bits [31:1] Reserved, must be zero. + * Bit [0] If set to 1, the platform supports 64-bit reset addresses. If set + to 0, the platform supports 32-bit reset addresses. + +Protocol Message Attributes {#scmi_apcore_protocol_message__attributes} +--------------------------- + +On success, this command returns the implementation details associated with a +specific message in this protocol. In addition to the standard status codes +described in section 4.1.4 of the SCMI specification, the command can return the +error NOT_FOUND if the message identified by message_id is not provided by +the implementation. + +message_id: 0x2<br> +protocol_id: 0x90 + +This command is mandatory. + +Parameters: +* uint32 message_id + * message_id of the message. + +Return values: +* int32 status + * See section 4.1.4 of the SCMI specification for status code + definitions. +* uint32 attributes + * Flags associated with a specific command in the protocol. For all commands + in this protocol this parameter has a value of 0. + +Core Reset Address Set {#scmi_apcore_protocol_set_address} +---------------------- + +Set the application core reset address. The address applies to all cores. + +In some platforms only the SCP is capable of programming the application core +reset address. This command allows the SCP to carry out the programming on +behalf of AP firmware. Such a feature is supported in the [Arm Trusted Firmware] +(https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/reset-design.rst) + +message_id: 0x3<br> +protocol_id: 0x90 + +This command is optional. + +Parameters: +* uint32 Reset address (lower word) + * Bit[31:0] AP core reset address (low) +* uint32 Reset address (higher word) + * Bit[31:0] AP core reset address (high) + * On platforms that support only 32-bit addresses, only the lower word is + used - this higher word must be zero and the address must be 4-byte + aligned. For platforms supporting 64-bit addresses both words may be used + and the address must be 8-byte aligned. +* uint32 attributes + * Bit[31:1] Reserved, must be zero. + * Bit[0] Lock. When set to 1, the platform will deny any further attempts to + change the reset address. + +Return values: +* int32 status + * SUCCESS if the reset address was set successfully. + * INVALID_PARAMETERS: + * Reset address alignment is invalid. + * Platform supports only 32-bit addresses and the reset address received + is larger than 32-bits. + * DENIED: The reset address is locked and changes are not permitted. + * DENIED: The calling agent is not permitted to modify the reset address. + * See section 4.1.4 of the SCMI specification for status code + definitions. + +Core Reset Address Get {#scmi_apcore_protocol_get_address} +---------------------- + +Get the application core reset address. The address applies to all cores. + +message_id: 0x4<br> +protocol_id: 0x90 + +This command is optional. + +Return values: +* int32 status + * SUCCESS if the reset address was retrieved successfully. + * DENIED: The calling agent is not permitted to retrieve the reset address. + * See section 4.1.4 of the SCMI specification for status code + definitions. +* uint32 Reset address (lower word) + * Bit[31:0] AP core reset address (low) +* uint32 Reset address (higher word) + * Bit[31:0] AP core reset address (high) + * On platforms that support only 32-bit addresses, only the lower word is + used and this higher word must be zero. +* uint32 attributes + * Bit[31:1] Reserved, must be zero. + * Bit[0] Lock. When set to 1, changing the reset address is not permitted. diff --git a/module/scmi_apcore/include/internal/scmi_apcore.h b/module/scmi_apcore/include/internal/scmi_apcore.h new file mode 100644 index 00000000..d55e676b --- /dev/null +++ b/module/scmi_apcore/include/internal/scmi_apcore.h @@ -0,0 +1,71 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SCMI Core Configuration Protocol Support + */ + +#ifndef SCMI_APCORE_H +#define SCMI_APCORE_H + +#include <stdint.h> + +#define SCMI_PROTOCOL_ID_APCORE UINT32_C(0x90) +#define SCMI_PROTOCOL_VERSION_APCORE UINT32_C(0x10000) + +/* + * Identifiers of the SCMI Core Configuration Protocol commands + */ +enum scmi_apcore_command_id { + SCMI_APCORE_RESET_ADDRESS_SET = 0x3, + SCMI_APCORE_RESET_ADDRESS_GET = 0x4, +}; + +/* + * Protocol Attributes + */ + +#define SCMI_APCORE_PROTOCOL_ATTRIBUTES_64BIT_POS 0 + +#define SCMI_APCORE_PROTOCOL_ATTRIBUTES_64BIT_MASK \ + (UINT32_C(0x1) << SCMI_APCORE_PROTOCOL_ATTRIBUTES_64BIT_POS) + +/* + * Reset Address Set + */ + +#define SCMI_APCORE_RESET_ADDRESS_SET_LOCK_POS 0 + +#define SCMI_APCORE_RESET_ADDRESS_SET_LOCK_MASK \ + (UINT32_C(0x1) << SCMI_APCORE_RESET_ADDRESS_SET_LOCK_POS) + +struct __attribute((packed)) scmi_apcore_reset_address_set_a2p { + uint32_t reset_address_low; + uint32_t reset_address_high; + uint32_t attributes; +}; + +struct __attribute((packed)) scmi_apcore_reset_address_set_p2a { + int32_t status; +}; + +/* + * Reset Address Get + */ + +#define SCMI_APCORE_RESET_ADDRESS_GET_LOCK_POS 0 + +#define SCMI_APCORE_RESET_ADDRESS_GET_LOCK_MASK \ + (UINT32_C(0x1) << SCMI_APCORE_RESET_ADDRESS_GET_LOCK_POS) + +struct __attribute((packed)) scmi_apcore_reset_address_get_p2a { + int32_t status; + uint32_t reset_address_low; + uint32_t reset_address_high; + uint32_t attributes; +}; + +#endif /* SCMI_APCORE_H */ diff --git a/module/scmi_apcore/include/mod_scmi_apcore.h b/module/scmi_apcore/include/mod_scmi_apcore.h new file mode 100644 index 00000000..82fe61d6 --- /dev/null +++ b/module/scmi_apcore/include/mod_scmi_apcore.h @@ -0,0 +1,75 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SCMI Core Configuration Protocol Support. + */ + +#ifndef MOD_SCMI_APCORE_H +#define MOD_SCMI_APCORE_H + +#include <stdint.h> +#include <stddef.h> + +/*! + * \ingroup GroupModules Modules + * \defgroup GroupSCMI_APCORE SCMI Core Configuration Protocol + * \{ + */ + +/*! + * \brief Platform reset register widths. + */ +enum mod_scmi_apcore_register_width { + /*! Single-word, 32-bit reset address registers supported */ + MOD_SCMI_APCORE_REG_WIDTH_32, + + /*! Double-word, 64-bit reset address registers supported */ + MOD_SCMI_APCORE_REG_WIDTH_64, + + /*! Number of valid register widths */ + MOD_SCMI_APCORE_REG_WIDTH_COUNT, +}; + +/*! + * \brief Reset register group. + * + * \details Describes a set of reset registers that are contiguous in memory. + */ +struct mod_scmi_apcore_reset_register_group { + /*! Address of the first register in the group */ + uintptr_t base_register; + + /*! The number of registers in the group */ + size_t register_count; +}; + +/*! + * \brief Module configuration. + */ +struct mod_scmi_apcore_config { + /*! + * \brief Pointer to the table of \ref mod_scmi_apcore_reset_register_group + * structures that define the reset registers within the platform. + */ + const struct mod_scmi_apcore_reset_register_group + *reset_register_group_table; + + /*! + * \brief Number of \ref mod_scmi_apcore_reset_register_group structures in + * \ref reset_register_group_table. + */ + size_t reset_register_group_count; + + /*! Width of the reset address supported by the platform */ + enum mod_scmi_apcore_register_width reset_register_width; +}; + +/*! + * \} + */ + +#endif /* MOD_SCMI_APCORE_H */ diff --git a/module/scmi_apcore/src/Makefile b/module/scmi_apcore/src/Makefile new file mode 100644 index 00000000..c5cf7079 --- /dev/null +++ b/module/scmi_apcore/src/Makefile @@ -0,0 +1,11 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_LIB_NAME := SCMI Core Configuration Protocol +BS_LIB_SOURCES := mod_scmi_apcore.c + +include $(BS_DIR)/lib.mk diff --git a/module/scmi_apcore/src/mod_scmi_apcore.c b/module/scmi_apcore/src/mod_scmi_apcore.c new file mode 100644 index 00000000..afedf8fc --- /dev/null +++ b/module/scmi_apcore/src/mod_scmi_apcore.c @@ -0,0 +1,432 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SCMI Core Configuration Protocol Support. + */ + +#include <assert.h> +#include <stdint.h> +#include <fwk_errno.h> +#include <fwk_id.h> +#include <fwk_macros.h> +#include <fwk_module.h> +#include <fwk_module_idx.h> +#include <internal/scmi.h> +#include <internal/scmi_apcore.h> +#include <mod_scmi.h> +#include <mod_scmi_apcore.h> + +struct scmi_apcore_ctx { + /* Module Configuration */ + const struct mod_scmi_apcore_config *config; + + /* SCMI module API */ + const struct mod_scmi_from_protocol_api *scmi_api; + + /* + * Tracks whether an agent has requested that the configuration be locked. + * \c true if the configuration is locked and the reset address of the CPUs + * can no longer be altered, \c false otherwise. + */ + bool locked; +}; + +static int scmi_apcore_protocol_version_handler(fwk_id_t service_id, + const uint32_t *payload); +static int scmi_apcore_protocol_attributes_handler(fwk_id_t service_id, + const uint32_t *payload); +static int scmi_apcore_protocol_message_attributes_handler( + fwk_id_t service_id, const uint32_t *payload); +static int scmi_apcore_reset_address_set_handler(fwk_id_t service_id, + const uint32_t *payload); +static int scmi_apcore_reset_address_get_handler(fwk_id_t service_id, + const uint32_t *payload); + +/* + * Internal variables. + */ +static struct scmi_apcore_ctx scmi_apcore_ctx; + +static int (* const handler_table[])(fwk_id_t, const uint32_t *) = { + [SCMI_PROTOCOL_VERSION] = scmi_apcore_protocol_version_handler, + [SCMI_PROTOCOL_ATTRIBUTES] = scmi_apcore_protocol_attributes_handler, + [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = + scmi_apcore_protocol_message_attributes_handler, + [SCMI_APCORE_RESET_ADDRESS_SET] = scmi_apcore_reset_address_set_handler, + [SCMI_APCORE_RESET_ADDRESS_GET] = scmi_apcore_reset_address_get_handler, +}; + +static const unsigned int payload_size_table[] = { + [SCMI_PROTOCOL_VERSION] = 0, + [SCMI_PROTOCOL_ATTRIBUTES] = 0, + [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = + sizeof(struct scmi_protocol_message_attributes_a2p), + [SCMI_APCORE_RESET_ADDRESS_SET] = + sizeof(struct scmi_apcore_reset_address_set_a2p), + [SCMI_APCORE_RESET_ADDRESS_GET] = 0, +}; + +/* + * Static, Helper Functions + */ +static int set_reset_address(uint32_t address_low, uint32_t address_high) +{ + uint64_t address_composite; + unsigned int grp_idx; + unsigned int reg_idx; + const struct mod_scmi_apcore_reset_register_group *reg_group; + uintptr_t reset_reg; + + address_composite = ((uint64_t)address_high << 32) | address_low; + + /* Iterate over the reset register group structures */ + for (grp_idx = 0; + grp_idx < scmi_apcore_ctx.config->reset_register_group_count; + grp_idx++) { + + reg_group = + &scmi_apcore_ctx.config->reset_register_group_table[grp_idx]; + assert(reg_group->base_register != 0); + + /* Begin with the first register in the group */ + reset_reg = reg_group->base_register; + + /* Program each reset vector register within the group */ + for (reg_idx = 0; reg_idx < reg_group->register_count; reg_idx++) { + if (scmi_apcore_ctx.config->reset_register_width == + MOD_SCMI_APCORE_REG_WIDTH_32) { + /* Treat the register as 32-bit */ + *(uint32_t *)reset_reg = address_low; + reset_reg += sizeof(uint32_t); + } else { + /* Treat the register as 64-bit */ + *(uint64_t *)reset_reg = address_composite; + reset_reg += sizeof(uint64_t); + } + } + } + + return FWK_SUCCESS; +} + +/* + * Protocol Version + */ +static int scmi_apcore_protocol_version_handler(fwk_id_t service_id, + const uint32_t *payload) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_PROTOCOL_VERSION_APCORE, + }; + + scmi_apcore_ctx.scmi_api->respond( + service_id, &return_values, sizeof(return_values)); + return FWK_SUCCESS; +} + +/* + * Protocol Attributes + */ +static int scmi_apcore_protocol_attributes_handler(fwk_id_t service_id, + const uint32_t *payload) +{ + struct scmi_protocol_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + .attributes = 0, + }; + + if (scmi_apcore_ctx.config->reset_register_width == + MOD_SCMI_APCORE_REG_WIDTH_64) + return_values.attributes |= SCMI_APCORE_PROTOCOL_ATTRIBUTES_64BIT_MASK; + + scmi_apcore_ctx.scmi_api->respond( + service_id, + &return_values, + sizeof(return_values)); + + return FWK_SUCCESS; +} + +/* + * Protocol Message Attributes + */ +static int scmi_apcore_protocol_message_attributes_handler(fwk_id_t service_id, + const uint32_t *payload) +{ + size_t response_size; + const struct scmi_protocol_message_attributes_a2p *parameters; + unsigned int message_id; + struct scmi_protocol_message_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + .attributes = 0, + }; + + parameters = (const struct scmi_protocol_message_attributes_a2p *) + payload; + message_id = parameters->message_id; + + if ((message_id >= FWK_ARRAY_SIZE(handler_table)) || + (handler_table[message_id] == NULL)) + return_values.status = SCMI_NOT_FOUND; + + response_size = (return_values.status == SCMI_SUCCESS) ? + sizeof(return_values) : sizeof(return_values.status); + + scmi_apcore_ctx.scmi_api->respond( + service_id, &return_values, response_size); + + return FWK_SUCCESS; +} + +/* + * Reset Address Set + */ +static int scmi_apcore_reset_address_set_handler(fwk_id_t service_id, + const uint32_t *payload) +{ + int status; + unsigned int agent_id; + enum scmi_agent_type agent_type; + const struct scmi_apcore_reset_address_set_a2p *parameters; + struct scmi_apcore_reset_address_set_p2a return_values = { + .status = SCMI_GENERIC_ERROR + }; + + parameters = (const struct scmi_apcore_reset_address_set_a2p *)payload; + + status = scmi_apcore_ctx.scmi_api->get_agent_id(service_id, &agent_id); + if (status != FWK_SUCCESS) + goto exit; + + status = scmi_apcore_ctx.scmi_api->get_agent_type(agent_id, &agent_type); + if (status != FWK_SUCCESS) + goto exit; + + /* Only the PSCI agent may set the reset address */ + if (agent_type != SCMI_AGENT_TYPE_PSCI) { + return_values.status = SCMI_DENIED; + goto exit; + } + + /* An agent previously requested that the configuration be locked */ + if (scmi_apcore_ctx.locked) { + return_values.status = SCMI_DENIED; + goto exit; + } + + /* + * Ensure that the platform has 64-bit reset vector registers if a reset + * address utilizing more that 32 bits has been provided. + */ + if ((parameters->reset_address_high != 0) && + (scmi_apcore_ctx.config->reset_register_width == + MOD_SCMI_APCORE_REG_WIDTH_32)) { + return_values.status = SCMI_INVALID_PARAMETERS; + goto exit; + } + + /* Check for alignment */ + if (scmi_apcore_ctx.config->reset_register_width == + MOD_SCMI_APCORE_REG_WIDTH_32) { + if ((parameters->reset_address_low % 4) != 0) { + return_values.status = SCMI_INVALID_PARAMETERS; + goto exit; + } + } else if ((parameters->reset_address_low % 8) != 0) { + return_values.status = SCMI_INVALID_PARAMETERS; + goto exit; + } + + status = set_reset_address( + parameters->reset_address_low, parameters->reset_address_high); + if (status != FWK_SUCCESS) + goto exit; + + return_values.status = SCMI_SUCCESS; + + /* Lock the configuration if requested */ + if (parameters->attributes & SCMI_APCORE_RESET_ADDRESS_SET_LOCK_MASK) + scmi_apcore_ctx.locked = true; + +exit: + scmi_apcore_ctx.scmi_api->respond( + service_id, &return_values, sizeof(return_values)); + return status; +} + +/* + * Reset Address Get + */ +static int scmi_apcore_reset_address_get_handler(fwk_id_t service_id, + const uint32_t *payload) +{ + int status; + unsigned int agent_id; + const struct mod_scmi_apcore_reset_register_group *reg_group; + uint64_t reset_address; + enum scmi_agent_type agent_type; + struct scmi_apcore_reset_address_get_p2a return_values = { + .status = SCMI_GENERIC_ERROR + }; + + status = scmi_apcore_ctx.scmi_api->get_agent_id(service_id, &agent_id); + if (status != FWK_SUCCESS) + goto exit; + + status = scmi_apcore_ctx.scmi_api->get_agent_type(agent_id, &agent_type); + if (status != FWK_SUCCESS) + goto exit; + + /* Only the PSCI agent may get the current reset address */ + if (agent_type != SCMI_AGENT_TYPE_PSCI) { + return_values.status = SCMI_DENIED; + goto exit; + } + + /* The reset address is common across all reset address registers */ + reg_group = &scmi_apcore_ctx.config->reset_register_group_table[0]; + + if (scmi_apcore_ctx.config->reset_register_width == + MOD_SCMI_APCORE_REG_WIDTH_32) { + reset_address = *(uint32_t *)reg_group->base_register; + return_values.reset_address_high = 0; + } else { + reset_address = *(uint64_t *)reg_group->base_register; + return_values.reset_address_high = (reset_address >> 32) & UINT32_MAX; + } + + return_values.reset_address_low = (uint32_t)reset_address; + + return_values.attributes |= + (scmi_apcore_ctx.locked << SCMI_APCORE_RESET_ADDRESS_GET_LOCK_POS); + return_values.status = SCMI_SUCCESS; + +exit: + scmi_apcore_ctx.scmi_api->respond( + service_id, &return_values, sizeof(return_values)); + return status; +} + +/* + * SCMI module -> SCMI AP Core Configuration module interface + */ +static int scmi_apcore_get_scmi_protocol_id(fwk_id_t protocol_id, + uint8_t *scmi_protocol_id) +{ + int status; + + status = fwk_module_check_call(protocol_id); + if (status != FWK_SUCCESS) + return status; + + *scmi_protocol_id = SCMI_PROTOCOL_ID_APCORE; + + return FWK_SUCCESS; +} + +static int scmi_apcore_message_handler( + fwk_id_t protocol_id, + fwk_id_t service_id, + const uint32_t *payload, + size_t payload_size, + unsigned int message_id) +{ + int status; + int32_t return_value; + + static_assert(FWK_ARRAY_SIZE(handler_table) == + FWK_ARRAY_SIZE(payload_size_table), + "[SCMI] Core configuration protocol table sizes not consistent"); + assert(payload != NULL); + + status = fwk_module_check_call(protocol_id); + if (status != FWK_SUCCESS) + return status; + + if (message_id >= FWK_ARRAY_SIZE(handler_table)) { + return_value = SCMI_NOT_SUPPORTED; + goto error; + } + + if (payload_size != payload_size_table[message_id]) { + return_value = SCMI_PROTOCOL_ERROR; + goto error; + } + + return handler_table[message_id](service_id, payload); + +error: + scmi_apcore_ctx.scmi_api->respond( + service_id, + &return_value, + sizeof(return_value)); + + return FWK_SUCCESS; +} + +static struct mod_scmi_to_protocol_api scmi_apcore_mod_scmi_to_protocol_api = { + .get_scmi_protocol_id = scmi_apcore_get_scmi_protocol_id, + .message_handler = scmi_apcore_message_handler +}; + +/* + * Framework handlers + */ + +static int scmi_apcore_init(fwk_id_t module_id, unsigned int element_count, + const void *data) +{ + const struct mod_scmi_apcore_config *config = + (const struct mod_scmi_apcore_config *)data; + + if (config == NULL) + return FWK_E_PARAM; + if (config->reset_register_group_table == NULL) + return FWK_E_PARAM; + if (config->reset_register_group_count == 0) + return FWK_E_PARAM; + if (config->reset_register_width >= MOD_SCMI_APCORE_REG_WIDTH_COUNT) + return FWK_E_PARAM; + + scmi_apcore_ctx.config = config; + + return FWK_SUCCESS; +} + +static int scmi_apcore_bind(fwk_id_t id, unsigned int round) +{ + if (round == 1) + return FWK_SUCCESS; + + /* Bind to the SCMI module, storing an API pointer for later use. */ + return fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_SCMI), + FWK_ID_API(FWK_MODULE_IDX_SCMI, MOD_SCMI_API_IDX_PROTOCOL), + &scmi_apcore_ctx.scmi_api); +} + +static int scmi_apcore_process_bind_request(fwk_id_t source_id, + fwk_id_t target_id, fwk_id_t api_id, const void **api) +{ + /* Only accept binding requests from the SCMI module. */ + if (!fwk_id_is_equal(source_id, FWK_ID_MODULE(FWK_MODULE_IDX_SCMI))) + return FWK_E_ACCESS; + + *api = &scmi_apcore_mod_scmi_to_protocol_api; + + return FWK_SUCCESS; +} + +/* SCMI Clock Management Protocol Definition */ +const struct fwk_module module_scmi_apcore = { + .name = "SCMI Core Configuration Protocol", + .api_count = 1, + .type = FWK_MODULE_TYPE_PROTOCOL, + .init = scmi_apcore_init, + .bind = scmi_apcore_bind, + .process_bind_request = scmi_apcore_process_bind_request, +}; |