1 /*
2  * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <components/service/log/backend/uart/uart_backend.h>
8 #include <components/service/log/factory/log_factory.h>
9 #include <components/service/log/provider/log_provider.h>
10 #include <sp_api.h>
11 #include <sp_discovery.h>
12 #include <sp_messaging.h>
13 #include <sp_rxtx.h>
14 #include <trace.h>
15 
16 #include "config/loader/sp/sp_config_loader.h"
17 #include "config/ramstore/config_ramstore.h"
18 #include "rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.h"
19 
20 static bool sp_init(uint16_t *own_sp_id);
21 
sp_main(union ffa_boot_info * boot_info)22 void __noreturn sp_main(union ffa_boot_info *boot_info)
23 {
24 	struct rpc_service_interface *log_iface = NULL;
25 	struct ts_rpc_endpoint_sp rpc_endpoint = { 0 };
26 	struct sp_msg req_msg = { 0 };
27 	struct sp_msg resp_msg = { 0 };
28 	struct log_provider log_provider = { 0 };
29 	struct log_backend *log_backend = NULL;
30 	uint16_t own_id = 0;
31 	sp_result result = SP_RESULT_INTERNAL_ERROR;
32 	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
33 
34 	/* Boot */
35 	if (!sp_init(&own_id)) {
36 		EMSG("Failed to init SP");
37 		goto fatal_error;
38 	}
39 
40 	config_ramstore_init();
41 
42 	if (!sp_config_load(boot_info)) {
43 		EMSG("Failed to load SP config");
44 		goto fatal_error;
45 	}
46 
47 	log_backend = uart_backend_init(0);
48 	if (!log_backend) {
49 		EMSG("Failed to create log backend.");
50 		goto fatal_error;
51 	}
52 	log_iface = log_provider_init(&log_provider, log_backend);
53 
54 	if (!log_iface) {
55 		EMSG("Failed to init service provider");
56 		goto fatal_error;
57 	}
58 
59 	rpc_status = ts_rpc_endpoint_sp_init(&rpc_endpoint, 1, 16);
60 	if (rpc_status != RPC_SUCCESS) {
61 		EMSG("Failed to initialize RPC endpoint: %d", rpc_status);
62 		goto fatal_error;
63 	}
64 
65 	rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, log_iface);
66 	if (rpc_status != RPC_SUCCESS) {
67 		EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
68 		goto fatal_error;
69 	}
70 
71 	/* End of boot phase */
72 	result = sp_msg_wait(&req_msg);
73 	if (result != SP_RESULT_OK) {
74 		EMSG("Failed to send message wait %d", result);
75 		goto fatal_error;
76 	}
77 
78 	while (1) {
79 		ts_rpc_endpoint_sp_receive(&rpc_endpoint, &req_msg, &resp_msg);
80 
81 		result = sp_msg_send_direct_resp(&resp_msg, &req_msg);
82 		if (result != SP_RESULT_OK) {
83 			EMSG("Failed to send direct response %d", result);
84 			result = sp_msg_wait(&req_msg);
85 			if (result != SP_RESULT_OK) {
86 				EMSG("Failed to send message wait %d", result);
87 				goto fatal_error;
88 			}
89 		}
90 	}
91 
92 fatal_error:
93 	/* SP is not viable */
94 	EMSG("LOGGING SP error");
95 	while (1) {
96 	}
97 }
98 
sp_interrupt_handler(uint32_t interrupt_id)99 void sp_interrupt_handler(uint32_t interrupt_id)
100 {
101 	(void)interrupt_id;
102 }
103 
ffa_vm_created_handler(uint16_t vm_id,uint64_t handle)104 ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle)
105 {
106 	(void)vm_id;
107 	(void)handle;
108 
109 	return FFA_OK;
110 }
111 
ffa_vm_destroyed_handler(uint16_t vm_id,uint64_t handle)112 ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle)
113 {
114 	(void)vm_id;
115 	(void)handle;
116 
117 	return FFA_OK;
118 }
119 
sp_init(uint16_t * own_id)120 static bool sp_init(uint16_t *own_id)
121 {
122 	sp_result sp_res = SP_RESULT_INTERNAL_ERROR;
123 	static uint8_t tx_buffer[4096] __aligned(4096);
124 	static uint8_t rx_buffer[4096] __aligned(4096);
125 
126 	sp_res = sp_rxtx_buffer_map(tx_buffer, rx_buffer, sizeof(rx_buffer));
127 	if (sp_res != SP_RESULT_OK) {
128 		EMSG("Failed to map RXTX buffers: %d", sp_res);
129 		return false;
130 	}
131 
132 	sp_res = sp_discovery_own_id_get(own_id);
133 	if (sp_res != SP_RESULT_OK) {
134 		EMSG("Failed to query own ID: %d", sp_res);
135 		return false;
136 	}
137 
138 	return true;
139 }
140