LCOV - code coverage report
Current view: top level - legacy/ascend950/framework/topo/topo_addr_info/src - hal.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 31.8 % 195 62
Test Date: 2026-08-29 17:38:31 Functions: 35.7 % 14 5

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2026 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "hal.h"
      12              : #include "topo_addr_info_log.h"
      13              : #include <stdint.h>
      14              : #include <stdio.h>
      15              : #include <time.h>
      16              : #include <dlfcn.h>
      17              : #include <stdarg.h>
      18              : #include <stdlib.h>
      19              : #include <string.h>
      20              : #include <ctype.h>
      21              : #include <string.h>
      22              : #include <unistd.h>
      23              : #include <sys/socket.h>
      24              : #include <sys/ioctl.h>
      25              : #include <net/if.h>
      26              : #include <net/if_arp.h>
      27              : #include <errno.h>
      28              : #include <pthread.h>
      29              : #include <syslog.h>
      30              : #include "securec.h"
      31              : 
      32              : #define MAX_LINE_LENGTH 256                    // 每行最大长度
      33              : #define TARGET_KEY "Driver_Install_Path_Param" // 要查找的key
      34              : 
      35              : #define DRIVER_DRFAULT_INSTALL_PATH "/usr/local/Ascend"
      36              : #define DRIVER_TOPO_FILE_DIR_PATH "driver/topo/950"
      37              : #define MAX_TOPO_FILENAME_LEN (64)
      38              : 
      39              : #define HAL_TRUE (1)
      40              : #define HAL_FALSE (0)
      41              : 
      42              : #define MODULE_TYPE_SYSTEM (0)
      43              : #define INFO_TYPE_SERVER_ID (27)
      44              : #define INFO_TYPE_SPOD_ID (29)
      45              : #define INFO_TYPE_MAINBOARD_ID (39)
      46              : #define INFO_TYPE_CHASSI_ID (48)
      47              : #define INFO_TYPE_SPOD_TYPE (49)
      48              : 
      49              : enum dcmi_main_cmd {
      50              :     DCMI_MAIN_CMD_DVPP = 0,
      51              :     DCMI_MAIN_CMD_ISP,
      52              :     DCMI_MAIN_CMD_TS_GROUP_NUM,
      53              :     DCMI_MAIN_CMD_CAN,
      54              :     DCMI_MAIN_CMD_UART,
      55              :     DCMI_MAIN_CMD_UPGRADE = 5,
      56              :     DCMI_MAIN_CMD_UFS,
      57              :     DCMI_MAIN_CMD_OS_POWER,
      58              :     DCMI_MAIN_CMD_LP,
      59              :     DCMI_MAIN_CMD_MEMORY,
      60              :     DCMI_MAIN_CMD_RECOVERY,
      61              :     DCMI_MAIN_CMD_TS,
      62              :     DCMI_MAIN_CMD_CHIP_INF,
      63              :     DCMI_MAIN_CMD_QOS,
      64              :     DCMI_MAIN_CMD_SOC_INFO,
      65              :     DCMI_MAIN_CMD_HCCS = 16,
      66              :     DCMI_MAIN_CMD_TEMP = 50,
      67              :     DCMI_MAIN_CMD_SVM = 51,
      68              :     DCMI_MAIN_CMD_VDEV_MNG,
      69              :     DCMI_MAIN_CMD_SIO = 56,
      70              :     DCMI_MAIN_CMD_DEVICE_SHARE = 0x8001,
      71              :     DCMI_MAIN_CMD_MAX
      72              : };
      73              : 
      74              : typedef enum {
      75              :     DCMI_CHIP_INFO_SUB_CMD_CHIP_ID,
      76              :     DCMI_CHIP_INFO_SUB_CMD_SPOD_INFO,
      77              :     DCMI_CHIP_INFO_SUB_CMD_MAX = 0xFF,
      78              : } DCMI_CHIP_INFO_SUB_CMD;
      79              : 
      80              : static int (*dcmi_init)(void);
      81              : 
      82              : static int (*dcmiv2_get_urma_device_cnt)(int npu_id, unsigned int* dev_cnt);
      83              : 
      84              : static int (*dcmiv2_get_eid_list_by_urma_dev_index)(
      85              :     int npu_id, int urma_dev_index, dcmi_urma_eid_info_t* eid_list, int* eid_cnt);
      86              : 
      87              : static int (*dcmiv2_get_device_pcie_info)(int npu_id, struct dcmi_pcie_info_all* pcie_info);
      88              : 
      89              : static int (*aclrtGetUserDevIdByPhyDevId)(const int32_t phyId, int32_t* const userDevId);
      90              : 
      91              : static int (*aclrtGetLogicDevIdByUserDevId)(const int32_t userDevId, int32_t* const logicId);
      92              : 
      93              : static int (*halGetDeviceInfo)(unsigned int devId, uint32_t moduleType, int32_t infoType, int64_t* value);
      94              : 
      95           16 : void* hal_dlopen(const char* filename, int flag) { return dlopen(filename, flag); }
      96              : 
      97            0 : void* hal_dlsym(void* handle, const char* symbol) { return dlsym(handle, symbol); }
      98              : 
      99           26 : int load_dcmi()
     100              : {
     101              :     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
     102              :     static void* dcmi = NULL;
     103              :     static void* acl = NULL;
     104              :     static int isInit = HAL_FALSE;
     105           26 :     pthread_mutex_lock(&mutex);
     106           26 :     if (dcmi != NULL && acl != NULL && isInit == HAL_TRUE) {
     107           17 :         pthread_mutex_unlock(&mutex);
     108           17 :         return 0;
     109              :     }
     110            9 :     if (dcmi == NULL || acl == NULL) {
     111            9 :         dcmi = hal_dlopen("libdcmi.so", RTLD_LAZY);
     112            9 :         acl = hal_dlopen("libacl_rt.so", RTLD_LAZY);
     113              :     }
     114              : 
     115            9 :     if (dcmi == NULL || acl == NULL) {
     116            8 :         pthread_mutex_unlock(&mutex);
     117            8 :         return -1;
     118              :     }
     119            1 :     dcmi_init = hal_dlsym(dcmi, "dcmiv2_init");
     120            1 :     dcmiv2_get_urma_device_cnt = hal_dlsym(dcmi, "dcmiv2_get_urma_device_cnt");
     121            1 :     dcmiv2_get_eid_list_by_urma_dev_index = hal_dlsym(dcmi, "dcmiv2_get_eid_list_by_urma_dev_index");
     122            1 :     dcmiv2_get_device_pcie_info = hal_dlsym(dcmi, "dcmiv2_get_device_pcie_info");
     123              : 
     124              :     // 兼容性处理 aclrtGetLogicDevIdByPhyDevId接口语义错误,实际返回的是UserDevId,优先使用新接口
     125            1 :     aclrtGetUserDevIdByPhyDevId = hal_dlsym(acl, "aclrtGetUserDevIdByPhyDevId");
     126            1 :     if (aclrtGetUserDevIdByPhyDevId == NULL) {
     127            0 :         aclrtGetUserDevIdByPhyDevId = hal_dlsym(acl, "aclrtGetLogicDevIdByPhyDevId");
     128              :     }
     129              : 
     130            1 :     halGetDeviceInfo = hal_dlsym(acl, "halGetDeviceInfo");
     131            1 :     aclrtGetLogicDevIdByUserDevId = hal_dlsym(acl, "aclrtGetLogicDevIdByUserDevId");
     132              : 
     133            1 :     if ((dcmi_init == NULL) || (dcmiv2_get_urma_device_cnt == NULL) || (dcmiv2_get_eid_list_by_urma_dev_index == NULL)
     134            1 :         || (halGetDeviceInfo == NULL) || (dcmiv2_get_device_pcie_info == NULL) || (aclrtGetUserDevIdByPhyDevId == NULL)
     135            1 :         || (aclrtGetLogicDevIdByUserDevId == NULL)) {
     136            0 :         pthread_mutex_unlock(&mutex);
     137            0 :         return -1;
     138              :     }
     139            1 :     (void)dcmi_init(); //  dcmi_init可能已经调用过了
     140            1 :     isInit = HAL_TRUE;
     141            1 :     pthread_mutex_unlock(&mutex);
     142            1 :     return 0;
     143              : }
     144              : 
     145           26 : int hal_get_mainboard_id(int phyId, unsigned int* mainboardId)
     146              : {
     147           26 :     unsigned int logicId = 0;
     148           26 :     if (hal_get_logicid_from_phyid((unsigned int)phyId, &logicId) != 0) {
     149            8 :         return -1;
     150              :     }
     151           18 :     int64_t value = 0;
     152           18 :     int ret = halGetDeviceInfo(logicId, MODULE_TYPE_SYSTEM, INFO_TYPE_MAINBOARD_ID, &value);
     153           18 :     if (ret == 0) {
     154           18 :         *mainboardId = (unsigned int)value;
     155              :     }
     156           18 :     return ret;
     157              : }
     158              : 
     159              : #define MAX_IFREQ_NUM (16)
     160          102 : int get_server_id(char* server_id, size_t len)
     161              : {
     162              :     int sock_fd;
     163              :     struct ifconf ifc;
     164              :     struct ifreq ifr[MAX_IFREQ_NUM];
     165              :     int if_count, i;
     166              : 
     167          102 :     if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
     168            0 :         return -1;
     169              :     }
     170              : 
     171          102 :     ifc.ifc_len = sizeof(ifr);
     172          102 :     ifc.ifc_buf = (char*)ifr;
     173          102 :     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
     174            0 :         close(sock_fd);
     175            0 :         return -1;
     176              :     }
     177              : 
     178          102 :     if_count = ifc.ifc_len / sizeof(struct ifreq);
     179          204 :     for (i = 0; i < if_count; ++i) {
     180          204 :         if (strcmp(ifr[i].ifr_name, "lo") == 0) {
     181          102 :             continue;
     182              :         }
     183          102 :         if (ioctl(sock_fd, SIOCGIFHWADDR, &ifr[i]) < 0) {
     184            0 :             continue;
     185              :         }
     186          102 :         if (ifr[i].ifr_hwaddr.sa_family != ARPHRD_ETHER) {
     187            0 :             continue;
     188              :         }
     189          102 :         unsigned char* mac = (unsigned char*)ifr[i].ifr_hwaddr.sa_data;
     190          102 :         (void)sprintf_s(server_id, len, "%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
     191          102 :         close(sock_fd);
     192          102 :         return 0;
     193              :     }
     194            0 :     close(sock_fd);
     195            0 :     return -1;
     196              : }
     197              : 
     198            0 : int hal_get_eid_list_by_phy_id(int phyId, dcmi_urma_eid_info_t* eidList, size_t* eidCnt)
     199              : {
     200            0 :     unsigned int logicId = 0;
     201            0 :     if (hal_get_logicid_from_phyid((unsigned int)phyId, &logicId) != 0) {
     202            0 :         return -1;
     203              :     }
     204            0 :     unsigned int dev_cnt = 0;
     205            0 :     int ret = dcmiv2_get_urma_device_cnt((int)logicId, &dev_cnt);
     206            0 :     if (ret != 0) {
     207            0 :         return ret;
     208              :     }
     209            0 :     size_t eid_current_cnt = 0;
     210            0 :     size_t eid_space_left = (*eidCnt);
     211            0 :     for (size_t i = 0; i < dev_cnt; ++i) {
     212            0 :         int left = (int)eid_space_left;
     213            0 :         ret = dcmiv2_get_eid_list_by_urma_dev_index((int)logicId, i, &eidList[eid_current_cnt], &left);
     214            0 :         if (ret != 0) {
     215            0 :             continue;
     216              :         }
     217            0 :         eid_space_left -= left;
     218            0 :         eid_current_cnt += left;
     219              :     }
     220            0 :     (*eidCnt) = eid_current_cnt;
     221            0 :     return 0;
     222              : }
     223              : 
     224            0 : int HalGetUBEntityList(int phyId, UEList* ueList)
     225              : {
     226            0 :     if (ueList == NULL) {
     227            0 :         return 0;
     228              :     }
     229            0 :     (void)memset_s(ueList, sizeof(UEList), 0x00, sizeof(UEList));
     230            0 :     unsigned int logicId = 0;
     231            0 :     if (hal_get_logicid_from_phyid((unsigned int)phyId, &logicId) != 0) {
     232            0 :         return -1;
     233              :     }
     234            0 :     int ret = dcmiv2_get_urma_device_cnt((int)logicId, &ueList->ueNum);
     235            0 :     if (ret != 0) {
     236            0 :         return ret;
     237              :     }
     238            0 :     for (size_t i = 0; i < ueList->ueNum; ++i) {
     239            0 :         int num = MAX_EID_PER_UE;
     240            0 :         ret = dcmiv2_get_eid_list_by_urma_dev_index((int)logicId, i, ueList->ueList[i].eidList, &num);
     241            0 :         if (ret != 0) {
     242            0 :             continue;
     243              :         }
     244            0 :         ueList->ueList[i].eidNum = (unsigned int)num;
     245              :     }
     246            0 :     return 0;
     247              : }
     248              : 
     249            0 : int hal_get_device_pcie_info(int phyId, struct dcmi_pcie_info_all* pcieInfo)
     250              : {
     251            0 :     unsigned int logicId = 0;
     252            0 :     if (hal_get_logicid_from_phyid((unsigned int)phyId, &logicId) != 0) {
     253            0 :         return -1;
     254              :     }
     255            0 :     return dcmiv2_get_device_pcie_info(logicId, pcieInfo);
     256              : }
     257              : 
     258            0 : int hal_get_spod_info(int phyId, struct dcmi_spod_info* spodInfo)
     259              : {
     260            0 :     unsigned int logicId = 0;
     261            0 :     if (hal_get_logicid_from_phyid((unsigned int)phyId, &logicId) != 0) {
     262            0 :         return -1;
     263              :     }
     264            0 :     int64_t spodId = 0;
     265            0 :     int64_t serverId = 0;
     266            0 :     int64_t chassisId = 0;
     267            0 :     int64_t spodType = 0;
     268            0 :     int ret1 = halGetDeviceInfo(logicId, MODULE_TYPE_SYSTEM, INFO_TYPE_SPOD_ID, &spodId);
     269            0 :     int ret2 = halGetDeviceInfo(logicId, MODULE_TYPE_SYSTEM, INFO_TYPE_SERVER_ID, &serverId);
     270            0 :     int ret3 = halGetDeviceInfo(logicId, MODULE_TYPE_SYSTEM, INFO_TYPE_CHASSI_ID, &chassisId);
     271            0 :     int ret4 = halGetDeviceInfo(logicId, MODULE_TYPE_SYSTEM, INFO_TYPE_SPOD_TYPE, &spodType);
     272            0 :     if (ret1 != 0 || ret2 != 0 || ret3 != 0 || ret4 != 0) {
     273            0 :         return -1;
     274              :     }
     275            0 :     spodInfo->super_pod_id = (unsigned int)spodId;
     276            0 :     spodInfo->server_index = (unsigned int)serverId;
     277            0 :     spodInfo->chassis_id = (unsigned int)chassisId;
     278            0 :     spodInfo->super_pod_type = (unsigned int)spodType;
     279            0 :     return 0;
     280              : }
     281              : 
     282            0 : int hal_get_npu_count()
     283              : {
     284              : #define MAX_NPU_COUNT (64)
     285              : #define MAX_DAVINCI_DEV_LEN (64)
     286            0 :     int count = 0;
     287            0 :     for (int i = 0; i < MAX_NPU_COUNT; ++i) {
     288            0 :         char davinci_dev[MAX_DAVINCI_DEV_LEN] = {0};
     289            0 :         (void)sprintf_s(davinci_dev, sizeof(davinci_dev), "/dev/davinci%d", i);
     290            0 :         if (access(davinci_dev, F_OK) == 0) {
     291            0 :             count++;
     292              :         }
     293              :     }
     294            0 :     return count;
     295              : }
     296              : 
     297           26 : int hal_get_logicid_from_phyid(unsigned int phyId, unsigned int* logicId)
     298              : {
     299           26 :     if (load_dcmi() != 0) {
     300            8 :         return -1;
     301              :     }
     302           18 :     int userDevId = -1;
     303           18 :     int ret = aclrtGetUserDevIdByPhyDevId((int)phyId, &userDevId);
     304           18 :     if (ret != 0) {
     305            0 :         return -1;
     306              :     }
     307           18 :     int value = -1;
     308           18 :     ret = aclrtGetLogicDevIdByUserDevId(userDevId, &value);
     309           18 :     if (ret != 0) {
     310            0 :         return -1;
     311              :     }
     312           18 :     *logicId = (unsigned int)value;
     313           18 :     return 0;
     314              : }
     315              : 
     316            0 : int hal_get_userdevid_by_phyid(int phyId, int* userDevId)
     317              : {
     318            0 :     if (load_dcmi() != 0) {
     319            0 :         return -1;
     320              :     }
     321            0 :     return aclrtGetUserDevIdByPhyDevId(phyId, userDevId);
     322              : }
     323              : 
     324              : // 去除字符串首尾的空白字符
     325            0 : static char* trim_whitespace(char* str)
     326              : {
     327              :     char* end;
     328              : 
     329              :     // 去除开头空格
     330            0 :     while (isspace((unsigned char)*str)) {
     331            0 :         str++;
     332              :     }
     333              :     // 如果字符串全是空格,返回空字符串
     334            0 :     if (*str == 0) {
     335            0 :         return str;
     336              :     }
     337              : 
     338              :     // 去除结尾空格
     339            0 :     end = str + strlen(str) - 1;
     340            0 :     while (end > str && isspace((unsigned char)*end)) {
     341            0 :         end--;
     342              :     }
     343              :     // 添加字符串结束符
     344            0 :     end[1] = '\0';
     345            0 :     return str;
     346              : }
     347              : 
     348              : /**
     349              :  * @brief 解析ascend_install.info文件,获取指定key的value
     350              :  * @param value_buf 存储结果的缓冲区
     351              :  * @param buf_size 缓冲区大小
     352              :  * @return 成功返回0,失败返回-1值
     353              :  */
     354            0 : int hal_get_driver_install_path(char* value_buf, size_t buf_size)
     355              : {
     356            0 :     FILE* fp = NULL;
     357            0 :     char* line = NULL;
     358            0 :     size_t len = 0;
     359              :     ssize_t read;
     360              :     // 参数合法性检查
     361            0 :     if (value_buf == NULL || buf_size == 0) {
     362            0 :         return -1;
     363              :     }
     364              :     // 初始化缓冲区
     365            0 :     value_buf[0] = '\0';
     366              : 
     367              :     // 打开文件
     368            0 :     fp = fopen("/etc/ascend_install.info", "r");
     369            0 :     if (fp == NULL) {
     370            0 :         if (strcpy_s(value_buf, buf_size, DRIVER_DRFAULT_INSTALL_PATH) != 0) {
     371            0 :             return -1;
     372              :         }
     373            0 :         return 0;
     374              :     }
     375              : 
     376              :     // 逐行读取文件
     377            0 :     while ((read = getline(&line, &len, fp)) != -1) {
     378              :         // 去除换行符
     379            0 :         char* newline = strchr(line, '\n');
     380            0 :         if (newline)
     381            0 :             *newline = '\0';
     382              : 
     383              :         // 查找等号位置
     384            0 :         char* equal_sign = strchr(line, '=');
     385            0 :         if (equal_sign == NULL) {
     386            0 :             continue; // 跳过没有等号的行
     387              :         }
     388              : 
     389              :         // 分割key和value
     390            0 :         *equal_sign = '\0';
     391            0 :         char* key = trim_whitespace(line);
     392            0 :         char* value = trim_whitespace(equal_sign + 1);
     393              : 
     394              :         // 匹配目标key
     395            0 :         if (strcmp(key, TARGET_KEY) == 0) {
     396              :             // 检查缓冲区大小
     397            0 :             if (strlen(value) + 1 > buf_size) {
     398            0 :                 break;
     399              :             }
     400              :             // 复制value到缓冲区
     401            0 :             errno_t ret = strcpy_s(value_buf, buf_size, value);
     402            0 :             if (ret != 0) {
     403            0 :                 break;
     404              :             }
     405            0 :             value_buf[buf_size - 1] = '\0';
     406            0 :             break;
     407              :         }
     408              :     }
     409              : 
     410              :     // 释放资源
     411            0 :     if (line) {
     412            0 :         free(line);
     413              :     }
     414            0 :     if (fp) {
     415            0 :         fclose(fp);
     416              :     }
     417            0 :     if (strlen(value_buf) == 0) {
     418              :         // 默认值兜底
     419            0 :         if (strcpy_s(value_buf, buf_size, DRIVER_DRFAULT_INSTALL_PATH) != 0) {
     420            0 :             return -1;
     421              :         }
     422              :     }
     423            0 :     return 0;
     424              : }
        

Generated by: LCOV version 2.0-1