xref: /aosp_15_r20/system/chre/platform/tinysys/host_link.cc (revision 84e339476a462649f82315436d70fd732297a399)
1*84e33947SAndroid Build Coastguard Worker /*
2*84e33947SAndroid Build Coastguard Worker  * Copyright (C) 2023 The Android Open Source Project
3*84e33947SAndroid Build Coastguard Worker  *
4*84e33947SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*84e33947SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*84e33947SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*84e33947SAndroid Build Coastguard Worker  *
8*84e33947SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*84e33947SAndroid Build Coastguard Worker  *
10*84e33947SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*84e33947SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*84e33947SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*84e33947SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*84e33947SAndroid Build Coastguard Worker  * limitations under the License.
15*84e33947SAndroid Build Coastguard Worker  */
16*84e33947SAndroid Build Coastguard Worker 
17*84e33947SAndroid Build Coastguard Worker #include "FreeRTOS.h"
18*84e33947SAndroid Build Coastguard Worker #include "encoding.h"
19*84e33947SAndroid Build Coastguard Worker #include "task.h"
20*84e33947SAndroid Build Coastguard Worker 
21*84e33947SAndroid Build Coastguard Worker #include "chre/core/event_loop_manager.h"
22*84e33947SAndroid Build Coastguard Worker #include "chre/core/host_comms_manager.h"
23*84e33947SAndroid Build Coastguard Worker #include "chre/platform/host_link.h"
24*84e33947SAndroid Build Coastguard Worker #include "chre/platform/log.h"
25*84e33947SAndroid Build Coastguard Worker #include "chre/platform/shared/host_protocol_chre.h"
26*84e33947SAndroid Build Coastguard Worker #include "chre/platform/shared/log_buffer_manager.h"
27*84e33947SAndroid Build Coastguard Worker #include "chre/platform/shared/nanoapp_load_manager.h"
28*84e33947SAndroid Build Coastguard Worker #include "chre/platform/system_time.h"
29*84e33947SAndroid Build Coastguard Worker #include "chre/platform/system_timer.h"
30*84e33947SAndroid Build Coastguard Worker #include "chre/util/flatbuffers/helpers.h"
31*84e33947SAndroid Build Coastguard Worker #include "chre/util/nested_data_ptr.h"
32*84e33947SAndroid Build Coastguard Worker #include "chre_api/chre.h"
33*84e33947SAndroid Build Coastguard Worker 
34*84e33947SAndroid Build Coastguard Worker #include "dma_api.h"
35*84e33947SAndroid Build Coastguard Worker #include "ipi.h"
36*84e33947SAndroid Build Coastguard Worker #include "ipi_id.h"
37*84e33947SAndroid Build Coastguard Worker #include "resource_req.h"
38*84e33947SAndroid Build Coastguard Worker #include "scp_dram_region.h"
39*84e33947SAndroid Build Coastguard Worker 
40*84e33947SAndroid Build Coastguard Worker // Because the LOGx macros are being redirected to logcat through
41*84e33947SAndroid Build Coastguard Worker // HostLink::sendLogMessageV2 and HostLink::send, calling them from
42*84e33947SAndroid Build Coastguard Worker // inside HostLink impl could result in endless recursion.
43*84e33947SAndroid Build Coastguard Worker // So redefine them to just printf function to SCP console.
44*84e33947SAndroid Build Coastguard Worker #if CHRE_MINIMUM_LOG_LEVEL >= CHRE_LOG_LEVEL_ERROR
45*84e33947SAndroid Build Coastguard Worker #undef LOGE
46*84e33947SAndroid Build Coastguard Worker #define LOGE(fmt, arg...) PRINTF_E("[CHRE]" fmt "\n", ##arg)
47*84e33947SAndroid Build Coastguard Worker #endif
48*84e33947SAndroid Build Coastguard Worker 
49*84e33947SAndroid Build Coastguard Worker #if CHRE_MINIMUM_LOG_LEVEL >= CHRE_LOG_LEVEL_WARN
50*84e33947SAndroid Build Coastguard Worker #undef LOGW
51*84e33947SAndroid Build Coastguard Worker #define LOGW(fmt, arg...) PRINTF_W("[CHRE]" fmt "\n", ##arg)
52*84e33947SAndroid Build Coastguard Worker #endif
53*84e33947SAndroid Build Coastguard Worker 
54*84e33947SAndroid Build Coastguard Worker #if CHRE_MINIMUM_LOG_LEVEL >= CHRE_LOG_LEVEL_INFO
55*84e33947SAndroid Build Coastguard Worker #undef LOGI
56*84e33947SAndroid Build Coastguard Worker #define LOGI(fmt, arg...) PRINTF_I("[CHRE]" fmt "\n", ##arg)
57*84e33947SAndroid Build Coastguard Worker #endif
58*84e33947SAndroid Build Coastguard Worker 
59*84e33947SAndroid Build Coastguard Worker #if CHRE_MINIMUM_LOG_LEVEL >= CHRE_LOG_LEVEL_DEBUG
60*84e33947SAndroid Build Coastguard Worker #undef LOGD
61*84e33947SAndroid Build Coastguard Worker #define LOGD(fmt, arg...) PRINTF_D("[CHRE]" fmt "\n", ##arg)
62*84e33947SAndroid Build Coastguard Worker #endif
63*84e33947SAndroid Build Coastguard Worker 
64*84e33947SAndroid Build Coastguard Worker #if CHRE_MINIMUM_LOG_LEVEL >= CHRE_LOG_LEVEL_VERBOSE
65*84e33947SAndroid Build Coastguard Worker #undef LOGV
66*84e33947SAndroid Build Coastguard Worker #define LOGV(fmt, arg...) PRINTF_D("[CHRE]" fmt "\n", ##arg)
67*84e33947SAndroid Build Coastguard Worker #endif
68*84e33947SAndroid Build Coastguard Worker 
69*84e33947SAndroid Build Coastguard Worker namespace chre {
70*84e33947SAndroid Build Coastguard Worker namespace {
71*84e33947SAndroid Build Coastguard Worker 
72*84e33947SAndroid Build Coastguard Worker struct UnloadNanoappCallbackData {
73*84e33947SAndroid Build Coastguard Worker   uint64_t appId;
74*84e33947SAndroid Build Coastguard Worker   uint32_t transactionId;
75*84e33947SAndroid Build Coastguard Worker   uint16_t hostClientId;
76*84e33947SAndroid Build Coastguard Worker   bool allowSystemNanoappUnload;
77*84e33947SAndroid Build Coastguard Worker };
78*84e33947SAndroid Build Coastguard Worker 
79*84e33947SAndroid Build Coastguard Worker SRAM_REGION_BSS uint32_t gChreIpiRecvData[2];
80*84e33947SAndroid Build Coastguard Worker 
81*84e33947SAndroid Build Coastguard Worker // SCP reply ack data (AP to SCP)
82*84e33947SAndroid Build Coastguard Worker SRAM_REGION_BSS uint32_t gChreIpiAckToHost[2];
83*84e33947SAndroid Build Coastguard Worker 
84*84e33947SAndroid Build Coastguard Worker // SCP get ack data from AP (SCP to AP)
85*84e33947SAndroid Build Coastguard Worker SRAM_REGION_BSS int gChreIpiAckFromHost[2];
86*84e33947SAndroid Build Coastguard Worker 
87*84e33947SAndroid Build Coastguard Worker #ifdef SCP_CHRE_USE_DMA
88*84e33947SAndroid Build Coastguard Worker // The min total size of a message to trigger DMA for sending/receiving.
89*84e33947SAndroid Build Coastguard Worker constexpr uint32_t kMinMessageSizeForDma = 0x1000;  // 4k
90*84e33947SAndroid Build Coastguard Worker #endif
91*84e33947SAndroid Build Coastguard Worker 
92*84e33947SAndroid Build Coastguard Worker // The buffer used to receive messages from AP.
93*84e33947SAndroid Build Coastguard Worker // The size should be consistent with the max sending size on the host side.
94*84e33947SAndroid Build Coastguard Worker constexpr uint32_t kChreIpiRecvBufferSize = 0x8000;  // 32k
95*84e33947SAndroid Build Coastguard Worker DRAM_REGION_VARIABLE uint8_t gChreRecvBuffer[kChreIpiRecvBufferSize]
96*84e33947SAndroid Build Coastguard Worker     __attribute__((aligned(CACHE_LINE_SIZE)));
97*84e33947SAndroid Build Coastguard Worker 
98*84e33947SAndroid Build Coastguard Worker #ifdef SCP_CHRE_USE_DMA
99*84e33947SAndroid Build Coastguard Worker // Rounds up the value to be aligned with CACHE_LINE_SIZE.
alignToCacheLine(uint32_t value)100*84e33947SAndroid Build Coastguard Worker static inline uint32_t alignToCacheLine(uint32_t value) {
101*84e33947SAndroid Build Coastguard Worker   // alignment must be a power of 2.
102*84e33947SAndroid Build Coastguard Worker   static_assert(CACHE_LINE_SIZE > 0 &&
103*84e33947SAndroid Build Coastguard Worker                 (CACHE_LINE_SIZE & (CACHE_LINE_SIZE - 1)) == 0);
104*84e33947SAndroid Build Coastguard Worker   return (value + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1);
105*84e33947SAndroid Build Coastguard Worker }
106*84e33947SAndroid Build Coastguard Worker #endif
107*84e33947SAndroid Build Coastguard Worker 
108*84e33947SAndroid Build Coastguard Worker void *gChreSubregionRecvAddr;
109*84e33947SAndroid Build Coastguard Worker size_t gChreSubregionRecvSize;
110*84e33947SAndroid Build Coastguard Worker void *gChreSubregionSendAddr;
111*84e33947SAndroid Build Coastguard Worker size_t gChreSubregionSendSize;
112*84e33947SAndroid Build Coastguard Worker 
113*84e33947SAndroid Build Coastguard Worker #define SCP_CHRE_MAGIC 0x67728269
114*84e33947SAndroid Build Coastguard Worker struct ScpChreIpiMsg {
115*84e33947SAndroid Build Coastguard Worker   uint32_t magic;
116*84e33947SAndroid Build Coastguard Worker   uint32_t size;
117*84e33947SAndroid Build Coastguard Worker };
118*84e33947SAndroid Build Coastguard Worker 
119*84e33947SAndroid Build Coastguard Worker struct NanoappListData {
120*84e33947SAndroid Build Coastguard Worker   ChreFlatBufferBuilder *builder;
121*84e33947SAndroid Build Coastguard Worker   DynamicVector<NanoappListEntryOffset> nanoappEntries;
122*84e33947SAndroid Build Coastguard Worker   uint16_t hostClientId;
123*84e33947SAndroid Build Coastguard Worker };
124*84e33947SAndroid Build Coastguard Worker 
125*84e33947SAndroid Build Coastguard Worker enum class PendingMessageType {
126*84e33947SAndroid Build Coastguard Worker   Shutdown,
127*84e33947SAndroid Build Coastguard Worker   NanoappMessageToHost,
128*84e33947SAndroid Build Coastguard Worker   HubInfoResponse,
129*84e33947SAndroid Build Coastguard Worker   NanoappListResponse,
130*84e33947SAndroid Build Coastguard Worker   LoadNanoappResponse,
131*84e33947SAndroid Build Coastguard Worker   UnloadNanoappResponse,
132*84e33947SAndroid Build Coastguard Worker   DebugDumpData,
133*84e33947SAndroid Build Coastguard Worker   DebugDumpResponse,
134*84e33947SAndroid Build Coastguard Worker   TimeSyncRequest,
135*84e33947SAndroid Build Coastguard Worker   LowPowerMicAccessRequest,
136*84e33947SAndroid Build Coastguard Worker   LowPowerMicAccessRelease,
137*84e33947SAndroid Build Coastguard Worker   EncodedLogMessage,
138*84e33947SAndroid Build Coastguard Worker   SelfTestResponse,
139*84e33947SAndroid Build Coastguard Worker   MetricLog,
140*84e33947SAndroid Build Coastguard Worker   NanConfigurationRequest,
141*84e33947SAndroid Build Coastguard Worker   PulseRequest,
142*84e33947SAndroid Build Coastguard Worker   PulseResponse,
143*84e33947SAndroid Build Coastguard Worker   NanoappTokenDatabaseInfo,
144*84e33947SAndroid Build Coastguard Worker   MessageDeliveryStatus,
145*84e33947SAndroid Build Coastguard Worker };
146*84e33947SAndroid Build Coastguard Worker 
147*84e33947SAndroid Build Coastguard Worker struct PendingMessage {
PendingMessagechre::__anond3ca4bff0111::PendingMessage148*84e33947SAndroid Build Coastguard Worker   PendingMessage(PendingMessageType msgType, uint16_t hostClientId) {
149*84e33947SAndroid Build Coastguard Worker     type = msgType;
150*84e33947SAndroid Build Coastguard Worker     data.hostClientId = hostClientId;
151*84e33947SAndroid Build Coastguard Worker   }
152*84e33947SAndroid Build Coastguard Worker 
PendingMessagechre::__anond3ca4bff0111::PendingMessage153*84e33947SAndroid Build Coastguard Worker   PendingMessage(PendingMessageType msgType,
154*84e33947SAndroid Build Coastguard Worker                  const HostMessage *msgToHost = nullptr) {
155*84e33947SAndroid Build Coastguard Worker     type = msgType;
156*84e33947SAndroid Build Coastguard Worker     data.msgToHost = msgToHost;
157*84e33947SAndroid Build Coastguard Worker   }
158*84e33947SAndroid Build Coastguard Worker 
PendingMessagechre::__anond3ca4bff0111::PendingMessage159*84e33947SAndroid Build Coastguard Worker   PendingMessage(PendingMessageType msgType, ChreFlatBufferBuilder *builder) {
160*84e33947SAndroid Build Coastguard Worker     type = msgType;
161*84e33947SAndroid Build Coastguard Worker     data.builder = builder;
162*84e33947SAndroid Build Coastguard Worker   }
163*84e33947SAndroid Build Coastguard Worker 
164*84e33947SAndroid Build Coastguard Worker   PendingMessageType type;
165*84e33947SAndroid Build Coastguard Worker   union {
166*84e33947SAndroid Build Coastguard Worker     const HostMessage *msgToHost;
167*84e33947SAndroid Build Coastguard Worker     uint16_t hostClientId;
168*84e33947SAndroid Build Coastguard Worker     ChreFlatBufferBuilder *builder;
169*84e33947SAndroid Build Coastguard Worker   } data;
170*84e33947SAndroid Build Coastguard Worker };
171*84e33947SAndroid Build Coastguard Worker 
172*84e33947SAndroid Build Coastguard Worker constexpr size_t kOutboundQueueSize = 100;
173*84e33947SAndroid Build Coastguard Worker SRAM_REGION_VARIABLE FixedSizeBlockingQueue<PendingMessage, kOutboundQueueSize>
174*84e33947SAndroid Build Coastguard Worker     gOutboundQueue;
175*84e33947SAndroid Build Coastguard Worker 
176*84e33947SAndroid Build Coastguard Worker typedef void(MessageBuilderFunction)(ChreFlatBufferBuilder &builder,
177*84e33947SAndroid Build Coastguard Worker                                      void *cookie);
178*84e33947SAndroid Build Coastguard Worker 
getHostCommsManager()179*84e33947SAndroid Build Coastguard Worker inline HostCommsManager &getHostCommsManager() {
180*84e33947SAndroid Build Coastguard Worker   return EventLoopManagerSingleton::get()->getHostCommsManager();
181*84e33947SAndroid Build Coastguard Worker }
182*84e33947SAndroid Build Coastguard Worker 
generateMessageFromBuilder(ChreFlatBufferBuilder * builder)183*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION bool generateMessageFromBuilder(
184*84e33947SAndroid Build Coastguard Worker     ChreFlatBufferBuilder *builder) {
185*84e33947SAndroid Build Coastguard Worker   CHRE_ASSERT(builder != nullptr);
186*84e33947SAndroid Build Coastguard Worker   LOGV("%s: message size %d", __func__, builder->GetSize());
187*84e33947SAndroid Build Coastguard Worker   bool result =
188*84e33947SAndroid Build Coastguard Worker       HostLinkBase::send(builder->GetBufferPointer(), builder->GetSize());
189*84e33947SAndroid Build Coastguard Worker 
190*84e33947SAndroid Build Coastguard Worker   // clean up
191*84e33947SAndroid Build Coastguard Worker   builder->~ChreFlatBufferBuilder();
192*84e33947SAndroid Build Coastguard Worker   memoryFree(builder);
193*84e33947SAndroid Build Coastguard Worker   return result;
194*84e33947SAndroid Build Coastguard Worker }
195*84e33947SAndroid Build Coastguard Worker 
generateMessageToHost(const HostMessage * message)196*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION bool generateMessageToHost(const HostMessage *message) {
197*84e33947SAndroid Build Coastguard Worker   LOGV("%s: message size %zu", __func__, message->message.size());
198*84e33947SAndroid Build Coastguard Worker   // TODO(b/285219398): ideally we'd construct our flatbuffer directly in the
199*84e33947SAndroid Build Coastguard Worker   // host-supplied buffer
200*84e33947SAndroid Build Coastguard Worker   constexpr size_t kFixedReserveSize = 88;
201*84e33947SAndroid Build Coastguard Worker   ChreFlatBufferBuilder builder(message->message.size() + kFixedReserveSize);
202*84e33947SAndroid Build Coastguard Worker   HostProtocolChre::encodeNanoappMessage(
203*84e33947SAndroid Build Coastguard Worker       builder, message->appId, message->toHostData.messageType,
204*84e33947SAndroid Build Coastguard Worker       message->toHostData.hostEndpoint, message->message.data(),
205*84e33947SAndroid Build Coastguard Worker       message->message.size(), message->toHostData.appPermissions,
206*84e33947SAndroid Build Coastguard Worker       message->toHostData.messagePermissions, message->toHostData.wokeHost);
207*84e33947SAndroid Build Coastguard Worker   bool result =
208*84e33947SAndroid Build Coastguard Worker       HostLinkBase::send(builder.GetBufferPointer(), builder.GetSize());
209*84e33947SAndroid Build Coastguard Worker 
210*84e33947SAndroid Build Coastguard Worker   // clean up
211*84e33947SAndroid Build Coastguard Worker   getHostCommsManager().onMessageToHostComplete(message);
212*84e33947SAndroid Build Coastguard Worker   return result;
213*84e33947SAndroid Build Coastguard Worker }
214*84e33947SAndroid Build Coastguard Worker 
generateHubInfoResponse(uint16_t hostClientId)215*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION int generateHubInfoResponse(uint16_t hostClientId) {
216*84e33947SAndroid Build Coastguard Worker   constexpr size_t kInitialBufferSize = 192;
217*84e33947SAndroid Build Coastguard Worker 
218*84e33947SAndroid Build Coastguard Worker   constexpr char kHubName[] = "CHRE on Tinysys";
219*84e33947SAndroid Build Coastguard Worker   constexpr char kVendor[] = "Google";
220*84e33947SAndroid Build Coastguard Worker   constexpr char kToolchain[] =
221*84e33947SAndroid Build Coastguard Worker       "Clang " STRINGIFY(__clang_major__) "." STRINGIFY(
222*84e33947SAndroid Build Coastguard Worker           __clang_minor__) "." STRINGIFY(__clang_patchlevel__);
223*84e33947SAndroid Build Coastguard Worker   constexpr uint32_t kLegacyPlatformVersion = 0;
224*84e33947SAndroid Build Coastguard Worker   constexpr uint32_t kLegacyToolchainVersion =
225*84e33947SAndroid Build Coastguard Worker       ((__clang_major__ & 0xFF) << 24) | ((__clang_minor__ & 0xFF) << 16) |
226*84e33947SAndroid Build Coastguard Worker       (__clang_patchlevel__ & 0xFFFF);
227*84e33947SAndroid Build Coastguard Worker   constexpr float kPeakMips = 350;
228*84e33947SAndroid Build Coastguard Worker   constexpr float kStoppedPower = 0;
229*84e33947SAndroid Build Coastguard Worker   constexpr float kSleepPower = 1;
230*84e33947SAndroid Build Coastguard Worker   constexpr float kPeakPower = 15;
231*84e33947SAndroid Build Coastguard Worker   bool supportsReliableMessages =
232*84e33947SAndroid Build Coastguard Worker       IS_BIT_SET(chreGetCapabilities(), CHRE_CAPABILITIES_RELIABLE_MESSAGES);
233*84e33947SAndroid Build Coastguard Worker 
234*84e33947SAndroid Build Coastguard Worker   // Note that this may execute prior to EventLoopManager::lateInit() completing
235*84e33947SAndroid Build Coastguard Worker   ChreFlatBufferBuilder builder(kInitialBufferSize);
236*84e33947SAndroid Build Coastguard Worker   HostProtocolChre::encodeHubInfoResponse(
237*84e33947SAndroid Build Coastguard Worker       builder, kHubName, kVendor, kToolchain, kLegacyPlatformVersion,
238*84e33947SAndroid Build Coastguard Worker       kLegacyToolchainVersion, kPeakMips, kStoppedPower, kSleepPower,
239*84e33947SAndroid Build Coastguard Worker       kPeakPower, chreGetMessageToHostMaxSize(), chreGetPlatformId(),
240*84e33947SAndroid Build Coastguard Worker       chreGetVersion(), hostClientId, supportsReliableMessages);
241*84e33947SAndroid Build Coastguard Worker 
242*84e33947SAndroid Build Coastguard Worker   return HostLinkBase::send(builder.GetBufferPointer(), builder.GetSize());
243*84e33947SAndroid Build Coastguard Worker }
244*84e33947SAndroid Build Coastguard Worker 
dequeueMessage(PendingMessage pendingMsg)245*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION bool dequeueMessage(PendingMessage pendingMsg) {
246*84e33947SAndroid Build Coastguard Worker   LOGV("%s: message type %d", __func__, pendingMsg.type);
247*84e33947SAndroid Build Coastguard Worker   bool result = false;
248*84e33947SAndroid Build Coastguard Worker   switch (pendingMsg.type) {
249*84e33947SAndroid Build Coastguard Worker     case PendingMessageType::NanoappMessageToHost:
250*84e33947SAndroid Build Coastguard Worker       result = generateMessageToHost(pendingMsg.data.msgToHost);
251*84e33947SAndroid Build Coastguard Worker       break;
252*84e33947SAndroid Build Coastguard Worker 
253*84e33947SAndroid Build Coastguard Worker     case PendingMessageType::HubInfoResponse:
254*84e33947SAndroid Build Coastguard Worker       result = generateHubInfoResponse(pendingMsg.data.hostClientId);
255*84e33947SAndroid Build Coastguard Worker       break;
256*84e33947SAndroid Build Coastguard Worker     default:
257*84e33947SAndroid Build Coastguard Worker       result = generateMessageFromBuilder(pendingMsg.data.builder);
258*84e33947SAndroid Build Coastguard Worker       break;
259*84e33947SAndroid Build Coastguard Worker   }
260*84e33947SAndroid Build Coastguard Worker   return result;
261*84e33947SAndroid Build Coastguard Worker }
262*84e33947SAndroid Build Coastguard Worker 
263*84e33947SAndroid Build Coastguard Worker /**
264*84e33947SAndroid Build Coastguard Worker  * Wrapper function to enqueue a message on the outbound message queue. All
265*84e33947SAndroid Build Coastguard Worker  * outgoing message to the host must be called through this function.
266*84e33947SAndroid Build Coastguard Worker  *
267*84e33947SAndroid Build Coastguard Worker  * @param message The message to send to host.
268*84e33947SAndroid Build Coastguard Worker  *
269*84e33947SAndroid Build Coastguard Worker  * @return true if the message was successfully added to the queue.
270*84e33947SAndroid Build Coastguard Worker  */
enqueueMessage(PendingMessage pendingMsg)271*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION bool enqueueMessage(PendingMessage pendingMsg) {
272*84e33947SAndroid Build Coastguard Worker   return gOutboundQueue.push(pendingMsg);
273*84e33947SAndroid Build Coastguard Worker }
274*84e33947SAndroid Build Coastguard Worker 
275*84e33947SAndroid Build Coastguard Worker /**
276*84e33947SAndroid Build Coastguard Worker  * Helper function that takes care of the boilerplate for allocating a
277*84e33947SAndroid Build Coastguard Worker  * ChreFlatBufferBuilder on the heap and adding it to the outbound message
278*84e33947SAndroid Build Coastguard Worker  * queue.
279*84e33947SAndroid Build Coastguard Worker  *
280*84e33947SAndroid Build Coastguard Worker  * @param msgType Identifies the message while in the outbound queue
281*84e33947SAndroid Build Coastguard Worker  * @param initialBufferSize Number of bytes to reserve when first allocating the
282*84e33947SAndroid Build Coastguard Worker  *        ChreFlatBufferBuilder
283*84e33947SAndroid Build Coastguard Worker  * @param buildMsgFunc Synchronous callback used to encode the FlatBuffer
284*84e33947SAndroid Build Coastguard Worker  *        message. Will not be invoked if allocation fails.
285*84e33947SAndroid Build Coastguard Worker  * @param cookie Opaque pointer that will be passed through to buildMsgFunc
286*84e33947SAndroid Build Coastguard Worker  *
287*84e33947SAndroid Build Coastguard Worker  * @return true if the message was successfully added to the queue
288*84e33947SAndroid Build Coastguard Worker  */
buildAndEnqueueMessage(PendingMessageType msgType,size_t initialBufferSize,MessageBuilderFunction * msgBuilder,void * cookie)289*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION bool buildAndEnqueueMessage(
290*84e33947SAndroid Build Coastguard Worker     PendingMessageType msgType, size_t initialBufferSize,
291*84e33947SAndroid Build Coastguard Worker     MessageBuilderFunction *msgBuilder, void *cookie) {
292*84e33947SAndroid Build Coastguard Worker   LOGV("%s: message type %d, size %zu", __func__, msgType, initialBufferSize);
293*84e33947SAndroid Build Coastguard Worker   bool pushed = false;
294*84e33947SAndroid Build Coastguard Worker 
295*84e33947SAndroid Build Coastguard Worker   auto builder = MakeUnique<ChreFlatBufferBuilder>(initialBufferSize);
296*84e33947SAndroid Build Coastguard Worker   if (builder.isNull()) {
297*84e33947SAndroid Build Coastguard Worker     LOGE("Couldn't allocate memory for message type %d",
298*84e33947SAndroid Build Coastguard Worker          static_cast<int>(msgType));
299*84e33947SAndroid Build Coastguard Worker   } else {
300*84e33947SAndroid Build Coastguard Worker     msgBuilder(*builder, cookie);
301*84e33947SAndroid Build Coastguard Worker 
302*84e33947SAndroid Build Coastguard Worker     if (!enqueueMessage(PendingMessage(msgType, builder.get()))) {
303*84e33947SAndroid Build Coastguard Worker       LOGE("Couldn't push message type %d to outbound queue",
304*84e33947SAndroid Build Coastguard Worker            static_cast<int>(msgType));
305*84e33947SAndroid Build Coastguard Worker     } else {
306*84e33947SAndroid Build Coastguard Worker       builder.release();
307*84e33947SAndroid Build Coastguard Worker       pushed = true;
308*84e33947SAndroid Build Coastguard Worker     }
309*84e33947SAndroid Build Coastguard Worker   }
310*84e33947SAndroid Build Coastguard Worker 
311*84e33947SAndroid Build Coastguard Worker   return pushed;
312*84e33947SAndroid Build Coastguard Worker }
313*84e33947SAndroid Build Coastguard Worker 
314*84e33947SAndroid Build Coastguard Worker /**
315*84e33947SAndroid Build Coastguard Worker  * FlatBuffer message builder callback used with handleNanoappListRequest()
316*84e33947SAndroid Build Coastguard Worker  */
buildPulseResponse(ChreFlatBufferBuilder & builder,void *)317*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void buildPulseResponse(ChreFlatBufferBuilder &builder,
318*84e33947SAndroid Build Coastguard Worker                                              void * /*cookie*/) {
319*84e33947SAndroid Build Coastguard Worker   HostProtocolChre::encodePulseResponse(builder);
320*84e33947SAndroid Build Coastguard Worker }
321*84e33947SAndroid Build Coastguard Worker 
322*84e33947SAndroid Build Coastguard Worker /**
323*84e33947SAndroid Build Coastguard Worker  * FlatBuffer message builder callback used with handleNanoappListRequest()
324*84e33947SAndroid Build Coastguard Worker  */
buildNanoappListResponse(ChreFlatBufferBuilder & builder,void * cookie)325*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void buildNanoappListResponse(
326*84e33947SAndroid Build Coastguard Worker     ChreFlatBufferBuilder &builder, void *cookie) {
327*84e33947SAndroid Build Coastguard Worker   LOGV("%s", __func__);
328*84e33947SAndroid Build Coastguard Worker   auto nanoappAdderCallback = [](const Nanoapp *nanoapp, void *data) {
329*84e33947SAndroid Build Coastguard Worker     auto *cbData = static_cast<NanoappListData *>(data);
330*84e33947SAndroid Build Coastguard Worker     HostProtocolChre::addNanoappListEntry(
331*84e33947SAndroid Build Coastguard Worker         *(cbData->builder), cbData->nanoappEntries, nanoapp->getAppId(),
332*84e33947SAndroid Build Coastguard Worker         nanoapp->getAppVersion(), true /*enabled*/, nanoapp->isSystemNanoapp(),
333*84e33947SAndroid Build Coastguard Worker         nanoapp->getAppPermissions(), nanoapp->getRpcServices());
334*84e33947SAndroid Build Coastguard Worker   };
335*84e33947SAndroid Build Coastguard Worker 
336*84e33947SAndroid Build Coastguard Worker   // Add a NanoappListEntry to the FlatBuffer for each nanoapp
337*84e33947SAndroid Build Coastguard Worker   auto *cbData = static_cast<NanoappListData *>(cookie);
338*84e33947SAndroid Build Coastguard Worker   cbData->builder = &builder;
339*84e33947SAndroid Build Coastguard Worker   EventLoop &eventLoop = EventLoopManagerSingleton::get()->getEventLoop();
340*84e33947SAndroid Build Coastguard Worker   eventLoop.forEachNanoapp(nanoappAdderCallback, cbData);
341*84e33947SAndroid Build Coastguard Worker   HostProtocolChre::finishNanoappListResponse(builder, cbData->nanoappEntries,
342*84e33947SAndroid Build Coastguard Worker                                               cbData->hostClientId);
343*84e33947SAndroid Build Coastguard Worker }
344*84e33947SAndroid Build Coastguard Worker 
handleUnloadNanoappCallback(uint16_t,void * data,void *)345*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void handleUnloadNanoappCallback(uint16_t /*type*/,
346*84e33947SAndroid Build Coastguard Worker                                                       void *data,
347*84e33947SAndroid Build Coastguard Worker                                                       void * /*extraData*/) {
348*84e33947SAndroid Build Coastguard Worker   auto *cbData = static_cast<UnloadNanoappCallbackData *>(data);
349*84e33947SAndroid Build Coastguard Worker   bool success = false;
350*84e33947SAndroid Build Coastguard Worker   uint16_t instanceId;
351*84e33947SAndroid Build Coastguard Worker   EventLoop &eventLoop = EventLoopManagerSingleton::get()->getEventLoop();
352*84e33947SAndroid Build Coastguard Worker   if (!eventLoop.findNanoappInstanceIdByAppId(cbData->appId, &instanceId)) {
353*84e33947SAndroid Build Coastguard Worker     LOGE("Couldn't unload app ID 0x%016" PRIx64 ": not found", cbData->appId);
354*84e33947SAndroid Build Coastguard Worker   } else {
355*84e33947SAndroid Build Coastguard Worker     success =
356*84e33947SAndroid Build Coastguard Worker         eventLoop.unloadNanoapp(instanceId, cbData->allowSystemNanoappUnload);
357*84e33947SAndroid Build Coastguard Worker   }
358*84e33947SAndroid Build Coastguard Worker 
359*84e33947SAndroid Build Coastguard Worker   constexpr size_t kInitialBufferSize = 52;
360*84e33947SAndroid Build Coastguard Worker   auto builder = MakeUnique<ChreFlatBufferBuilder>(kInitialBufferSize);
361*84e33947SAndroid Build Coastguard Worker   HostProtocolChre::encodeUnloadNanoappResponse(*builder, cbData->hostClientId,
362*84e33947SAndroid Build Coastguard Worker                                                 cbData->transactionId, success);
363*84e33947SAndroid Build Coastguard Worker 
364*84e33947SAndroid Build Coastguard Worker   if (!enqueueMessage(PendingMessage(PendingMessageType::UnloadNanoappResponse,
365*84e33947SAndroid Build Coastguard Worker                                      builder.get()))) {
366*84e33947SAndroid Build Coastguard Worker     LOGE("Failed to send unload response to host: %x transactionID: 0x%x",
367*84e33947SAndroid Build Coastguard Worker          cbData->hostClientId, cbData->transactionId);
368*84e33947SAndroid Build Coastguard Worker   } else {
369*84e33947SAndroid Build Coastguard Worker     builder.release();
370*84e33947SAndroid Build Coastguard Worker   }
371*84e33947SAndroid Build Coastguard Worker 
372*84e33947SAndroid Build Coastguard Worker   memoryFree(data);
373*84e33947SAndroid Build Coastguard Worker }
374*84e33947SAndroid Build Coastguard Worker 
sendDebugDumpData(uint16_t hostClientId,const char * debugStr,size_t debugStrSize)375*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void sendDebugDumpData(uint16_t hostClientId,
376*84e33947SAndroid Build Coastguard Worker                                             const char *debugStr,
377*84e33947SAndroid Build Coastguard Worker                                             size_t debugStrSize) {
378*84e33947SAndroid Build Coastguard Worker   struct DebugDumpMessageData {
379*84e33947SAndroid Build Coastguard Worker     uint16_t hostClientId;
380*84e33947SAndroid Build Coastguard Worker     const char *debugStr;
381*84e33947SAndroid Build Coastguard Worker     size_t debugStrSize;
382*84e33947SAndroid Build Coastguard Worker   };
383*84e33947SAndroid Build Coastguard Worker 
384*84e33947SAndroid Build Coastguard Worker   auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
385*84e33947SAndroid Build Coastguard Worker     const auto *data = static_cast<const DebugDumpMessageData *>(cookie);
386*84e33947SAndroid Build Coastguard Worker     HostProtocolChre::encodeDebugDumpData(builder, data->hostClientId,
387*84e33947SAndroid Build Coastguard Worker                                           data->debugStr, data->debugStrSize);
388*84e33947SAndroid Build Coastguard Worker   };
389*84e33947SAndroid Build Coastguard Worker 
390*84e33947SAndroid Build Coastguard Worker   constexpr size_t kFixedSizePortion = 52;
391*84e33947SAndroid Build Coastguard Worker   DebugDumpMessageData data;
392*84e33947SAndroid Build Coastguard Worker   data.hostClientId = hostClientId;
393*84e33947SAndroid Build Coastguard Worker   data.debugStr = debugStr;
394*84e33947SAndroid Build Coastguard Worker   data.debugStrSize = debugStrSize;
395*84e33947SAndroid Build Coastguard Worker   buildAndEnqueueMessage(PendingMessageType::DebugDumpData,
396*84e33947SAndroid Build Coastguard Worker                          kFixedSizePortion + debugStrSize, msgBuilder, &data);
397*84e33947SAndroid Build Coastguard Worker }
398*84e33947SAndroid Build Coastguard Worker 
sendDebugDumpResponse(uint16_t hostClientId,bool success,uint32_t dataCount)399*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void sendDebugDumpResponse(uint16_t hostClientId,
400*84e33947SAndroid Build Coastguard Worker                                                 bool success,
401*84e33947SAndroid Build Coastguard Worker                                                 uint32_t dataCount) {
402*84e33947SAndroid Build Coastguard Worker   struct DebugDumpResponseData {
403*84e33947SAndroid Build Coastguard Worker     uint16_t hostClientId;
404*84e33947SAndroid Build Coastguard Worker     bool success;
405*84e33947SAndroid Build Coastguard Worker     uint32_t dataCount;
406*84e33947SAndroid Build Coastguard Worker   };
407*84e33947SAndroid Build Coastguard Worker 
408*84e33947SAndroid Build Coastguard Worker   auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
409*84e33947SAndroid Build Coastguard Worker     const auto *data = static_cast<const DebugDumpResponseData *>(cookie);
410*84e33947SAndroid Build Coastguard Worker     HostProtocolChre::encodeDebugDumpResponse(builder, data->hostClientId,
411*84e33947SAndroid Build Coastguard Worker                                               data->success, data->dataCount);
412*84e33947SAndroid Build Coastguard Worker   };
413*84e33947SAndroid Build Coastguard Worker 
414*84e33947SAndroid Build Coastguard Worker   constexpr size_t kInitialSize = 52;
415*84e33947SAndroid Build Coastguard Worker   DebugDumpResponseData data;
416*84e33947SAndroid Build Coastguard Worker   data.hostClientId = hostClientId;
417*84e33947SAndroid Build Coastguard Worker   data.success = success;
418*84e33947SAndroid Build Coastguard Worker   data.dataCount = dataCount;
419*84e33947SAndroid Build Coastguard Worker   buildAndEnqueueMessage(PendingMessageType::DebugDumpResponse, kInitialSize,
420*84e33947SAndroid Build Coastguard Worker                          msgBuilder, &data);
421*84e33947SAndroid Build Coastguard Worker }
422*84e33947SAndroid Build Coastguard Worker }  // anonymous namespace
423*84e33947SAndroid Build Coastguard Worker 
sendDebugDumpResultToHost(uint16_t hostClientId,const char * debugStr,size_t debugStrSize,bool complete,uint32_t dataCount)424*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void sendDebugDumpResultToHost(uint16_t hostClientId,
425*84e33947SAndroid Build Coastguard Worker                                                     const char *debugStr,
426*84e33947SAndroid Build Coastguard Worker                                                     size_t debugStrSize,
427*84e33947SAndroid Build Coastguard Worker                                                     bool complete,
428*84e33947SAndroid Build Coastguard Worker                                                     uint32_t dataCount) {
429*84e33947SAndroid Build Coastguard Worker   LOGV("%s: host client id %d", __func__, hostClientId);
430*84e33947SAndroid Build Coastguard Worker   if (debugStrSize > 0) {
431*84e33947SAndroid Build Coastguard Worker     sendDebugDumpData(hostClientId, debugStr, debugStrSize);
432*84e33947SAndroid Build Coastguard Worker   }
433*84e33947SAndroid Build Coastguard Worker   if (complete) {
434*84e33947SAndroid Build Coastguard Worker     sendDebugDumpResponse(hostClientId, /* success= */ true, dataCount);
435*84e33947SAndroid Build Coastguard Worker   }
436*84e33947SAndroid Build Coastguard Worker }
437*84e33947SAndroid Build Coastguard Worker 
HostLinkBase()438*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION HostLinkBase::HostLinkBase() {
439*84e33947SAndroid Build Coastguard Worker   LOGV("HostLinkBase::%s", __func__);
440*84e33947SAndroid Build Coastguard Worker   initializeIpi();
441*84e33947SAndroid Build Coastguard Worker }
442*84e33947SAndroid Build Coastguard Worker 
~HostLinkBase()443*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION HostLinkBase::~HostLinkBase() {
444*84e33947SAndroid Build Coastguard Worker   LOGV("HostLinkBase::%s", __func__);
445*84e33947SAndroid Build Coastguard Worker }
446*84e33947SAndroid Build Coastguard Worker 
vChreReceiveTask(void * pvParameters)447*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostLinkBase::vChreReceiveTask(void *pvParameters) {
448*84e33947SAndroid Build Coastguard Worker   int i = 0;
449*84e33947SAndroid Build Coastguard Worker   int ret = 0;
450*84e33947SAndroid Build Coastguard Worker 
451*84e33947SAndroid Build Coastguard Worker   LOGV("%s", __func__);
452*84e33947SAndroid Build Coastguard Worker   while (true) {
453*84e33947SAndroid Build Coastguard Worker     LOGV("%s calling ipi_recv_reply(), Cnt=%d", __func__, i++);
454*84e33947SAndroid Build Coastguard Worker     ret = ipi_recv_reply(IPI_IN_C_HOST_SCP_CHRE, (void *)&gChreIpiAckToHost[0],
455*84e33947SAndroid Build Coastguard Worker                          1);
456*84e33947SAndroid Build Coastguard Worker     if (ret != IPI_ACTION_DONE)
457*84e33947SAndroid Build Coastguard Worker       LOGE("%s ipi_recv_reply() ret = %d", __func__, ret);
458*84e33947SAndroid Build Coastguard Worker     LOGV("%s reply_end", __func__);
459*84e33947SAndroid Build Coastguard Worker   }
460*84e33947SAndroid Build Coastguard Worker }
461*84e33947SAndroid Build Coastguard Worker 
vChreSendTask(void * pvParameters)462*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostLinkBase::vChreSendTask(void *pvParameters) {
463*84e33947SAndroid Build Coastguard Worker   while (true) {
464*84e33947SAndroid Build Coastguard Worker     auto msg = gOutboundQueue.pop();
465*84e33947SAndroid Build Coastguard Worker     dequeueMessage(msg);
466*84e33947SAndroid Build Coastguard Worker   }
467*84e33947SAndroid Build Coastguard Worker }
468*84e33947SAndroid Build Coastguard Worker 
chreIpiHandler(unsigned int id,void * prdata,void * data,unsigned int len)469*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostLinkBase::chreIpiHandler(unsigned int id,
470*84e33947SAndroid Build Coastguard Worker                                                        void *prdata, void *data,
471*84e33947SAndroid Build Coastguard Worker                                                        unsigned int len) {
472*84e33947SAndroid Build Coastguard Worker   /* receive magic and cmd */
473*84e33947SAndroid Build Coastguard Worker   struct ScpChreIpiMsg msg = *(struct ScpChreIpiMsg *)data;
474*84e33947SAndroid Build Coastguard Worker 
475*84e33947SAndroid Build Coastguard Worker   // check the magic number and payload size need to be copy(if need) */
476*84e33947SAndroid Build Coastguard Worker   LOGD("%s: Received a message from AP. Size=%u", __func__, msg.size);
477*84e33947SAndroid Build Coastguard Worker   if (msg.magic != SCP_CHRE_MAGIC) {
478*84e33947SAndroid Build Coastguard Worker     LOGE("Invalid magic number: 0x%x, skip message", msg.magic);
479*84e33947SAndroid Build Coastguard Worker     gChreIpiAckToHost[0] = IPI_NO_MEMORY;
480*84e33947SAndroid Build Coastguard Worker     gChreIpiAckToHost[1] = 0;
481*84e33947SAndroid Build Coastguard Worker     return;
482*84e33947SAndroid Build Coastguard Worker   }
483*84e33947SAndroid Build Coastguard Worker 
484*84e33947SAndroid Build Coastguard Worker   // Mapping the physical address of share memory for SCP
485*84e33947SAndroid Build Coastguard Worker   uint32_t srcAddr =
486*84e33947SAndroid Build Coastguard Worker       ap_to_scp(reinterpret_cast<uint32_t>(gChreSubregionRecvAddr));
487*84e33947SAndroid Build Coastguard Worker 
488*84e33947SAndroid Build Coastguard Worker #ifdef SCP_CHRE_USE_DMA
489*84e33947SAndroid Build Coastguard Worker   if (msg.size < kMinMessageSizeForDma) {
490*84e33947SAndroid Build Coastguard Worker     dvfs_enable_DRAM_resource(CHRE_MEM_ID);
491*84e33947SAndroid Build Coastguard Worker     memcpy(static_cast<void *>(gChreRecvBuffer),
492*84e33947SAndroid Build Coastguard Worker            reinterpret_cast<void *>(srcAddr), msg.size);
493*84e33947SAndroid Build Coastguard Worker     dvfs_disable_DRAM_resource(CHRE_MEM_ID);
494*84e33947SAndroid Build Coastguard Worker   } else {
495*84e33947SAndroid Build Coastguard Worker     auto dstAddr = reinterpret_cast<uint32_t>(gChreRecvBuffer);
496*84e33947SAndroid Build Coastguard Worker 
497*84e33947SAndroid Build Coastguard Worker     // destination address for receiving data is in a cacheable memory, it
498*84e33947SAndroid Build Coastguard Worker     // should be invalidated/flushed before transferring from share buffer to
499*84e33947SAndroid Build Coastguard Worker     // SCP
500*84e33947SAndroid Build Coastguard Worker     scp_dcache_flush(dstAddr, alignToCacheLine(msg.size));
501*84e33947SAndroid Build Coastguard Worker 
502*84e33947SAndroid Build Coastguard Worker     // Using SCP DMA HW to copy the data from share memory to SCP side.
503*84e33947SAndroid Build Coastguard Worker     // The dstAddr could be a global variables or a SCP heap memory at SRAM/DRAM
504*84e33947SAndroid Build Coastguard Worker     DMA_RESULT result = scp_dma_transaction_dram(dstAddr, srcAddr, msg.size,
505*84e33947SAndroid Build Coastguard Worker                                                  DMA_MEM_ID, NO_RESERVED);
506*84e33947SAndroid Build Coastguard Worker 
507*84e33947SAndroid Build Coastguard Worker     if (result != DMA_RESULT_DONE) {
508*84e33947SAndroid Build Coastguard Worker       LOGE("Failed to receive a message from AP using DMA");
509*84e33947SAndroid Build Coastguard Worker     }
510*84e33947SAndroid Build Coastguard Worker   }
511*84e33947SAndroid Build Coastguard Worker #else  // SCP_CHRE_USE_DMA
512*84e33947SAndroid Build Coastguard Worker 
513*84e33947SAndroid Build Coastguard Worker   dvfs_enable_DRAM_resource(CHRE_MEM_ID);
514*84e33947SAndroid Build Coastguard Worker   memcpy(static_cast<void *>(gChreRecvBuffer),
515*84e33947SAndroid Build Coastguard Worker          reinterpret_cast<void *>(srcAddr), msg.size);
516*84e33947SAndroid Build Coastguard Worker   dvfs_disable_DRAM_resource(CHRE_MEM_ID);
517*84e33947SAndroid Build Coastguard Worker 
518*84e33947SAndroid Build Coastguard Worker #endif  // SCP_CHRE_USE_DMA
519*84e33947SAndroid Build Coastguard Worker 
520*84e33947SAndroid Build Coastguard Worker   // process the message
521*84e33947SAndroid Build Coastguard Worker   receive(static_cast<HostLinkBase *>(prdata), gChreRecvBuffer, msg.size);
522*84e33947SAndroid Build Coastguard Worker 
523*84e33947SAndroid Build Coastguard Worker   // After finishing the job, akc the message to host
524*84e33947SAndroid Build Coastguard Worker   gChreIpiAckToHost[0] = IPI_ACTION_DONE;
525*84e33947SAndroid Build Coastguard Worker   gChreIpiAckToHost[1] = msg.size;
526*84e33947SAndroid Build Coastguard Worker }
527*84e33947SAndroid Build Coastguard Worker 
initializeIpi(void)528*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostLinkBase::initializeIpi(void) {
529*84e33947SAndroid Build Coastguard Worker   bool success = false;
530*84e33947SAndroid Build Coastguard Worker   int ret;
531*84e33947SAndroid Build Coastguard Worker   constexpr size_t kBackgroundTaskStackSize = 1024;
532*84e33947SAndroid Build Coastguard Worker 
533*84e33947SAndroid Build Coastguard Worker #ifdef PRI_CHRE_BACKGROUND
534*84e33947SAndroid Build Coastguard Worker   constexpr UBaseType_t kBackgroundTaskPriority = PRI_CHRE_BACKGROUND;
535*84e33947SAndroid Build Coastguard Worker #else
536*84e33947SAndroid Build Coastguard Worker   constexpr UBaseType_t kBackgroundTaskPriority = 2;
537*84e33947SAndroid Build Coastguard Worker #endif
538*84e33947SAndroid Build Coastguard Worker 
539*84e33947SAndroid Build Coastguard Worker   // prepared share memory information and register the callback functions
540*84e33947SAndroid Build Coastguard Worker   if (!(ret = scp_get_reserve_mem_by_id(SCP_CHRE_FROM_MEM_ID,
541*84e33947SAndroid Build Coastguard Worker                                         &gChreSubregionRecvAddr,
542*84e33947SAndroid Build Coastguard Worker                                         &gChreSubregionRecvSize))) {
543*84e33947SAndroid Build Coastguard Worker     LOGE("%s: get SCP_CHRE_FROM_MEM_ID memory fail", __func__);
544*84e33947SAndroid Build Coastguard Worker   } else if (!(ret = scp_get_reserve_mem_by_id(SCP_CHRE_TO_MEM_ID,
545*84e33947SAndroid Build Coastguard Worker                                                &gChreSubregionSendAddr,
546*84e33947SAndroid Build Coastguard Worker                                                &gChreSubregionSendSize))) {
547*84e33947SAndroid Build Coastguard Worker     LOGE("%s: get SCP_CHRE_TO_MEM_ID memory fail", __func__);
548*84e33947SAndroid Build Coastguard Worker   } else if (pdPASS != xTaskCreate(vChreReceiveTask, "CHRE_RECEIVE",
549*84e33947SAndroid Build Coastguard Worker                                    kBackgroundTaskStackSize, (void *)0,
550*84e33947SAndroid Build Coastguard Worker                                    kBackgroundTaskPriority, NULL)) {
551*84e33947SAndroid Build Coastguard Worker     LOGE("%s failed to create ipi receiver task", __func__);
552*84e33947SAndroid Build Coastguard Worker   } else if (pdPASS != xTaskCreate(vChreSendTask, "CHRE_SEND",
553*84e33947SAndroid Build Coastguard Worker                                    kBackgroundTaskStackSize, (void *)0,
554*84e33947SAndroid Build Coastguard Worker                                    kBackgroundTaskPriority, NULL)) {
555*84e33947SAndroid Build Coastguard Worker     LOGE("%s failed to create ipi outbound message queue task", __func__);
556*84e33947SAndroid Build Coastguard Worker   } else if (IPI_ACTION_DONE !=
557*84e33947SAndroid Build Coastguard Worker              (ret = ipi_register(IPI_IN_C_HOST_SCP_CHRE, (void *)chreIpiHandler,
558*84e33947SAndroid Build Coastguard Worker                                  (void *)this, (void *)&gChreIpiRecvData[0]))) {
559*84e33947SAndroid Build Coastguard Worker     LOGE("ipi_register IPI_IN_C_HOST_SCP_CHRE failed, %d", ret);
560*84e33947SAndroid Build Coastguard Worker   } else if (IPI_ACTION_DONE !=
561*84e33947SAndroid Build Coastguard Worker              (ret = ipi_register(IPI_OUT_C_SCP_HOST_CHRE, NULL, (void *)this,
562*84e33947SAndroid Build Coastguard Worker                                  (void *)&gChreIpiAckFromHost[0]))) {
563*84e33947SAndroid Build Coastguard Worker     LOGE("ipi_register IPI_OUT_C_SCP_HOST_CHRE failed, %d", ret);
564*84e33947SAndroid Build Coastguard Worker   } else {
565*84e33947SAndroid Build Coastguard Worker     success = true;
566*84e33947SAndroid Build Coastguard Worker   }
567*84e33947SAndroid Build Coastguard Worker 
568*84e33947SAndroid Build Coastguard Worker   if (!success) {
569*84e33947SAndroid Build Coastguard Worker     FATAL_ERROR("HostLinkBase::initializeIpi() failed");
570*84e33947SAndroid Build Coastguard Worker   }
571*84e33947SAndroid Build Coastguard Worker }
572*84e33947SAndroid Build Coastguard Worker 
receive(HostLinkBase * instance,void * message,int messageLen)573*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostLinkBase::receive(HostLinkBase *instance,
574*84e33947SAndroid Build Coastguard Worker                                                 void *message, int messageLen) {
575*84e33947SAndroid Build Coastguard Worker   LOGV("%s: message len %d", __func__, messageLen);
576*84e33947SAndroid Build Coastguard Worker 
577*84e33947SAndroid Build Coastguard Worker   // TODO(b/277128368): A crude way to initially determine daemon's up - set
578*84e33947SAndroid Build Coastguard Worker   // a flag on the first message received. This is temporary until a better
579*84e33947SAndroid Build Coastguard Worker   // way to do this is available.
580*84e33947SAndroid Build Coastguard Worker   instance->setInitialized(true);
581*84e33947SAndroid Build Coastguard Worker 
582*84e33947SAndroid Build Coastguard Worker   if (!HostProtocolChre::decodeMessageFromHost(message, messageLen)) {
583*84e33947SAndroid Build Coastguard Worker     LOGE("Failed to decode msg %p of len %u", message, messageLen);
584*84e33947SAndroid Build Coastguard Worker   }
585*84e33947SAndroid Build Coastguard Worker }
586*84e33947SAndroid Build Coastguard Worker 
send(uint8_t * data,size_t dataLen)587*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION bool HostLinkBase::send(uint8_t *data, size_t dataLen) {
588*84e33947SAndroid Build Coastguard Worker #ifndef HOST_LINK_IPI_SEND_TIMEOUT_MS
589*84e33947SAndroid Build Coastguard Worker #define HOST_LINK_IPI_SEND_TIMEOUT_MS 100
590*84e33947SAndroid Build Coastguard Worker #endif
591*84e33947SAndroid Build Coastguard Worker #ifndef HOST_LINK_IPI_RESPONSE_TIMEOUT_MS
592*84e33947SAndroid Build Coastguard Worker #define HOST_LINK_IPI_RESPONSE_TIMEOUT_MS 100
593*84e33947SAndroid Build Coastguard Worker #endif
594*84e33947SAndroid Build Coastguard Worker   LOGV("HostLinkBase::%s: %zu, %p", __func__, dataLen, data);
595*84e33947SAndroid Build Coastguard Worker   struct ScpChreIpiMsg msg;
596*84e33947SAndroid Build Coastguard Worker   msg.magic = SCP_CHRE_MAGIC;
597*84e33947SAndroid Build Coastguard Worker   msg.size = dataLen;
598*84e33947SAndroid Build Coastguard Worker 
599*84e33947SAndroid Build Coastguard Worker   uint32_t dstAddr =
600*84e33947SAndroid Build Coastguard Worker       ap_to_scp(reinterpret_cast<uint32_t>(gChreSubregionSendAddr));
601*84e33947SAndroid Build Coastguard Worker 
602*84e33947SAndroid Build Coastguard Worker #ifdef SCP_CHRE_USE_DMA
603*84e33947SAndroid Build Coastguard Worker   if (dataLen < kMinMessageSizeForDma) {
604*84e33947SAndroid Build Coastguard Worker     dvfs_enable_DRAM_resource(CHRE_MEM_ID);
605*84e33947SAndroid Build Coastguard Worker     memcpy(reinterpret_cast<void *>(dstAddr), data, dataLen);
606*84e33947SAndroid Build Coastguard Worker     dvfs_disable_DRAM_resource(CHRE_MEM_ID);
607*84e33947SAndroid Build Coastguard Worker   } else {
608*84e33947SAndroid Build Coastguard Worker     auto srcAddr = reinterpret_cast<uint32_t>(data);
609*84e33947SAndroid Build Coastguard Worker     auto msgSize = reinterpret_cast<uint32_t>(msg.size);
610*84e33947SAndroid Build Coastguard Worker 
611*84e33947SAndroid Build Coastguard Worker     // Separate the message into 2 parts, copySize and dmaSize, and use memcpy
612*84e33947SAndroid Build Coastguard Worker     // and dma to transfer them respectively. This is needed due to the
613*84e33947SAndroid Build Coastguard Worker     // alignment requirement of the dma transfer.
614*84e33947SAndroid Build Coastguard Worker     uint32_t dmaStartSrcAddr = alignToCacheLine(srcAddr);
615*84e33947SAndroid Build Coastguard Worker     uint32_t copySize = dmaStartSrcAddr - srcAddr;
616*84e33947SAndroid Build Coastguard Worker     uint32_t dmaSize = msgSize - copySize;
617*84e33947SAndroid Build Coastguard Worker 
618*84e33947SAndroid Build Coastguard Worker     if (copySize > 0) {
619*84e33947SAndroid Build Coastguard Worker       dvfs_enable_DRAM_resource(CHRE_MEM_ID);
620*84e33947SAndroid Build Coastguard Worker       memcpy(reinterpret_cast<void *>(dstAddr), data, copySize);
621*84e33947SAndroid Build Coastguard Worker       dvfs_disable_DRAM_resource(CHRE_MEM_ID);
622*84e33947SAndroid Build Coastguard Worker     }
623*84e33947SAndroid Build Coastguard Worker 
624*84e33947SAndroid Build Coastguard Worker     // source address for sending data is in a cacheable memory, it should
625*84e33947SAndroid Build Coastguard Worker     // be invalidated/flushed before transferring from SCP to shared buffer
626*84e33947SAndroid Build Coastguard Worker     scp_dcache_flush(dmaStartSrcAddr, alignToCacheLine(dmaSize));
627*84e33947SAndroid Build Coastguard Worker 
628*84e33947SAndroid Build Coastguard Worker     // Using SCP DMA HW to copy the data from SCP to shared memory.
629*84e33947SAndroid Build Coastguard Worker     // The dstAddr could be a global variables or a SCP heap memory at SRAM/DRAM
630*84e33947SAndroid Build Coastguard Worker     DMA_RESULT result = scp_dma_transaction_dram(
631*84e33947SAndroid Build Coastguard Worker         dstAddr + copySize, dmaStartSrcAddr, dmaSize, DMA_MEM_ID, NO_RESERVED);
632*84e33947SAndroid Build Coastguard Worker 
633*84e33947SAndroid Build Coastguard Worker     if (result != DMA_RESULT_DONE) {
634*84e33947SAndroid Build Coastguard Worker       LOGE("Failed to receive a message from AP using DMA");
635*84e33947SAndroid Build Coastguard Worker     }
636*84e33947SAndroid Build Coastguard Worker   }
637*84e33947SAndroid Build Coastguard Worker #else
638*84e33947SAndroid Build Coastguard Worker   dvfs_enable_DRAM_resource(CHRE_MEM_ID);
639*84e33947SAndroid Build Coastguard Worker   memcpy(reinterpret_cast<void *>(dstAddr), data, dataLen);
640*84e33947SAndroid Build Coastguard Worker   dvfs_disable_DRAM_resource(CHRE_MEM_ID);
641*84e33947SAndroid Build Coastguard Worker #endif
642*84e33947SAndroid Build Coastguard Worker   // NB: len param for ipi_send is in number of 32-bit words
643*84e33947SAndroid Build Coastguard Worker   int ret = ipi_send_compl(
644*84e33947SAndroid Build Coastguard Worker       IPI_OUT_C_SCP_HOST_CHRE, &msg, sizeof(msg) / sizeof(uint32_t),
645*84e33947SAndroid Build Coastguard Worker       HOST_LINK_IPI_SEND_TIMEOUT_MS, HOST_LINK_IPI_RESPONSE_TIMEOUT_MS);
646*84e33947SAndroid Build Coastguard Worker   if (ret) {
647*84e33947SAndroid Build Coastguard Worker     LOGE("chre ipi send fail(%d)", ret);
648*84e33947SAndroid Build Coastguard Worker   } else {
649*84e33947SAndroid Build Coastguard Worker     /* check ack data for make sure IPI wasn't busy */
650*84e33947SAndroid Build Coastguard Worker     if (gChreIpiAckFromHost[0] == IPI_ACTION_DONE) {
651*84e33947SAndroid Build Coastguard Worker       LOGV("chre ipi send done, you can send another IPI");
652*84e33947SAndroid Build Coastguard Worker     } else if (gChreIpiAckFromHost[0] == IPI_PIN_BUSY) {
653*84e33947SAndroid Build Coastguard Worker       /* you may have to re-send the IPI, or drop this one */
654*84e33947SAndroid Build Coastguard Worker       LOGW(
655*84e33947SAndroid Build Coastguard Worker           "chre ipi send busy, user thread has not wait the IPI until job "
656*84e33947SAndroid Build Coastguard Worker           "finished");
657*84e33947SAndroid Build Coastguard Worker     } else if (gChreIpiAckFromHost[0] == IPI_NO_MEMORY) {
658*84e33947SAndroid Build Coastguard Worker       LOGW("chre ipi send with wrong size(%zu)", dataLen);
659*84e33947SAndroid Build Coastguard Worker     } else {
660*84e33947SAndroid Build Coastguard Worker       LOGW("chre ipi send unknown case: 0x%x", gChreIpiAckFromHost[0]);
661*84e33947SAndroid Build Coastguard Worker     }
662*84e33947SAndroid Build Coastguard Worker   }
663*84e33947SAndroid Build Coastguard Worker 
664*84e33947SAndroid Build Coastguard Worker   return ret == IPI_ACTION_DONE;
665*84e33947SAndroid Build Coastguard Worker }
666*84e33947SAndroid Build Coastguard Worker 
sendTimeSyncRequest()667*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostLinkBase::sendTimeSyncRequest() {}
668*84e33947SAndroid Build Coastguard Worker 
sendNanConfiguration(bool)669*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostLinkBase::sendNanConfiguration(
670*84e33947SAndroid Build Coastguard Worker     bool /* enabled */) {
671*84e33947SAndroid Build Coastguard Worker   LOGE("%s is unsupported", __func__);
672*84e33947SAndroid Build Coastguard Worker }
673*84e33947SAndroid Build Coastguard Worker 
sendLogMessageV2(const uint8_t * logMessage,size_t logMessageSize,uint32_t numLogsDropped)674*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostLinkBase::sendLogMessageV2(
675*84e33947SAndroid Build Coastguard Worker     const uint8_t *logMessage, size_t logMessageSize, uint32_t numLogsDropped) {
676*84e33947SAndroid Build Coastguard Worker   LOGV("%s: size %zu", __func__, logMessageSize);
677*84e33947SAndroid Build Coastguard Worker   struct LogMessageData {
678*84e33947SAndroid Build Coastguard Worker     const uint8_t *logMsg;
679*84e33947SAndroid Build Coastguard Worker     size_t logMsgSize;
680*84e33947SAndroid Build Coastguard Worker     uint32_t numLogsDropped;
681*84e33947SAndroid Build Coastguard Worker   };
682*84e33947SAndroid Build Coastguard Worker 
683*84e33947SAndroid Build Coastguard Worker   LogMessageData logMessageData{logMessage, logMessageSize, numLogsDropped};
684*84e33947SAndroid Build Coastguard Worker 
685*84e33947SAndroid Build Coastguard Worker   auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
686*84e33947SAndroid Build Coastguard Worker     const auto *data = static_cast<const LogMessageData *>(cookie);
687*84e33947SAndroid Build Coastguard Worker     HostProtocolChre::encodeLogMessagesV2(
688*84e33947SAndroid Build Coastguard Worker         builder, data->logMsg, data->logMsgSize, data->numLogsDropped);
689*84e33947SAndroid Build Coastguard Worker   };
690*84e33947SAndroid Build Coastguard Worker 
691*84e33947SAndroid Build Coastguard Worker   constexpr size_t kInitialSize = 128;
692*84e33947SAndroid Build Coastguard Worker   bool result = false;
693*84e33947SAndroid Build Coastguard Worker   if (isInitialized()) {
694*84e33947SAndroid Build Coastguard Worker     result = buildAndEnqueueMessage(
695*84e33947SAndroid Build Coastguard Worker         PendingMessageType::EncodedLogMessage,
696*84e33947SAndroid Build Coastguard Worker         kInitialSize + logMessageSize + sizeof(numLogsDropped), msgBuilder,
697*84e33947SAndroid Build Coastguard Worker         &logMessageData);
698*84e33947SAndroid Build Coastguard Worker   }
699*84e33947SAndroid Build Coastguard Worker 
700*84e33947SAndroid Build Coastguard Worker #ifdef CHRE_USE_BUFFERED_LOGGING
701*84e33947SAndroid Build Coastguard Worker   if (LogBufferManagerSingleton::isInitialized()) {
702*84e33947SAndroid Build Coastguard Worker     LogBufferManagerSingleton::get()->onLogsSentToHost(result);
703*84e33947SAndroid Build Coastguard Worker   }
704*84e33947SAndroid Build Coastguard Worker #else
705*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(result);
706*84e33947SAndroid Build Coastguard Worker #endif
707*84e33947SAndroid Build Coastguard Worker }
708*84e33947SAndroid Build Coastguard Worker 
sendMessage(HostMessage const * message)709*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION bool HostLink::sendMessage(HostMessage const *message) {
710*84e33947SAndroid Build Coastguard Worker   LOGV("HostLink::%s size(%zu)", __func__, message->message.size());
711*84e33947SAndroid Build Coastguard Worker   bool success = false;
712*84e33947SAndroid Build Coastguard Worker 
713*84e33947SAndroid Build Coastguard Worker   if (isInitialized()) {
714*84e33947SAndroid Build Coastguard Worker     success = enqueueMessage(
715*84e33947SAndroid Build Coastguard Worker         PendingMessage(PendingMessageType::NanoappMessageToHost, message));
716*84e33947SAndroid Build Coastguard Worker   } else {
717*84e33947SAndroid Build Coastguard Worker     LOGW("Dropping outbound message: host link not initialized yet");
718*84e33947SAndroid Build Coastguard Worker   }
719*84e33947SAndroid Build Coastguard Worker   return success;
720*84e33947SAndroid Build Coastguard Worker }
721*84e33947SAndroid Build Coastguard Worker 
sendMessageDeliveryStatus(uint32_t messageSequenceNumber,uint8_t errorCode)722*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION bool HostLink::sendMessageDeliveryStatus(
723*84e33947SAndroid Build Coastguard Worker     uint32_t messageSequenceNumber, uint8_t errorCode) {
724*84e33947SAndroid Build Coastguard Worker   struct DeliveryStatusData {
725*84e33947SAndroid Build Coastguard Worker     uint32_t messageSequenceNumber;
726*84e33947SAndroid Build Coastguard Worker     uint8_t errorCode;
727*84e33947SAndroid Build Coastguard Worker   } args{messageSequenceNumber, errorCode};
728*84e33947SAndroid Build Coastguard Worker 
729*84e33947SAndroid Build Coastguard Worker   auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
730*84e33947SAndroid Build Coastguard Worker     auto args = static_cast<const DeliveryStatusData *>(cookie);
731*84e33947SAndroid Build Coastguard Worker     HostProtocolChre::encodeMessageDeliveryStatus(
732*84e33947SAndroid Build Coastguard Worker         builder, args->messageSequenceNumber, args->errorCode);
733*84e33947SAndroid Build Coastguard Worker   };
734*84e33947SAndroid Build Coastguard Worker 
735*84e33947SAndroid Build Coastguard Worker   return buildAndEnqueueMessage(PendingMessageType::MessageDeliveryStatus,
736*84e33947SAndroid Build Coastguard Worker                                 /* initialBufferSize= */ 64, msgBuilder, &args);
737*84e33947SAndroid Build Coastguard Worker }
738*84e33947SAndroid Build Coastguard Worker 
739*84e33947SAndroid Build Coastguard Worker // TODO(b/285219398): HostMessageHandlers member function implementations are
740*84e33947SAndroid Build Coastguard Worker // expected to be (mostly) identical for any platform that uses flatbuffers
741*84e33947SAndroid Build Coastguard Worker // to encode messages - refactor the host link to merge the multiple copies
742*84e33947SAndroid Build Coastguard Worker // we currently have.
handleNanoappMessage(uint64_t appId,uint32_t messageType,uint16_t hostEndpoint,const void * messageData,size_t messageDataLen,bool isReliable,uint32_t messageSequenceNumber)743*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostMessageHandlers::handleNanoappMessage(
744*84e33947SAndroid Build Coastguard Worker     uint64_t appId, uint32_t messageType, uint16_t hostEndpoint,
745*84e33947SAndroid Build Coastguard Worker     const void *messageData, size_t messageDataLen, bool isReliable,
746*84e33947SAndroid Build Coastguard Worker     uint32_t messageSequenceNumber) {
747*84e33947SAndroid Build Coastguard Worker   LOGV("Parsed nanoapp message from host: app ID 0x%016" PRIx64
748*84e33947SAndroid Build Coastguard Worker        ", endpoint "
749*84e33947SAndroid Build Coastguard Worker        "0x%" PRIx16 ", msgType %" PRIu32 ", payload size %zu",
750*84e33947SAndroid Build Coastguard Worker        appId, hostEndpoint, messageType, messageDataLen);
751*84e33947SAndroid Build Coastguard Worker 
752*84e33947SAndroid Build Coastguard Worker   getHostCommsManager().sendMessageToNanoappFromHost(
753*84e33947SAndroid Build Coastguard Worker       appId, messageType, hostEndpoint, messageData, messageDataLen, isReliable,
754*84e33947SAndroid Build Coastguard Worker       messageSequenceNumber);
755*84e33947SAndroid Build Coastguard Worker }
756*84e33947SAndroid Build Coastguard Worker 
handleMessageDeliveryStatus(uint32_t messageSequenceNumber,uint8_t errorCode)757*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostMessageHandlers::handleMessageDeliveryStatus(
758*84e33947SAndroid Build Coastguard Worker     uint32_t messageSequenceNumber, uint8_t errorCode) {
759*84e33947SAndroid Build Coastguard Worker   getHostCommsManager().completeTransaction(messageSequenceNumber, errorCode);
760*84e33947SAndroid Build Coastguard Worker }
761*84e33947SAndroid Build Coastguard Worker 
handleHubInfoRequest(uint16_t hostClientId)762*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostMessageHandlers::handleHubInfoRequest(
763*84e33947SAndroid Build Coastguard Worker     uint16_t hostClientId) {
764*84e33947SAndroid Build Coastguard Worker   LOGV("%s: host client id %d", __func__, hostClientId);
765*84e33947SAndroid Build Coastguard Worker   enqueueMessage(
766*84e33947SAndroid Build Coastguard Worker       PendingMessage(PendingMessageType::HubInfoResponse, hostClientId));
767*84e33947SAndroid Build Coastguard Worker }
768*84e33947SAndroid Build Coastguard Worker 
handleNanoappListRequest(uint16_t hostClientId)769*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostMessageHandlers::handleNanoappListRequest(
770*84e33947SAndroid Build Coastguard Worker     uint16_t hostClientId) {
771*84e33947SAndroid Build Coastguard Worker   auto callback = [](uint16_t /*type*/, void *data, void * /*extraData*/) {
772*84e33947SAndroid Build Coastguard Worker     uint16_t cbHostClientId = NestedDataPtr<uint16_t>(data);
773*84e33947SAndroid Build Coastguard Worker 
774*84e33947SAndroid Build Coastguard Worker     NanoappListData cbData = {};
775*84e33947SAndroid Build Coastguard Worker     cbData.hostClientId = cbHostClientId;
776*84e33947SAndroid Build Coastguard Worker 
777*84e33947SAndroid Build Coastguard Worker     size_t expectedNanoappCount =
778*84e33947SAndroid Build Coastguard Worker         EventLoopManagerSingleton::get()->getEventLoop().getNanoappCount();
779*84e33947SAndroid Build Coastguard Worker     if (!cbData.nanoappEntries.reserve(expectedNanoappCount)) {
780*84e33947SAndroid Build Coastguard Worker       LOG_OOM();
781*84e33947SAndroid Build Coastguard Worker     } else {
782*84e33947SAndroid Build Coastguard Worker       constexpr size_t kFixedOverhead = 48;
783*84e33947SAndroid Build Coastguard Worker       constexpr size_t kPerNanoappSize = 32;
784*84e33947SAndroid Build Coastguard Worker       size_t initialBufferSize =
785*84e33947SAndroid Build Coastguard Worker           (kFixedOverhead + expectedNanoappCount * kPerNanoappSize);
786*84e33947SAndroid Build Coastguard Worker 
787*84e33947SAndroid Build Coastguard Worker       buildAndEnqueueMessage(PendingMessageType::NanoappListResponse,
788*84e33947SAndroid Build Coastguard Worker                              initialBufferSize, buildNanoappListResponse,
789*84e33947SAndroid Build Coastguard Worker                              &cbData);
790*84e33947SAndroid Build Coastguard Worker     }
791*84e33947SAndroid Build Coastguard Worker   };
792*84e33947SAndroid Build Coastguard Worker 
793*84e33947SAndroid Build Coastguard Worker   LOGD("Nanoapp list request from client ID %" PRIu16, hostClientId);
794*84e33947SAndroid Build Coastguard Worker   EventLoopManagerSingleton::get()->deferCallback(
795*84e33947SAndroid Build Coastguard Worker       SystemCallbackType::NanoappListResponse,
796*84e33947SAndroid Build Coastguard Worker       NestedDataPtr<uint16_t>(hostClientId), callback);
797*84e33947SAndroid Build Coastguard Worker }
798*84e33947SAndroid Build Coastguard Worker 
sendFragmentResponse(uint16_t hostClientId,uint32_t transactionId,uint32_t fragmentId,bool success)799*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostMessageHandlers::sendFragmentResponse(
800*84e33947SAndroid Build Coastguard Worker     uint16_t hostClientId, uint32_t transactionId, uint32_t fragmentId,
801*84e33947SAndroid Build Coastguard Worker     bool success) {
802*84e33947SAndroid Build Coastguard Worker   struct FragmentedLoadInfoResponse {
803*84e33947SAndroid Build Coastguard Worker     uint16_t hostClientId;
804*84e33947SAndroid Build Coastguard Worker     uint32_t transactionId;
805*84e33947SAndroid Build Coastguard Worker     uint32_t fragmentId;
806*84e33947SAndroid Build Coastguard Worker     bool success;
807*84e33947SAndroid Build Coastguard Worker   };
808*84e33947SAndroid Build Coastguard Worker 
809*84e33947SAndroid Build Coastguard Worker   auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
810*84e33947SAndroid Build Coastguard Worker     auto *cbData = static_cast<FragmentedLoadInfoResponse *>(cookie);
811*84e33947SAndroid Build Coastguard Worker     HostProtocolChre::encodeLoadNanoappResponse(
812*84e33947SAndroid Build Coastguard Worker         builder, cbData->hostClientId, cbData->transactionId, cbData->success,
813*84e33947SAndroid Build Coastguard Worker         cbData->fragmentId);
814*84e33947SAndroid Build Coastguard Worker   };
815*84e33947SAndroid Build Coastguard Worker 
816*84e33947SAndroid Build Coastguard Worker   FragmentedLoadInfoResponse response = {
817*84e33947SAndroid Build Coastguard Worker       .hostClientId = hostClientId,
818*84e33947SAndroid Build Coastguard Worker       .transactionId = transactionId,
819*84e33947SAndroid Build Coastguard Worker       .fragmentId = fragmentId,
820*84e33947SAndroid Build Coastguard Worker       .success = success,
821*84e33947SAndroid Build Coastguard Worker   };
822*84e33947SAndroid Build Coastguard Worker   constexpr size_t kInitialBufferSize = 52;
823*84e33947SAndroid Build Coastguard Worker   buildAndEnqueueMessage(PendingMessageType::LoadNanoappResponse,
824*84e33947SAndroid Build Coastguard Worker                          kInitialBufferSize, msgBuilder, &response);
825*84e33947SAndroid Build Coastguard Worker }
826*84e33947SAndroid Build Coastguard Worker 
handlePulseRequest()827*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostMessageHandlers::handlePulseRequest() {
828*84e33947SAndroid Build Coastguard Worker   auto callback = [](uint16_t /*type*/, void * /*data*/, void * /*extraData*/) {
829*84e33947SAndroid Build Coastguard Worker     buildAndEnqueueMessage(PendingMessageType::PulseResponse,
830*84e33947SAndroid Build Coastguard Worker                            /*initialBufferSize= */ 48, buildPulseResponse,
831*84e33947SAndroid Build Coastguard Worker                            /* cookie= */ nullptr);
832*84e33947SAndroid Build Coastguard Worker   };
833*84e33947SAndroid Build Coastguard Worker   EventLoopManagerSingleton::get()->deferCallback(
834*84e33947SAndroid Build Coastguard Worker       SystemCallbackType::PulseResponse, /* data= */ nullptr, callback);
835*84e33947SAndroid Build Coastguard Worker }
836*84e33947SAndroid Build Coastguard Worker 
handleLoadNanoappRequest(uint16_t hostClientId,uint32_t transactionId,uint64_t appId,uint32_t appVersion,uint32_t appFlags,uint32_t targetApiVersion,const void * buffer,size_t bufferLen,const char * appFileName,uint32_t fragmentId,size_t appBinaryLen,bool respondBeforeStart)837*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostMessageHandlers::handleLoadNanoappRequest(
838*84e33947SAndroid Build Coastguard Worker     uint16_t hostClientId, uint32_t transactionId, uint64_t appId,
839*84e33947SAndroid Build Coastguard Worker     uint32_t appVersion, uint32_t appFlags, uint32_t targetApiVersion,
840*84e33947SAndroid Build Coastguard Worker     const void *buffer, size_t bufferLen, const char *appFileName,
841*84e33947SAndroid Build Coastguard Worker     uint32_t fragmentId, size_t appBinaryLen, bool respondBeforeStart) {
842*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(appFileName);
843*84e33947SAndroid Build Coastguard Worker 
844*84e33947SAndroid Build Coastguard Worker   loadNanoappData(hostClientId, transactionId, appId, appVersion, appFlags,
845*84e33947SAndroid Build Coastguard Worker                   targetApiVersion, buffer, bufferLen, fragmentId, appBinaryLen,
846*84e33947SAndroid Build Coastguard Worker                   respondBeforeStart);
847*84e33947SAndroid Build Coastguard Worker }
848*84e33947SAndroid Build Coastguard Worker 
handleUnloadNanoappRequest(uint16_t hostClientId,uint32_t transactionId,uint64_t appId,bool allowSystemNanoappUnload)849*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostMessageHandlers::handleUnloadNanoappRequest(
850*84e33947SAndroid Build Coastguard Worker     uint16_t hostClientId, uint32_t transactionId, uint64_t appId,
851*84e33947SAndroid Build Coastguard Worker     bool allowSystemNanoappUnload) {
852*84e33947SAndroid Build Coastguard Worker   LOGD("Unload nanoapp request from client %" PRIu16 " (txnID %" PRIu32
853*84e33947SAndroid Build Coastguard Worker        ") for appId 0x%016" PRIx64 " system %d",
854*84e33947SAndroid Build Coastguard Worker        hostClientId, transactionId, appId, allowSystemNanoappUnload);
855*84e33947SAndroid Build Coastguard Worker   auto *cbData = memoryAlloc<UnloadNanoappCallbackData>();
856*84e33947SAndroid Build Coastguard Worker   if (cbData == nullptr) {
857*84e33947SAndroid Build Coastguard Worker     LOG_OOM();
858*84e33947SAndroid Build Coastguard Worker   } else {
859*84e33947SAndroid Build Coastguard Worker     cbData->appId = appId;
860*84e33947SAndroid Build Coastguard Worker     cbData->transactionId = transactionId;
861*84e33947SAndroid Build Coastguard Worker     cbData->hostClientId = hostClientId;
862*84e33947SAndroid Build Coastguard Worker     cbData->allowSystemNanoappUnload = allowSystemNanoappUnload;
863*84e33947SAndroid Build Coastguard Worker 
864*84e33947SAndroid Build Coastguard Worker     EventLoopManagerSingleton::get()->deferCallback(
865*84e33947SAndroid Build Coastguard Worker         SystemCallbackType::HandleUnloadNanoapp, cbData,
866*84e33947SAndroid Build Coastguard Worker         handleUnloadNanoappCallback);
867*84e33947SAndroid Build Coastguard Worker   }
868*84e33947SAndroid Build Coastguard Worker }
869*84e33947SAndroid Build Coastguard Worker 
sendNanoappTokenDatabaseInfo(uint64_t appId,uint32_t tokenDatabaseOffset,size_t tokenDatabaseSize)870*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostLinkBase::sendNanoappTokenDatabaseInfo(
871*84e33947SAndroid Build Coastguard Worker     uint64_t appId, uint32_t tokenDatabaseOffset, size_t tokenDatabaseSize) {
872*84e33947SAndroid Build Coastguard Worker   constexpr size_t kInitialBufferSize = 56;
873*84e33947SAndroid Build Coastguard Worker   struct DatabaseInfoArgs {
874*84e33947SAndroid Build Coastguard Worker     uint64_t appId;
875*84e33947SAndroid Build Coastguard Worker     uint32_t tokenDatabaseOffset;
876*84e33947SAndroid Build Coastguard Worker     size_t tokenDatabaseSize;
877*84e33947SAndroid Build Coastguard Worker   } args{appId, tokenDatabaseOffset, tokenDatabaseSize};
878*84e33947SAndroid Build Coastguard Worker 
879*84e33947SAndroid Build Coastguard Worker   auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) {
880*84e33947SAndroid Build Coastguard Worker     DatabaseInfoArgs *args = static_cast<DatabaseInfoArgs *>(cookie);
881*84e33947SAndroid Build Coastguard Worker     uint16_t instanceId;
882*84e33947SAndroid Build Coastguard Worker     EventLoopManagerSingleton::get()
883*84e33947SAndroid Build Coastguard Worker         ->getEventLoop()
884*84e33947SAndroid Build Coastguard Worker         .findNanoappInstanceIdByAppId(args->appId, &instanceId);
885*84e33947SAndroid Build Coastguard Worker     HostProtocolChre::encodeNanoappTokenDatabaseInfo(
886*84e33947SAndroid Build Coastguard Worker         builder, instanceId, args->appId, args->tokenDatabaseOffset,
887*84e33947SAndroid Build Coastguard Worker         args->tokenDatabaseSize);
888*84e33947SAndroid Build Coastguard Worker   };
889*84e33947SAndroid Build Coastguard Worker 
890*84e33947SAndroid Build Coastguard Worker   buildAndEnqueueMessage(PendingMessageType::NanoappTokenDatabaseInfo,
891*84e33947SAndroid Build Coastguard Worker                          kInitialBufferSize, msgBuilder, &args);
892*84e33947SAndroid Build Coastguard Worker }
893*84e33947SAndroid Build Coastguard Worker 
flushMessagesSentByNanoapp(uint64_t)894*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostLink::flushMessagesSentByNanoapp(
895*84e33947SAndroid Build Coastguard Worker     uint64_t /* appId */) {
896*84e33947SAndroid Build Coastguard Worker   // Not implemented
897*84e33947SAndroid Build Coastguard Worker }
898*84e33947SAndroid Build Coastguard Worker 
handleTimeSyncMessage(int64_t offset)899*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostMessageHandlers::handleTimeSyncMessage(
900*84e33947SAndroid Build Coastguard Worker     int64_t offset) {
901*84e33947SAndroid Build Coastguard Worker   LOGE("%s is unsupported", __func__);
902*84e33947SAndroid Build Coastguard Worker }
903*84e33947SAndroid Build Coastguard Worker 
handleDebugDumpRequest(uint16_t hostClientId)904*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostMessageHandlers::handleDebugDumpRequest(
905*84e33947SAndroid Build Coastguard Worker     uint16_t hostClientId) {
906*84e33947SAndroid Build Coastguard Worker   LOGV("%s: host client id %d", __func__, hostClientId);
907*84e33947SAndroid Build Coastguard Worker   if (!EventLoopManagerSingleton::get()
908*84e33947SAndroid Build Coastguard Worker            ->getDebugDumpManager()
909*84e33947SAndroid Build Coastguard Worker            .onDebugDumpRequested(hostClientId)) {
910*84e33947SAndroid Build Coastguard Worker     LOGE("Couldn't trigger debug dump process");
911*84e33947SAndroid Build Coastguard Worker     sendDebugDumpResponse(hostClientId, /* success= */ false,
912*84e33947SAndroid Build Coastguard Worker                           /* dataCount= */ 0);
913*84e33947SAndroid Build Coastguard Worker   }
914*84e33947SAndroid Build Coastguard Worker }
915*84e33947SAndroid Build Coastguard Worker 
handleSettingChangeMessage(fbs::Setting setting,fbs::SettingState state)916*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostMessageHandlers::handleSettingChangeMessage(
917*84e33947SAndroid Build Coastguard Worker     fbs::Setting setting, fbs::SettingState state) {
918*84e33947SAndroid Build Coastguard Worker   // TODO(b/285219398): Refactor handleSettingChangeMessage to shared code
919*84e33947SAndroid Build Coastguard Worker   Setting chreSetting;
920*84e33947SAndroid Build Coastguard Worker   bool chreSettingEnabled;
921*84e33947SAndroid Build Coastguard Worker   if (HostProtocolChre::getSettingFromFbs(setting, &chreSetting) &&
922*84e33947SAndroid Build Coastguard Worker       HostProtocolChre::getSettingEnabledFromFbs(state, &chreSettingEnabled)) {
923*84e33947SAndroid Build Coastguard Worker     EventLoopManagerSingleton::get()->getSettingManager().postSettingChange(
924*84e33947SAndroid Build Coastguard Worker         chreSetting, chreSettingEnabled);
925*84e33947SAndroid Build Coastguard Worker   }
926*84e33947SAndroid Build Coastguard Worker }
927*84e33947SAndroid Build Coastguard Worker 
handleSelfTestRequest(uint16_t hostClientId)928*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostMessageHandlers::handleSelfTestRequest(
929*84e33947SAndroid Build Coastguard Worker     uint16_t hostClientId) {
930*84e33947SAndroid Build Coastguard Worker   LOGV("%s: host client id %d", __func__, hostClientId);
931*84e33947SAndroid Build Coastguard Worker }
932*84e33947SAndroid Build Coastguard Worker 
handleNanConfigurationUpdate(bool)933*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostMessageHandlers::handleNanConfigurationUpdate(
934*84e33947SAndroid Build Coastguard Worker     bool /* enabled */) {
935*84e33947SAndroid Build Coastguard Worker   LOGE("%s is unsupported", __func__);
936*84e33947SAndroid Build Coastguard Worker }
937*84e33947SAndroid Build Coastguard Worker 
handleBtSocketOpen(uint16_t,uint64_t,const char *,uint64_t,uint64_t,uint32_t,uint32_t,uint32_t,uint32_t,uint32_t,uint32_t,uint32_t,uint32_t,uint32_t,uint32_t)938*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void HostMessageHandlers::handleBtSocketOpen(
939*84e33947SAndroid Build Coastguard Worker     uint16_t /* hostClientId */, uint64_t /* socketId */,
940*84e33947SAndroid Build Coastguard Worker     const char * /* name */, uint64_t /* endpointId */, uint64_t /* hubId */,
941*84e33947SAndroid Build Coastguard Worker     uint32_t /* aclConnectionHandle */, uint32_t /* localCid */,
942*84e33947SAndroid Build Coastguard Worker     uint32_t /* remoteCid */, uint32_t /* psm */, uint32_t /* localMtu */,
943*84e33947SAndroid Build Coastguard Worker     uint32_t /* remoteMtu */, uint32_t /* localMps */, uint32_t /* remoteMps */,
944*84e33947SAndroid Build Coastguard Worker     uint32_t /* initialRxCredits */, uint32_t /* initialTxCredits */) {
945*84e33947SAndroid Build Coastguard Worker   LOGE("BT Socket offload not supported");
946*84e33947SAndroid Build Coastguard Worker }
947*84e33947SAndroid Build Coastguard Worker 
sendAudioRequest()948*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void sendAudioRequest() {
949*84e33947SAndroid Build Coastguard Worker   auto msgBuilder = [](ChreFlatBufferBuilder &builder, void * /*cookie*/) {
950*84e33947SAndroid Build Coastguard Worker     HostProtocolChre::encodeLowPowerMicAccessRequest(builder);
951*84e33947SAndroid Build Coastguard Worker   };
952*84e33947SAndroid Build Coastguard Worker   constexpr size_t kInitialSize = 32;
953*84e33947SAndroid Build Coastguard Worker   buildAndEnqueueMessage(PendingMessageType::LowPowerMicAccessRequest,
954*84e33947SAndroid Build Coastguard Worker                          kInitialSize, msgBuilder, /* cookie= */ nullptr);
955*84e33947SAndroid Build Coastguard Worker }
956*84e33947SAndroid Build Coastguard Worker 
sendAudioRelease()957*84e33947SAndroid Build Coastguard Worker DRAM_REGION_FUNCTION void sendAudioRelease() {
958*84e33947SAndroid Build Coastguard Worker   auto msgBuilder = [](ChreFlatBufferBuilder &builder, void * /*cookie*/) {
959*84e33947SAndroid Build Coastguard Worker     HostProtocolChre::encodeLowPowerMicAccessRelease(builder);
960*84e33947SAndroid Build Coastguard Worker   };
961*84e33947SAndroid Build Coastguard Worker   constexpr size_t kInitialSize = 32;
962*84e33947SAndroid Build Coastguard Worker   buildAndEnqueueMessage(PendingMessageType::LowPowerMicAccessRelease,
963*84e33947SAndroid Build Coastguard Worker                          kInitialSize, msgBuilder, /* cookie= */ nullptr);
964*84e33947SAndroid Build Coastguard Worker }
965*84e33947SAndroid Build Coastguard Worker 
966*84e33947SAndroid Build Coastguard Worker }  // namespace chre
967