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

Generated by: LCOV version 2.0-1