Qnx wfd_be & wfd_fe Android 通讯

在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, &params))
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_GVMMM_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  }

  • 10
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值