blob: 9fbaa879e616f280fed7995971763e3c18964cce [file] [log] [blame]
// SPDX-License-Identifier: BSD-3-Clause
/*
* Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
*/
#include "rpc/ffarpc/endpoint/ffarpc_call_ep.h"
#include "deployments/smm-gateway/common/smm_gateway.h"
#include "config/ramstore/config_ramstore.h"
#include "config/interface/config_store.h"
#include "config/loader/sp/sp_config_loader.h"
#include "components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.h"
#include "components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.h"
#include "platform/interface/memory_region.h"
#include "protocols/common/mm/mm_smc.h"
#include "ffa_api.h"
#include "sp_api.h"
#include "sp_discovery.h"
#include "sp_messaging.h"
#include "sp_rxtx.h"
#include "trace.h"
#define CONFIG_NAME_MM_COMM_BUFFER_REGION "mm-comm-buffer"
static bool sp_init(uint16_t *own_sp_id);
void __noreturn sp_main(union ffa_boot_info *boot_info)
{
struct memory_region mm_comm_buffer_region = { 0 };
struct rpc_interface *gateway_iface = NULL;
struct smm_variable_mm_service smm_var_service = { 0 };
struct mm_service_interface *smm_var_service_interface = NULL;
struct mm_communicate_ep mm_communicate_call_ep = { 0 };
struct ffa_direct_msg req_msg = { 0 };
struct ffa_direct_msg resp_msg = { 0 };
uint16_t own_id = 0;
ffa_result result = FFA_DENIED;
static const EFI_GUID smm_variable_guid = SMM_VARIABLE_GUID;
/* Boot phase */
if (!sp_init(&own_id)) {
EMSG("Failed to init SP");
goto fatal_error;
}
/* Load any dynamic configuration */
config_ramstore_init();
if (!sp_config_load(boot_info)) {
EMSG("Failed to load SP config");
goto fatal_error;
}
if (!config_store_query(CONFIG_CLASSIFIER_MEMORY_REGION, CONFIG_NAME_MM_COMM_BUFFER_REGION,
0, &mm_comm_buffer_region, sizeof(mm_comm_buffer_region))) {
EMSG(CONFIG_NAME_MM_COMM_BUFFER_REGION " is not set in SP configuration");
goto fatal_error;
}
/* Initialize service layer and associate with RPC endpoint */
gateway_iface = smm_gateway_create(own_id);
if (!gateway_iface) {
EMSG("Failed to create SMM gateway");
goto fatal_error;
}
/* Initialize SMM variable MM service */
smm_var_service_interface = smm_variable_mm_service_init(&smm_var_service, gateway_iface);
if (!smm_var_service_interface) {
EMSG("Failed to init SMM variable MM service");
goto fatal_error;
}
/* Initialize MM communication layer */
if (!mm_communicate_call_ep_init(&mm_communicate_call_ep,
(void *)mm_comm_buffer_region.base_addr,
mm_comm_buffer_region.region_size)) {
EMSG("Failed to init MM communicate call EP");
goto fatal_error;
}
/* Attach SMM variable service to MM communication layer */
mm_communicate_call_ep_attach_service(&mm_communicate_call_ep, &smm_variable_guid,
smm_var_service_interface);
/* End of boot phase */
result = ffa_msg_wait(&req_msg);
if (result != FFA_OK) {
EMSG("Failed to send message wait %d", result);
goto fatal_error;
}
while (1) {
if (FFA_IS_32_BIT_FUNC(req_msg.function_id)) {
EMSG("MM communicate over 32 bit FF-A messages is not supported");
ffa_msg_send_direct_resp_32(req_msg.destination_id, req_msg.source_id,
MM_RETURN_CODE_NOT_SUPPORTED, 0, 0, 0, 0,
&req_msg);
continue;
}
mm_communicate_call_ep_receive(&mm_communicate_call_ep, &req_msg, &resp_msg);
result = ffa_msg_send_direct_resp_64(req_msg.destination_id,
req_msg.source_id, resp_msg.args.args64[0],
resp_msg.args.args64[1], resp_msg.args.args64[2],
resp_msg.args.args64[3], resp_msg.args.args64[4],
&req_msg);
if (result != FFA_OK) {
EMSG("Failed to send direct response %d", result);
result = ffa_msg_wait(&req_msg);
if (result != FFA_OK) {
EMSG("Failed to send message wait %d", result);
goto fatal_error;
}
}
}
fatal_error:
/* SP is not viable */
EMSG("SMM gateway SP error");
while (1) {}
}
void sp_interrupt_handler(uint32_t interrupt_id)
{
(void)interrupt_id;
}
static bool sp_init(uint16_t *own_id)
{
sp_result sp_res = SP_RESULT_INTERNAL_ERROR;
static uint8_t tx_buffer[4096] __aligned(4096);
static uint8_t rx_buffer[4096] __aligned(4096);
sp_res = sp_rxtx_buffer_map(tx_buffer, rx_buffer, sizeof(rx_buffer));
if (sp_res != SP_RESULT_OK) {
EMSG("Failed to map RXTX buffers: %d", sp_res);
return false;
}
sp_res = sp_discovery_own_id_get(own_id);
if (sp_res != SP_RESULT_OK) {
EMSG("Failed to query own ID: %d", sp_res);
return false;
}
return true;
}