Qnx wfd_be & wfd_fe Android 通讯
2023-12-20 17:53:24
在android 侧和 qnx 侧都指定mmid 使用habmm_socket_open 创建通讯channel
使用user_os_utils_send_recv完成消息的发送和接收
apps/qnx_ap/AMSS/multimedia/display/Hoya/wfd_be_qnx/src
/* -----------------------------------------------------------------------------
932 * Main
933 * ---------------------------------------------------------------------------*/
934 int main(int argc, char **argv)
935 {
936 uint32_t uI = 0x00;
937 uint32_t uJ = 0x00;
938 int iStatus = 0x00;
939 int iHabRet = 0x00;
940 uint32_t uDispID = 0x00;
941 uint32_t uClientIdx = 6; /* WFD_CLIENT_ID_LV_GVM is default */
942 int iArgFoundIndex = -1;
943 int rc = 0x00;
944 client_app_ctx *psCtx = &gCtx;
945 u32 uPacketSize = 0x00;
946 struct openwfd_req *psWFDReq = NULL;
947 struct openwfd_resp *psWFDResp = NULL;
948 struct openwfd_cmd *psWFDcmd = NULL;
949 struct openwfd_cmd *psWFDcmd_resp = NULL;
950 struct wire_header *psHDR = NULL;
951 struct wire_packet sReq;
952 struct wire_packet sResp;
953 char thread_name[HOST_OS_UTILS_THREAD_NAME_LEN_IN_BYTES];
954 struct sched_param params;
955 client_buf_channel_ctx sBufCtx;
956
957 params.sched_priority = THREAD_PRIORITY;
958 if (sched_setparam(0, ¶ms))
959 {
960 fprintf(stderr, "sched_setparam() failed %d \n", errno);
961 }
962
963 // Register signal and signal handler
964 signal(SIGINT, signal_handler);
965 signal(SIGTERM, signal_handler);
966
967 /* Arguments processing */
968 if (1 != argc)
969 {
970 /* print help info */
971 iArgFoundIndex = searchArgv(argc, argv, ARGV_PRINT_HELP);
972 if (-1 != iArgFoundIndex)
973 {
974 printHelp();
975 return 0;
976 }
977
978 uClientIdx = atoi(argv[1]);
979 fprintf(stderr, "passed in uClientIdx=%d\n", uClientIdx);
980
981 if (WFD_CLIENT_TYPE_MAX <= uClientIdx)
982 {
983 fprintf(stderr, "uClientIdx=%d is invalid, exiting...\n", uClientIdx);
984 return -1;
985 }
986 } //END: if 1 != argc
987
988 /* [TODO] Currently, we index all the entries at position 0 since we do not know the type for the client.
989 * Following initialization will be terminated once we pass-in the type as a parameter to the wfd_be app.
990 * The change will allows us to index at the right position for channel_map array for hab channel connection.
991 */
992 uClientIdx = WFD_CLIENT_TYPE_NONE;
993
994 /* init slog buffer */
995 if (-1 == host_os_utils_log_open())
996 {
997 fprintf(stderr, "%s host_os_utils_log_open Failed\n", __FUNCTION__);
998 return -1;
999 }
1000
1001 /* init Wire Host */
1002 if (0 != wire_host_init())
1003 {
1004 WFD_BE_LOG_ERROR("wire_host_init() failed");
1005 return -1;
1006 }
1007
1008 memset((char *)psCtx, 0x00, sizeof(client_app_ctx));
1009
1010 for (uI = 0; uI < WFD_APP_NUM_THREADS; uI++)
1011 {
1012 if (0 == MM_SignalQ_Create(&psCtx->sThreadInfo[uI].uThreadSigQueue))
1013 {
1014 if (0 != MM_Signal_Create(psCtx->sThreadInfo[uI].uThreadSigQueue,
1015 NULL, NULL,
1016 &psCtx->sThreadInfo[uI].uThreadSigHdl))
1017 {
1018 WFD_BE_LOG_ERROR("Failed to create a signal handle");
1019 iStatus = -1;
1020 MM_SignalQ_Release(psCtx->sThreadInfo[uI].uThreadSigQueue);
1021 goto MAIN_END;
1022 }
1023 }
1024 else
1025 {
1026 WFD_BE_LOG_ERROR("failed to create signal queue");
1027 iStatus = -1;
1028 goto MAIN_END;
1029 }
1030
1031 WFD_BE_LOG_INFO("uThreadSigQueue=%p uThreadSigHdl=%p",
1032 psCtx->sThreadInfo[uI].uThreadSigQueue,
1033 psCtx->sThreadInfo[uI].uThreadSigHdl);
1034 }
1035
1036 /* create worker thread for commit */
1037 for (uI = 0; uI < WFD_NUM_DISPLAY; uI++)
1038 {
1039 if (uI >= WFD_APP_NUM_THREADS)
1040 {
1041 WFD_BE_LOG_ERROR("Err: pthread create exceed max thread");
1042 break;
1043 }
1044 if (0 != MM_CriticalSection_Create(&psCtx->sThreadInfo[uI].uThreadLock))
1045 {
1046 WFD_BE_LOG_ERROR("CS creation failed, exiting");
1047 goto MAIN_END;
1048 }
1049 snprintf(thread_name,
1050 HOST_OS_UTILS_THREAD_NAME_LEN_IN_BYTES,
1051 "%s_%s_%u",
1052 HOST_OS_UTILS_LOG_MODULE_NAME,
1053 HOST_OS_UTILS_COMMIT_WORKER_NAME,
1054 uI);
1055 psCtx->sThreadInfo[uI].eThreadCtrl = THREAD_RUNNING;
1056 psCtx->sThreadInfo[uI].uArg = uI;
1057 if (0 != MM_Thread_CreateEx(THREAD_PRIORITY,
1058 0,
1059 &commit_worker,
1060 &psCtx->sThreadInfo[uI].uArg,
1061 THREAD_STACK_SIZE,
1062 thread_name,
1063 &psCtx->sThreadInfo[uI].uThreadHdl))
1064 {
1065 WFD_BE_LOG_ERROR("Err pthread_create failed on commit_worker");
1066 goto MAIN_END;
1067 }
1068 }
1069
1070 /* create worker threads for vsync */
1071 for (uI = WFD_NUM_DISPLAY; uI < (WFD_NUM_DISPLAY * 2); uI++)
1072 {
1073 if (uI > WFD_APP_NUM_THREADS)
1074 {
1075 WFD_BE_LOG_ERROR("Err: pthread create exceed max thread");
1076 break;
1077 }
1078 if (0 != MM_CriticalSection_Create(&psCtx->sThreadInfo[uI].uThreadLock))
1079 {
1080 WFD_BE_LOG_ERROR("CS creation failed, exiting");
1081 goto MAIN_END;
1082 }
1083 snprintf(thread_name,
1084 HOST_OS_UTILS_THREAD_NAME_LEN_IN_BYTES,
1085 "%s_%s_%u",
1086 HOST_OS_UTILS_LOG_MODULE_NAME,
1087 HOST_OS_UTILS_VSYNC_LISTENER_NAME,
1088 uI - WFD_NUM_DISPLAY);
1089 psCtx->sThreadInfo[uI].eThreadCtrl = THREAD_RUNNING;
1090 psCtx->sThreadInfo[uI].uArg = uI;
1091 if (0 != MM_Thread_CreateEx(THREAD_PRIORITY,
1092 0,
1093 &vsync_listener,
1094 &psCtx->sThreadInfo[uI].uArg,
1095 THREAD_STACK_SIZE,
1096 thread_name,
1097 &psCtx->sThreadInfo[uI].uThreadHdl))
1098 {
1099 WFD_BE_LOG_ERROR("Err pthread_create failed on event_listener");
1100 goto MAIN_END;
1101 }
1102 }
1103
1104 if (0 != MM_CriticalSection_Create(&psCtx->uCBChlLock))
1105 {
1106 WFD_BE_LOG_ERROR("CS creation failed, exiting");
1107 goto MAIN_END;
1108 }
1109 drop_abilities_wfd_be();
1110 while(!psCtx->iExitApp)
1111 {
1112 WFD_BE_LOG_CRITICAL_INFO("creating channels for uClientIdx=%d, batch_support=%d",
1113 uClientIdx, ENABLE_BATCH_COMMIT);
1114
1115 if (0x00 != channel_map[uClientIdx][HYP_CMD_CHANNEL_IDX])
1116 {
1117 /* create hypervisor channel with HAB */
1118 iHabRet = habmm_socket_open(&psCtx->iCmdChlHdl,
1119 channel_map[uClientIdx][HYP_CMD_CHANNEL_IDX],
1120 (uint32_t)HYPERVISOR_NO_TIMEOUT_VAL,
1121 0x00);
1122 if (0x00 != iHabRet)
1123 {
1124 WFD_BE_LOG_ERROR("habmm_socket_open() failed, iHabRet=%d", iHabRet);
1125 goto MAIN_END;
1126 }
1127 WFD_BE_LOG_CRITICAL_INFO("habmm_socket_open successful w iHabHandle=%d MM_ID=%d",
1128 psCtx->iCmdChlHdl, channel_map[uClientIdx][HYP_CMD_CHANNEL_IDX]);
1129 }
1130
1131 if (0x00 != channel_map[uClientIdx][HYP_EVENT_CHANNEL_IDX])
1132 {
1133 /* create hypervisor channel with HAB */
//创建一个handle=psCtx->iCbChlHdl
1134 iHabRet = habmm_socket_open(&psCtx->iCbChlHdl,
1135 channel_map[uClientIdx][HYP_EVENT_CHANNEL_IDX],
1136 (uint32_t)HYPERVISOR_NO_TIMEOUT_VAL,
1137 0x00);
1138 if (0x00 != iHabRet)
1139 {
1140 WFD_BE_LOG_ERROR("habmm_socket_open() failed, iHabRet=%d", iHabRet);
1141 habmm_socket_close(psCtx->iCmdChlHdl);
1142 goto MAIN_END;
1143 }
1144 WFD_BE_LOG_CRITICAL_INFO("habmm_socket_open successful w iHabHandle=%d MM_ID=%d",
1145 psCtx->iCbChlHdl, channel_map[uClientIdx][HYP_EVENT_CHANNEL_IDX]);
1146 }
1147
1148 if (0x00 != channel_map[uClientIdx][HYP_BUFFER_CHANNEL_IDX])
1149 {
1150 snprintf(thread_name,
1151 HOST_OS_UTILS_THREAD_NAME_LEN_IN_BYTES,
1152 "%s_%s",
1153 HOST_OS_UTILS_LOG_MODULE_NAME,
1154 HOST_OS_UTILS_BUF_CHANNEL_WORKER_NAME);
1155
1156 sBufCtx.uClientIdx = uClientIdx;
1157 sBufCtx.psCtx = psCtx;
1158 //创建线程WFD_BECommitWorker
1159 if (0 != MM_Thread_CreateEx(THREAD_PRIORITY,
1160 0,
1161 &buffer_channel_worker,
1162 &sBufCtx,
1163 THREAD_STACK_SIZE,
1164 thread_name,
1165 &psCtx->sThreadInfo[WFD_NUM_DISPLAY * 2].uThreadHdl))
1166 {
1167 WFD_BE_LOG_ERROR("Err pthread_create failed on buffer_channel_worker");
1168 }
1169 }
1170
1171 psCtx->uError_state = ERROR_STATE_HAB_OK;
1172
1173 /* reset variables */
1174 psHDR = &sResp.hdr;
1175 iHabRet = 0x00;
1176
1177 bmetrics_log_subcomponent_done("wfd_be main()");
1178
1179 while (!psCtx->iExitApp)
1180 {
1181 memset((char *)&sReq, 0x00, sizeof(struct wire_packet));
1182 memset((char *)&sResp, 0x00, sizeof(struct wire_packet));
1183 uPacketSize = sizeof(struct wire_packet);
1184
1185 /* wait for incoming messages from Guest */
//接受数据到sReq
1186 iHabRet = habmm_socket_recv(psCtx->iCmdChlHdl,
1187 (void *)&sReq,
1188 &uPacketSize,
1189 (uint32_t)HYPERVISOR_NO_TIMEOUT_VAL,
1190 0x00);
1191 if (0x00 != iHabRet)
1192 {
1193 psCtx->uError_state |= ERROR_STATE_HAB_BROKEN;
1194 cleanup(psCtx);
1195 WFD_BE_LOG_ERROR("hab channel is broken, recv() iHabRet=%d, exiting...", iHabRet);
1196 break;
1197 }
1198
1199 /* check package integrity */
1200 if (WIRE_FORMAT_MAGIC != sReq.hdr.magic_num)
1201 {
1202 WFD_BE_LOG_ERROR("invalid packet (magic=0x%08x)", sReq.hdr.magic_num);
1203 continue;
1204 }
1205 if ((OPENWFD_CMD != sReq.hdr.payload_type) &&
1206 (EVENT_REGISTRATION != sReq.hdr.payload_type))
1207 {
1208 WFD_BE_LOG_ERROR("invalid packet (payload_type=0x%08x)", sReq.hdr.payload_type);
1209 continue;
1210 }
1211 if (uPacketSize != sReq.hdr.payload_size + sizeof(sReq.hdr))
1212 {
1213 WFD_BE_LOG_ERROR("invalid packet (bytes_reaad=%u != payload_size=%u + hdr_size=%u)",
1214 uPacketSize, sReq.hdr.payload_size, sizeof(sReq.hdr));
1215 continue;
1216 }
1217
1218 if (OPENWFD_CMD == sReq.hdr.payload_type)
1219 {
1220 if (DISPLAY_SHIM_OPENWFD_CMD_VERSION != sReq.hdr.version)
1221 {
1222 WFD_BE_LOG_ERROR("invalid packet (version=0x%08x)", sReq.hdr.version);
1223 continue;
1224 }
1225
1226 psWFDReq = (struct openwfd_req *)&sReq.payload;
1227 psWFDResp = (struct openwfd_resp *)&sResp.payload;
1228 psWFDcmd = (struct openwfd_cmd *)&psWFDReq->reqs[0];
1229 psWFDcmd_resp = (struct openwfd_cmd *)&psWFDResp->resps[0];
1230
1231 if (OPENWFD_CMD_MAX <= psWFDcmd->type)
1232 {
1233 WFD_BE_LOG_ERROR("invalid cmd type (type=%d)", psWFDcmd->type);
1234 continue;
1235 }
1236 WFD_BE_LOG_INFO("Calling WFD CMD (type=%d) for iHabHandle=%d",
1237 psWFDcmd->type, psCtx->iCmdChlHdl);
1238
1239 if (1 < psWFDReq->num_of_cmds)
1240 {
1241 #if ENABLE_BATCH_COMMIT
1242 // Batch mode packet
1243 rc = batch_cmd(psWFDcmd, psWFDcmd_resp,
1244 sReq.hdr.payload_size,
1245 psWFDReq->num_of_cmds);
1246 if (rc)
1247 {
1248 WFD_BE_LOG_ERROR("batch cmd failed, num_of_cmd=%d payload_size=%d error(%d)",
1249 psWFDReq->num_of_cmds, sReq.hdr.payload_size, rc);
1250 }
1251 #else
1252 WFD_BE_LOG_ERROR("Batch mode NOT supported, num_of_cmd=%d. Exiting...",
1253 psWFDReq->num_of_cmds);
1254 cleanup(psCtx);
1255 break;
1256 #endif
1257 }
1258 else if (NULL != wfd_be_func[psWFDcmd->type])
1259 {
1260 rc = wfd_be_func[psWFDcmd->type](psWFDcmd, psWFDcmd_resp);
1261 if (rc)
1262 {
1263 WFD_BE_LOG_ERROR("cmd type(%d) handler returned error(%d)",
1264 psWFDcmd->type, rc);
1265 continue;
1266 }
1267 }
1268 else
1269 {
1270 WFD_BE_LOG_ERROR("Function definition mismatch cmd(%d), exiting...",
1271 psWFDcmd->type);
1272 cleanup(psCtx);
1273 break;
1274 }
1275
1276 memcpy(psHDR, &sReq.hdr, sizeof(struct wire_header));
1277 psHDR->payload_size = sizeof(struct openwfd_batch_cmd) +
1278 wire_user_cmd_size[psWFDcmd->type] +
1279 sizeof(u32); /* status */
1280 uPacketSize = sizeof(struct wire_header) + psHDR->payload_size;
1281 psWFDResp->num_of_cmds = psWFDReq->num_of_cmds; //TODO: May need to do better1282 psWFDcmd_resp->type = psWFDcmd->type; //TODO: May need to do better1283 }
1284 else if (EVENT_REGISTRATION == sReq.hdr.payload_type)
1285 {
1286 if (DISPLAY_SHIM_EVENT_VERSION != sReq.hdr.version)
1287 {
1288 WFD_BE_LOG_ERROR("invalid packet (version=0x%08x)", sReq.hdr.version);
1289 continue;
1290 }
1291
1292 // activate callback
1293 WFD_BE_LOG_INFO("event register");
1294 uDispID = sReq.payload.ev_req.info.disp_event.display_id;
1295 if (sReq.payload.ev_req.info.disp_event.type == DISP_VSYNC)
1296 {
1297 for (uI = 0; uI < WFD_NUM_DISPLAY; uI++)
1298 {
1299 if (psCtx->sPortInfo[uI].uPortId == uDispID)
1300 {
1301 break;
1302 }
1303 }
1304
1305 /* If not found */
1306 if (uI == WFD_NUM_DISPLAY)
1307 {
1308 WFD_BE_LOG_ERROR("Invalid display id (%d)", uDispID);
1309 sResp.payload.ev_resp.status = WIRE_STS_BAD_PARAM;
1310 }
1311 else
1312 {
1313 uI += WFD_NUM_DISPLAY;
1314 WFD_BE_LOG_INFO("signal ThreadQ:%d disp_id:%d", uI, uDispID);
1315
1316 MM_Signal_Set(psCtx->sThreadInfo[uI].uThreadSigHdl);
1317 }
1318 }
1319
1320 memcpy(psHDR, &sReq.hdr, sizeof(struct wire_header));
1321 psHDR->payload_size = sizeof(struct event_resp);
1322 uPacketSize = sizeof(struct wire_header) + psHDR->payload_size;
1323 }
1324
1325 if (sReq.hdr.flags & WIRE_RESP_NOACK_FLAG)
1326 {
1327 continue;
1328 }
1329
1330 iHabRet = habmm_socket_send(psCtx->iCmdChlHdl,
1331 (void *)&sResp,
1332 uPacketSize,
1333 0x00);
1334 if (0x00 != iHabRet)
1335 {
1336 WFD_BE_LOG_ERROR("habmm_socket_send(sResp) failed, iRet=%d", iHabRet);
1337 }
1338 WFD_BE_LOG_INFO("habmm_socket_send successful w iHabHandle=%d", psCtx->iCmdChlHdl);
1339 }
1340
1341 /* If client didn't close properly, clean-up on their behalf */
1342 if (0 < psCtx->uNumDevices)
1343 {
1344 /* Destroy pipelines */
1345 for (uI = 0; uI < WFD_NUM_PIPELINES; uI++)
1346 {
1347 if (NULL != psCtx->sPipelineInfo[uI].hPipelineHdl)
1348 {
1349 (void)wfdDestroyPipeline(psCtx->sPipelineInfo[uI].hDevHdl,
1350 psCtx->sPipelineInfo[uI].hPipelineHdl);
1351
1352 memset((char *)&psCtx->sPipelineInfo[uI], 0x00, sizeof(pipeline_info));
1353 }
1354 }
1355
1356 /* Destroy ports */
1357 for (uI = 0; uI < WFD_NUM_DISPLAY; uI++)
1358 {
1359 if (NULL != psCtx->sPortInfo[uI].hPortHdl)
1360 {
1361 (void)wfdDestroyPort(psCtx->sPortInfo[uI].hDevHdl,
1362 psCtx->sPortInfo[uI].hPortHdl);
1363
1364 memset((char *)&psCtx->sPortInfo[uI], 0x00, sizeof(port_info));
1365 }
1366 }
1367 }
1368
1369 /* Destroy device */
1370 for (uJ = 0; uJ < WFD_DEVICE_ID_MAX; uJ++)
1371 {
1372 (void)wfdDestroyDevice(psCtx->hDevHdl[uJ]);
1373 psCtx->hDevHdl[uJ] = NULL;
1374 }
1375 psCtx->uNumDevices = 0;
1376 if (0x00 != psCtx->iCbChlHdl)
1377 {
1378 habmm_socket_close(psCtx->iCbChlHdl);
1379 WFD_BE_LOG_CRITICAL_INFO("habmm_socket_close successful w iHabHandle=%d", psCtx->iCbChlHdl);
1380 psCtx->iCbChlHdl = 0x00;
1381 }
1382 if (0x00 != psCtx->iCmdChlHdl)
1383 {
1384 habmm_socket_close(psCtx->iCmdChlHdl);
1385 WFD_BE_LOG_CRITICAL_INFO("habmm_socket_close successful w iHabHandle=%d", psCtx->iCmdChlHdl);
1386 psCtx->iCmdChlHdl = 0x00;
1387 }
1388 if (0x00 != psCtx->iBufChlHdl)
1389 {
1390 habmm_socket_close(psCtx->iBufChlHdl);
1391 WFD_BE_LOG_CRITICAL_INFO("habmm_socket_close successful w iHabHandle=%d", psCtx->iBufChlHdl);
1392 psCtx->iBufChlHdl = 0x00;
1393 }
1394 }
1395
1396 MAIN_END:
1397 iStatus = work_destroy(psCtx);
1398
1399 return iStatus;
1400 }
1401
1402 #ifdef __cplusplus
1403 }
1404 #endif
??qnx channel_map配置
static u32 channel_map[WFD_CLIENT_TYPE_MAX][3] =
87 {
88 /* Each MM ID translates to a physical channel per VM.
89 * Different clients on the same VM should use different MM IDs.
90 */
91
92 /* This is the default index, for the clients that do not know the type.
93 * [TODO] Following entry will be terminated once we pass-in the client type as one of
94 * the parameters to the wfd_be app. This will allow us to know the client type with certainty.
95 */
96 [WFD_CLIENT_TYPE_NONE]
97 {
98 MM_DISP_1,
99 MM_DISP_2,
100 MM_DISP_3
101 },
102 [WFD_CLIENT_TYPE_TELLTALE] /* Tell-Tale App */
103 {
104 MM_DISP_5105 },
106 [WFD_CLIENT_TYPE_CLUSTER] /* QNX GVM */
107 {
108 MM_DISP_3,
109 MM_DISP_4110 },
111 [WFD_CLIENT_TYPE_LA_GVM] /* LA GVM */
112 {
113 MM_DISP_1,
114 MM_DISP_2115 },
116 [WFD_CLIENT_TYPE_LV_GVM] /* LV GVM */
117 {
118 MM_DISP_1,
119 MM_DISP_2120 },
121 };
linux 中的配置virtio_device
lagvm/LINUX/android/kernel/msm-5.4/drivers/soc/qcom/hab/hab_virtio.c
static struct virtio_device_tbl {
29 int32_t mmid;
30 __u32 device;
31 struct virtio_device *vdev;
32 } vdev_tbl[] = {
33 { HAB_MMID_ALL_AREA, HAB_VIRTIO_DEVICE_ID_HAB, NULL }, /* hab */34 { MM_BUFFERQ_1, HAB_VIRTIO_DEVICE_ID_BUFFERQ, NULL },
35 { MM_MISC, HAB_VIRTIO_DEVICE_ID_MISC, NULL },
36 { MM_AUD_1, HAB_VIRTIO_DEVICE_ID_AUDIO, NULL },
37 { MM_CAM_1, HAB_VIRTIO_DEVICE_ID_CAMERA, NULL },
38 { MM_DISP_1, HAB_VIRTIO_DEVICE_ID_DISPLAY, NULL },
39 { MM_GFX, HAB_VIRTIO_DEVICE_ID_GRAPHICS, NULL },
40 { MM_VID, HAB_VIRTIO_DEVICE_ID_VIDEO, NULL },
41 };
?hab 中配置的 mmid信息
lagvm/LINUX/android/kernel/msm-5.4/drivers/soc/qcom/hab/hab_ghs.c
/* same vmid assignment for all the vms. it should matches dt_gipc_path_name */
11 static int mmid_order[GIPC_VM_SET_CNT] = {
12 MM_AUD_1,
13 MM_AUD_2,
14 MM_AUD_3,
15 MM_AUD_4,
16 MM_CAM_1,
17 MM_CAM_2,
18 MM_DISP_1,
19 MM_DISP_2,
20 MM_DISP_3,
21 MM_DISP_4,
22 MM_DISP_5,
23 MM_GFX,
24 MM_VID,
25 MM_MISC,
26 MM_QCPE_VM1,
27 MM_VID_2, /* newly recycled */28 0,
29 0,
30 MM_CLK_VM1,
31 MM_CLK_VM2,
32 MM_FDE_1,
33 MM_BUFFERQ_1,
34 };
Qnx 创建DSPY_1 channel
wfd_be
//发送mm_ip_id=channel_map[uClientIdx][HYP_CMD_CHANNEL_IDX]=MM_DISP_1
//匹配共享内存区域
uClientIdx = WFD_CLIENT_TYPE_NONE;
iHabRet = habmm_socket_open(&psCtx->iCmdChlHdl,
channel_map[uClientIdx][HYP_CMD_CHANNEL_IDX],
(uint32_t)HYPERVISOR_NO_TIMEOUT_VAL,
0x00);
Linux WFD Client初始化解析dtsi open hab的mmidWFD_CLIENT_ID_LA_GVM 的MM_DISP_1建立于qnx 通讯的共享内存通道
enum WFDClientIdType {
36 WFD_CLIENT_ID_CLUSTER = 0x7810,
37 WFD_CLIENT_ID_MONITOR = 0x7811,
38 WFD_CLIENT_ID_TELLTALE = 0x7812,
39 WFD_CLIENT_ID_RVC = 0x7813,
40 WFD_CLIENT_ID_QNX_GVM = 0x7814,
41 WFD_CLIENT_ID_LA_GVM = 0x7815,
42 WFD_CLIENT_ID_LV_GVM = 0x7816,
43 WFD_CLIENT_ID_FORCE_32BIT = 0x7FFFFFFF
44 };
Linux clientid 的配置与mmid的WFDClientIdType 保持一致
&wfd_kms {
2 qcom,client-id="7816";
3 };
4
5 &soc {
6 sde_cfg: qcom,sde-cfg {
7 compatible = "qcom,sde-cfg";
8
9 qcom,sde-sub-cfg@0 {
10 reg = <0>;
11 wfd_kms1: qcom,wfd_kms@1 {
12 compatible = "qcom,wfd-kms";
13 qcom,client-id = "7818";
14 };
15
16 qcom,sde_kms_hyp@ae10000 {
17 compatible = "qcom,sde-kms-hyp";
18 qcom,kms = <&wfd_kms1>;
19 };
20
21 wfd_kms2: qcom,wfd_kms@2 {
22 compatible = "qcom,wfd-kms";
23 qcom,client-id = "7819";
24 };
25
26 qcom,sde_kms_hyp@ae20000 {
27 compatible = "qcom,sde-kms-hyp";
28 qcom,kms = <&wfd_kms2>;
29 };
30
31 wfd_kms3: qcom,wfd_kms@3 {
32 compatible = "qcom,wfd-kms";
33 qcom,client-id = "7815";
34 };
35
36 qcom,sde_kms_hyp@ae30000 {
37 compatible = "qcom,sde-kms-hyp";
38 qcom,kms = <&wfd_kms3>;
39 };
40 };
41
42 qcom,sde-sub-cfg@1 {
43 reg = <1>;
44 qcom,sde_kms_hyp@ae10000 {
45 compatible = "qcom,sde-kms-hyp-legacy";
46 qcom,client-id = "7818";
47 };
48
49 qcom,sde_kms_hyp@ae20000 {
50 compatible = "qcom,sde-kms-hyp-legacy";
51 qcom,client-id = "7819";
52 };
53
54 qcom,sde_kms_hyp@ae30000 {
55 compatible = "qcom,sde-kms-hyp-legacy";
56 qcom,client-id = "7815";
57 };
58 };
59 };
60 };
61
static u32 channel_map[WFD_MAX_NUM_OF_CLIENTS][3] = {
77 /* Each MM ID translates to a physical channel per VM.
78 * Different clients on the same VM should use different MM IDs.
79 */
80 [WFD_CLIENT_ID_TELLTALE - WFD_CLIENT_ID_BASE] /* Tell-Tale App */
81 {
82 MM_DISP_5
83 },
84 [WFD_CLIENT_ID_QNX_GVM - WFD_CLIENT_ID_BASE] /* QNX GVM */
85 {
86 MM_DISP_3,
87 MM_DISP_4
88 },
89 [WFD_CLIENT_ID_LA_GVM - WFD_CLIENT_ID_BASE] /* LA GVM */
90 {
91 MM_DISP_1,
92 MM_DISP_2,
93 MM_DISP_3
94 },
95 [WFD_CLIENT_ID_LV_GVM - WFD_CLIENT_ID_BASE] /* LV GVM */
96 {
97 MM_DISP_1,
98 MM_DISP_2,
99 MM_DISP_3
100 },
101 [WFD_CLIENT_ID_LA_CONTAINER - WFD_CLIENT_ID_BASE] /* LA Container */
102 {
103 MM_DISP_1,
104 MM_DISP_2,
105 MM_DISP_3
106 },
107 [WFD_CLIENT_ID_LV_CONTAINER - WFD_CLIENT_ID_BASE] /* LV Container */
108 {
109 MM_DISP_1,
110 MM_DISP_2,
111 MM_DISP_3
112 },
113 };
Linux 侧 wfd_fe 解析dtsi 配置
lagvm/LINUX/android/kernel/msm-5.4/techpack/display/msm-hyp/wfd/wfd_kms.c
static int wfd_kms_probe(struct platform_device *pdev)
1602 {
1603 struct device *dev = &pdev->dev;
1604 struct wfd_kms *kms;
1605 int ret;
1606 char marker_buff[MARKER_BUFF_LENGTH] = {0};
1607
1608 kms = devm_kzalloc(dev, sizeof(*kms), GFP_KERNEL);
1609 if (!kms)
1610 return -ENOMEM;
1611
1612 ret = _wfd_kms_parse_dt(dev->of_node, &kms->client_id);
1613 if (ret)
1614 return ret;
1615
1616 ret = _wfd_kms_hw_init(kms);
1617 if (ret)
1618 return ret;
1619
1620 kms->base.funcs = &wfd_kms_funcs;
1621
1622 platform_set_drvdata(pdev, kms);
1623
1624 ret = component_add(&pdev->dev, &wfd_kms_comp_ops);
1625 if (ret) {
1626 pr_err("component add failed, rc=%d\n", ret);
1627 return ret;
1628 }
1629
1630 snprintf(marker_buff, sizeof(marker_buff),
1631 "kernel_fe: wfd_kms probe client %x", kms->client_id);
1632 place_marker(marker_buff);
1633
1634 return 0;
1635 }
lagvm/LINUX/android/kernel/msm-5.4/techpack/display/msm-hyp/wfd/wire_user.c
static int _wfd_kms_hw_init(struct wfd_kms *kms)
668 {
669 WFDint wfd_ids[MAX_DEVICE_CNT];
670 WFDint num_dev = 0;
671 WFDDevice wfd_dev = WFD_INVALID_HANDLE;
672 WFDint attribs[3];
673 WFDint wfd_port_ids[MAX_PORT_CNT];
674 WFDPort port;
675 int i, j, num_port, port_idx;
676 int rc;
677 int all_ports_cnt = 0;
678 struct wfd_kms_port wfd_kms_ports[MAX_PORT_CNT] = {{0, 0, 0}};
679 char marker_buff[MARKER_BUFF_LENGTH] = {0};
680
681 attribs[0] = WFD_DEVICE_CLIENT_TYPE;
682 attribs[1] = kms->client_id;
683 attribs[2] = WFD_NONE;
684
685 rc = wire_user_init(kms->client_id, WIRE_INIT_EVENT_SUPPORT);
686 if (rc) {
687 pr_err("failed to init wire user for client %x\n", kms->client_id);
688 return rc;
689 }
690
691 snprintf(marker_buff, sizeof(marker_buff),
692 "kernel_fe: wire client %x ready", kms->client_id);
693 place_marker(marker_buff);
694
695 /* open a open WFD device */
696 num_dev = wfdEnumerateDevices_User(NULL, 0, attribs);
697 if (!num_dev) {
698 pr_info("wfdEnumerateDevices_User - failed for client %x!\n",
699 kms->client_id);
700 /* TODO: Debug and add back wire_user_deinit(kms->client_id, 0x00) */
701 }
702
703 wfdEnumerateDevices_User(wfd_ids, num_dev, attribs);
704
705 for (j = 0; j < num_dev; j++) {
706 wfd_dev = wfdCreateDevice_User(wfd_ids[j], attribs);
707 if (wfd_dev == WFD_INVALID_HANDLE) {
708 pr_debug("wfdCreateDevice_User - failed\n");
709 continue;
710 }
711
712 kms->wfd_device[kms->wfd_device_cnt] = wfd_dev;
713 kms->wfd_device_cnt++;
714
715 num_port = wfdEnumeratePorts_User(wfd_dev, NULL, 0, NULL);
716
717 wfdEnumeratePorts_User(wfd_dev, wfd_port_ids, num_port, NULL);
718
719 for (i = 0; i < num_port; i++) {
720 port = wfdCreatePort_User(
721 wfd_dev, wfd_port_ids[i], NULL);
722 if (port == WFD_INVALID_HANDLE)
723 continue;
724
725 wfd_kms_ports[all_ports_cnt].wfd_port = port;
726 wfd_kms_ports[all_ports_cnt].wfd_device = wfd_dev;
727 wfd_kms_ports[all_ports_cnt].wfd_port_id = wfd_port_ids[i];
728 all_ports_cnt++;
729 }
730 }
731
732 if (!kms->wfd_device_cnt)
733 pr_info("can't find valid WFD device\n");
734
735 /* Sort wfd_kms_port by wfd_port_id */
736 if (all_ports_cnt > 1)
737 sort(wfd_kms_ports, all_ports_cnt, sizeof(wfd_kms_ports[0]),
738 wfd_kms_port_cmp, NULL);
739
740 for (port_idx = 0; port_idx < all_ports_cnt; port_idx++) {
741 kms->ports[port_idx] = wfd_kms_ports[port_idx].wfd_port;
742 kms->port_ids[port_idx] = wfd_kms_ports[port_idx].wfd_port_id;
743 kms->port_devs[port_idx] = wfd_kms_ports[port_idx].wfd_device;
744 kms->port_cnt++;
745
746 _wfd_kms_pipeline_init(kms, kms->port_devs[port_idx],
747 kms->ports[port_idx], port_idx);
748 }
749
750 return 0;
751 }
lagvm/LINUX/android/kernel/msm-5.4/techpack/display/msm-hyp/wfd/wire_user.c
/*
527 * ---------------------------------------------------------------------------
528 * Wire User APIs
529 * ---------------------------------------------------------------------------
530 */
531
532 int
533 wire_user_init(u32 client_id,
534 u32 flags)
535 {
536 struct wire_context *ctx;
537 int rc = 0;
538
539 wire_user_heap_init();
540
541 list_for_each_entry(ctx, &g_context_list, head) {
542 if (ctx->init_info.client_id == client_id) {
543 WIRE_LOG_ERROR("client %d already inited\n", client_id);
544 return -EINVAL;
545 }
546 }
547
548 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
549 if (!ctx)
550 return -ENOMEM;
551
552 ctx->init_info.client_id = client_id;
553
554 rc = user_os_utils_init(&ctx->init_info, flags);
555 if (rc) {
556 WIRE_LOG_ERROR("user_os_utils_init failed");
557 goto fail;
558 }
559
560 /* event handling initialization */
561 if ((rc == 0) && (ctx->init_info.enable_event_handling)) {
562 ctx->wire_isr_enable = true;
563 ctx->wire_isr_stop = false;
564 /* init event callback lock */
565 spin_lock_init(&ctx->_event_cb_lock);
566
567 /* create event listener thread */
568 ctx->listener_thread = kthread_run(event_listener, ctx,
569 "wfd event listener");
570
571 INIT_LIST_HEAD(&ctx->_cb_info_ctx);
572 }
573
574 list_add_tail(&ctx->head, &g_context_list);
575
576 return 0;
577 fail:
578 kfree(ctx);
579 return rc;
580 }
Linux open的pchan 指定的mmid[WFD_CLIENT_ID_LA_GVM - WFD_CLIENT_ID_BASE]
lagvm/LINUX/android/kernel/msm-5.4/techpack/display/msm-hyp/wfd/user_hab_utils.c
/*
231 * ---------------------------------------------------------------------------
232 * Public Functions
233 * ---------------------------------------------------------------------------
234 */
235 int
236 user_os_utils_init(
237 struct user_os_utils_init_info *init_info,
238 u32 flags)
239 {
240 struct user_os_utils_context *ctx;
241 int rc = 0;
242 int client_id = init_info->client_id;
243 int client_idx = 0;
244
245 if ((client_id < WFD_CLIENT_ID_CLUSTER) ||
246 (client_id > WFD_CLIENT_ID_LV_CONTAINER))
247 return -EINVAL;
248
249 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
250 if (!ctx)
251 return -ENOMEM;
252
253 init_info->clock_id = CLOCK_MONOTONIC;
254 init_info->enable_event_handling = (flags & WIRE_INIT_EVENT_SUPPORT) ?
255 true : false;
256
257 client_idx = client_id - WFD_CLIENT_ID_BASE;
258
259 if (channel_map[client_idx][CHANNEL_OPENWFD] != 0x00) {
260 /* open hab channel for openwfd commands */
261 #ifdef USE_HAB
262 rc = habmm_socket_open(
263 #else
264 rc = habmm_socket_open_dummy(
265 #endif
//open的pchan 指定的mmid[WFD_CLIENT_ID_LA_GVM - WFD_CLIENT_ID_BASE]
266 &ctx->hyp_hdl_disp[CHANNEL_OPENWFD],
267 channel_map[client_idx][CHANNEL_OPENWFD],
268 (uint32_t)HAB_NO_TIMEOUT_VAL,
269 0x00);
270 if (rc) {
271 UTILS_LOG_ERROR("habmm_socket_open(HAB_CHNL_OPENWFD) failed");
272 goto fail;
273 }
274 } else {
275 UTILS_LOG_ERROR("invalid hab channel id");
276 rc = -EINVAL;
277 goto fail;
278 }
279 /* create lock for openwfd commands hab channel */
280 spin_lock_init(&ctx->hyp_cmdchl_lock);
281
282 UTILS_LOG_CRITICAL_INFO("OpenWFD channel open successful, handle=%d",
283 ctx->hyp_hdl_disp[CHANNEL_OPENWFD]);
284
285 /* Initialize the flag */
286 ctx->cmdchl_lock_flags[CHANNEL_OPENWFD] = 0;
287
288 if ((init_info->enable_event_handling) &&
289 (channel_map[client_idx][CHANNEL_EVENTS]) != 0x00) {
290 /* open hab channel for events handling */
291 #ifdef USE_HAB
292 rc = habmm_socket_open(
293 #else
294 rc = habmm_socket_open_dummy(
295 #endif
296 &ctx->hyp_hdl_disp[CHANNEL_EVENTS],
297 channel_map[client_idx][CHANNEL_EVENTS],
298 (uint32_t)HAB_NO_TIMEOUT_VAL,
299 0x00);
300 if (rc) {
301 UTILS_LOG_ERROR("habmm_socket_open(HAB_CHNL_EVENTS) failed");
302 goto fail;
303 }
304 /* create lock for events handling hab channel */
305 mutex_init(&ctx->hyp_cbchl_lock);
306 UTILS_LOG_CRITICAL_INFO("Events channel open successful, handle=%d",
307 ctx->hyp_hdl_disp[CHANNEL_EVENTS]);
308
309 /* Initialize the flag */
310 ctx->cmdchl_lock_flags[CHANNEL_EVENTS] = 0;
311
312 }
313
314 /* create a thread buffer channel */
315 ctx->client_idx = client_idx;
316 ctx->buffer_thread = kthread_run(buffer_channel_task, ctx,
317 "buffer channel task");
318
319 ctx->client_id = client_id;
320 init_info->context = ctx;
321 return 0;
322
323 fail:
324 kfree(ctx);
325 return rc;
326 }
文章来源:https://blog.csdn.net/wing_7/article/details/135107285
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!