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