Blame external/opae-test/framework/platform/fpga_hw.cpp

Packit 534379
// Copyright(c) 2017-2018, Intel Corporation
Packit 534379
//
Packit 534379
// Redistribution  and  use  in source  and  binary  forms,  with  or  without
Packit 534379
// modification, are permitted provided that the following conditions are met:
Packit 534379
//
Packit 534379
// * Redistributions of  source code  must retain the  above copyright notice,
Packit 534379
//   this list of conditions and the following disclaimer.
Packit 534379
// * Redistributions in binary form must reproduce the above copyright notice,
Packit 534379
//   this list of conditions and the following disclaimer in the documentation
Packit 534379
//   and/or other materials provided with the distribution.
Packit 534379
// * Neither the name  of Intel Corporation  nor the names of its contributors
Packit 534379
//   may be used to  endorse or promote  products derived  from this  software
Packit 534379
//   without specific prior written permission.
Packit 534379
//
Packit 534379
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 534379
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO,  THE
Packit 534379
// IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit 534379
// ARE DISCLAIMED.  IN NO EVENT  SHALL THE COPYRIGHT OWNER  OR CONTRIBUTORS BE
Packit 534379
// LIABLE  FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
Packit 534379
// CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT  OF
Packit 534379
// SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
Packit 534379
// INTERRUPTION)  HOWEVER CAUSED  AND ON ANY THEORY  OF LIABILITY,  WHETHER IN
Packit 534379
// CONTRACT,  STRICT LIABILITY,  OR TORT  (INCLUDING NEGLIGENCE  OR OTHERWISE)
Packit 534379
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
Packit 534379
// POSSIBILITY OF SUCH DAMAGE.
Packit 534379
#include "fpga_hw.h"
Packit 534379
#include <dirent.h>
Packit 534379
#include <string.h>
Packit 534379
#include <sys/stat.h>
Packit 534379
#include <unistd.h>
Packit 534379
#include <algorithm>
Packit 534379
#include <iostream>
Packit 534379
#include <fstream>
Packit 534379
#include "mock/test_utils.h"
Packit 534379
#include <glob.h>
Packit 534379
#include <iomanip>
Packit 534379
#include <sstream>
Packit 534379
Packit 534379
#define FPGA_BBS_VER_MAJOR(i) (((i) >> 56) & 0xf)
Packit 534379
#define FPGA_BBS_VER_MINOR(i) (((i) >> 52) & 0xf)
Packit 534379
#define FPGA_BBS_VER_PATCH(i) (((i) >> 48) & 0xf)
Packit 534379
Packit 534379
namespace opae {
Packit 534379
namespace testing {
Packit 534379
Packit 534379
test_device test_device::unknown() {
Packit 534379
  return test_device{.fme_guid = "C544CE5C-F630-44E1-8551-59BD87AF432E",
Packit 534379
                     .afu_guid = "C544CE5C-F630-44E1-8551-59BD87AF432E",
Packit 534379
                     .segment = 0x1919,
Packit 534379
                     .bus = 0x0A,
Packit 534379
                     .device = 9,
Packit 534379
                     .function = 5,
Packit 534379
                     .num_vfs = 0,
Packit 534379
                     .socket_id = 9,
Packit 534379
                     .num_slots = 9,
Packit 534379
                     .bbs_id = 9,
Packit 534379
                     .bbs_version = {0xFF, 0xFF, 0xFF},
Packit 534379
                     .state = FPGA_ACCELERATOR_ASSIGNED,
Packit 534379
                     .num_mmio = 0,
Packit 534379
                     .num_interrupts = 0xf,
Packit 534379
                     .fme_object_id = 9,
Packit 534379
                     .port_object_id = 9,
Packit 534379
                     .vendor_id = 0x1234,
Packit 534379
                     .device_id = 0x1234,
Packit 534379
                     .fme_num_errors = 0x1234,
Packit 534379
                     .port_num_errors = 0x1234,
Packit 534379
                     .gbs_guid = "C544CE5C-F630-44E1-8551-59BD87AF432E",
Packit 534379
                     .mdata = ""};
Packit 534379
}
Packit 534379
Packit 534379
Packit 534379
const char *skx_mdata =
Packit 534379
    R"mdata({"version": 1,
Packit 534379
   "afu-image":
Packit 534379
    {"clock-frequency-high": 312,
Packit 534379
     "clock-frequency-low": 156,
Packit 534379
     "power": 50,
Packit 534379
     "interface-uuid": "1a422218-6dba-448e-b302-425cbcde1406",
Packit 534379
     "magic-no": 488605312,
Packit 534379
     "accelerator-clusters":
Packit 534379
      [
Packit 534379
        {
Packit 534379
          "total-contexts": 1,
Packit 534379
          "name": "nlb_400",
Packit 534379
          "accelerator-type-uuid": "d8424dc4-a4a3-c413-f89e-433683f9040b"
Packit 534379
        }
Packit 534379
      ]
Packit 534379
     },
Packit 534379
     "platform-name": "MCP"}"
Packit 534379
)mdata";
Packit 534379
Packit 534379
const char *rc_mdata =
Packit 534379
    R"mdata({"version": 1,
Packit 534379
   "afu-image":
Packit 534379
    {"clock-frequency-high": 312,
Packit 534379
     "clock-frequency-low": 156,
Packit 534379
     "interface-uuid": "89a05379-528e-5b84-b8f2-348aea5d02c0",
Packit 534379
     "magic-no": 488605312,
Packit 534379
     "accelerator-clusters":
Packit 534379
      [
Packit 534379
        {
Packit 534379
          "total-contexts": 1,
Packit 534379
          "name": "nlb3",
Packit 534379
          "accelerator-type-uuid": "d8424dc4-a4a3-c413-f89e-433683f9040b"
Packit 534379
        }
Packit 534379
      ]
Packit 534379
     },
Packit 534379
     "platform-name": "PAC"}"
Packit 534379
)mdata";
Packit 534379
Packit 534379
const char *vc_mdata =
Packit 534379
    R"mdata({"version": 1,
Packit 534379
   "afu-image":
Packit 534379
    {"clock-frequency-high": 312,
Packit 534379
     "clock-frequency-low": 156,
Packit 534379
     "interface-uuid": "cf9b1c50-37c9-45e9-8030-f921b17d2b3a",
Packit 534379
     "magic-no": 488605312,
Packit 534379
     "accelerator-clusters":
Packit 534379
      [
Packit 534379
        {
Packit 534379
          "total-contexts": 1,
Packit 534379
          "name": "nlb3",
Packit 534379
          "accelerator-type-uuid": "9aeffe5f-8457-0612-c000-c9660d824272"
Packit 534379
        }
Packit 534379
      ]
Packit 534379
     },
Packit 534379
     "platform-name": "PAC"}";
Packit 534379
)mdata";
Packit 534379
Packit 534379
static platform_db MOCK_PLATFORMS = {
Packit 534379
    {"skx-p",
Packit 534379
     test_platform{.mock_sysfs = "mock_sys_tmp-1socket-nlb0.tar.gz",
Packit 534379
                   .driver = fpga_driver::linux_intel,
Packit 534379
                   .devices = {test_device{
Packit 534379
                       .fme_guid = "1A422218-6DBA-448E-B302-425CBCDE1406",
Packit 534379
                       .afu_guid = "D8424DC4-A4A3-C413-F89E-433683F9040B",
Packit 534379
                       .segment = 0x0,
Packit 534379
                       .bus = 0x5e,
Packit 534379
                       .device = 0,
Packit 534379
                       .function = 0,
Packit 534379
                       .num_vfs = 0,
Packit 534379
                       .socket_id = 0,
Packit 534379
                       .num_slots = 1,
Packit 534379
                       .bbs_id = 0x06400002fc614bb9,
Packit 534379
                       .bbs_version = {6, 4, 0},
Packit 534379
                       .state = FPGA_ACCELERATOR_UNASSIGNED,
Packit 534379
                       .num_mmio = 0x2,
Packit 534379
                       .num_interrupts = 0,
Packit 534379
                       .fme_object_id = 0xf500000,
Packit 534379
                       .port_object_id = 0xf400000,
Packit 534379
                       .vendor_id = 0x8086,
Packit 534379
                       .device_id = 0xbcc0,
Packit 534379
                       .fme_num_errors = 8,
Packit 534379
                       .port_num_errors = 3,
Packit 534379
                       .gbs_guid = "58656f6e-4650-4741-b747-425376303031",
Packit 534379
                       .mdata = skx_mdata}}}},
Packit 534379
    {"skx-p-1vf",
Packit 534379
     test_platform{.mock_sysfs = "mock_sys_tmp-1socket-nlb0-vf.tar.gz",
Packit 534379
                   .driver = fpga_driver::linux_intel,
Packit 534379
                   .devices = {test_device{
Packit 534379
                       .fme_guid = "1A422218-6DBA-448E-B302-425CBCDE1406",
Packit 534379
                       .afu_guid = "D8424DC4-A4A3-C413-F89E-433683F9040B",
Packit 534379
                       .segment = 0x0,
Packit 534379
                       .bus = 0x5e,
Packit 534379
                       .device = 0,
Packit 534379
                       .function = 0,
Packit 534379
                       .num_vfs = 1,
Packit 534379
                       .socket_id = 0,
Packit 534379
                       .num_slots = 1,
Packit 534379
                       .bbs_id = 0x06400002fc614bb9,
Packit 534379
                       .bbs_version = {6, 4, 0},
Packit 534379
                       .state = FPGA_ACCELERATOR_UNASSIGNED,
Packit 534379
                       .num_mmio = 0x2,
Packit 534379
                       .num_interrupts = 0,
Packit 534379
                       .fme_object_id = 0xf500000,
Packit 534379
                       .port_object_id = 0xf400000,
Packit 534379
                       .vendor_id = 0x8086,
Packit 534379
                       .device_id = 0xbcc0,
Packit 534379
                       .fme_num_errors = 8,
Packit 534379
                       .port_num_errors = 3,
Packit 534379
                       .gbs_guid = "58656f6e-4650-4741-b747-425376303031",
Packit 534379
                       .mdata = skx_mdata}}}},
Packit 534379
    {"dcp-rc",
Packit 534379
     test_platform{.mock_sysfs = "mock_sys_tmp-dcp-rc-nlb3.tar.gz",
Packit 534379
                   .driver = fpga_driver::linux_intel,
Packit 534379
                   .devices = {test_device{
Packit 534379
                       .fme_guid = "F64E598B-EA11-517F-A28E-7BC65D885104",
Packit 534379
                       .afu_guid = "D8424DC4-A4A3-C413-F89E-433683F9040B",
Packit 534379
                       .segment = 0x0,
Packit 534379
                       .bus = 0x05,
Packit 534379
                       .device = 0,
Packit 534379
                       .function = 0,
Packit 534379
                       .num_vfs = 0,
Packit 534379
                       .socket_id = 0,
Packit 534379
                       .num_slots = 1,
Packit 534379
                       .bbs_id = 0x0113000200000177,
Packit 534379
                       .bbs_version = {1, 1, 3},
Packit 534379
                       .state = FPGA_ACCELERATOR_UNASSIGNED,
Packit 534379
                       .num_mmio = 0x2,
Packit 534379
                       .num_interrupts = 0,
Packit 534379
                       .fme_object_id = 0xf500000,
Packit 534379
                       .port_object_id = 0xf400000,
Packit 534379
                       .vendor_id = 0x8086,
Packit 534379
                       .device_id = 0x09c4,
Packit 534379
                       .fme_num_errors = 8,
Packit 534379
                       .port_num_errors = 3,
Packit 534379
                       .gbs_guid = "58656f6e-4650-4741-b747-425376303031",
Packit 534379
                       .mdata = rc_mdata}}}},
Packit 534379
   {"skx-p-dfl0",
Packit 534379
     test_platform{.mock_sysfs = "mock_sys_tmp-dfl0-nlb0.tar.gz",
Packit 534379
                   .driver = fpga_driver::linux_dfl0,
Packit 534379
                   .devices = {test_device{
Packit 534379
                       .fme_guid = "1A422218-6DBA-448E-B302-425CBCDE1406",
Packit 534379
                       .afu_guid = "D8424DC4-A4A3-C413-F89E-433683F9040B",
Packit 534379
                       .segment = 0x0,
Packit 534379
                       .bus = 0x5e,
Packit 534379
                       .device = 0,
Packit 534379
                       .function = 0,
Packit 534379
                       .num_vfs = 0,
Packit 534379
                       .socket_id = 0,
Packit 534379
                       .num_slots = 1,
Packit 534379
                       .bbs_id = 0x06400002fc614bb9,
Packit 534379
                       .bbs_version = {6, 4, 0},
Packit 534379
                       .state = FPGA_ACCELERATOR_UNASSIGNED,
Packit 534379
                       .num_mmio = 0x2,
Packit 534379
                       .num_interrupts = 0,
Packit 534379
                       .fme_object_id = 0xf500000,
Packit 534379
                       .port_object_id = 0xf400000,
Packit 534379
                       .vendor_id = 0x8086,
Packit 534379
                       .device_id = 0xbcc0,
Packit 534379
                       .fme_num_errors = 8,
Packit 534379
                       .port_num_errors = 3,
Packit 534379
                       .gbs_guid = "58656f6e-4650-4741-b747-425376303031",
Packit 534379
                       .mdata = skx_mdata}}}},
Packit 534379
   {"skx-p-dfl0_patchset2",
Packit 534379
     test_platform{.mock_sysfs = "mock_sys_tmp-dfl0_patchset2-nlb0.tar.gz",
Packit 534379
                .driver = fpga_driver::linux_dfl0,
Packit 534379
                .devices = {test_device{
Packit 534379
                       .fme_guid = "1A422218-6DBA-448E-B302-425CBCDE1406",
Packit 534379
                       .afu_guid = "D8424DC4-A4A3-C413-F89E-433683F9040B",
Packit 534379
                       .segment = 0x0,
Packit 534379
                       .bus = 0x5e,
Packit 534379
                       .device = 0,
Packit 534379
                       .function = 0,
Packit 534379
                       .num_vfs = 0,
Packit 534379
                       .socket_id = 0,
Packit 534379
                       .num_slots = 1,
Packit 534379
                       .bbs_id = 0x06400002fc614bb9,
Packit 534379
                       .bbs_version = {6, 4, 0},
Packit 534379
                       .state = FPGA_ACCELERATOR_UNASSIGNED,
Packit 534379
                       .num_mmio = 0x2,
Packit 534379
                       .num_interrupts = 0,
Packit 534379
                       .fme_object_id = 0xf500000,
Packit 534379
                       .port_object_id = 0xf400000,
Packit 534379
                       .vendor_id = 0x8086,
Packit 534379
                       .device_id = 0xbcc0,
Packit 534379
                       .fme_num_errors = 8,
Packit 534379
                       .port_num_errors = 3,
Packit 534379
                       .gbs_guid = "58656f6e-4650-4741-b747-425376303031",
Packit 534379
                       .mdata = skx_mdata}}}},
Packit 534379
   {"dcp-rc-dfl0_patchset2",
Packit 534379
     test_platform{.mock_sysfs = "mock_sys_tmp-dcp-rc-dfl0_patchset2-nlb0.tar.gz",
Packit 534379
                .driver = fpga_driver::linux_dfl0,
Packit 534379
                .devices = {test_device{
Packit 534379
                       .fme_guid = "F64E598B-EA11-517F-A28E-7BC65D885104",
Packit 534379
                       .afu_guid = "D8424DC4-A4A3-C413-F89E-433683F9040B",
Packit 534379
                       .segment = 0x0,
Packit 534379
                       .bus = 0x05,
Packit 534379
                       .device = 0,
Packit 534379
                       .function = 0,
Packit 534379
                       .num_vfs = 0,
Packit 534379
                       .socket_id = 0,
Packit 534379
                       .num_slots = 1,
Packit 534379
                       .bbs_id = 0x0113000200000177,
Packit 534379
                       .bbs_version = {1, 1, 3},
Packit 534379
                       .state = FPGA_ACCELERATOR_UNASSIGNED,
Packit 534379
                       .num_mmio = 0x2,
Packit 534379
                       .num_interrupts = 0,
Packit 534379
                       .fme_object_id = 0xf500000,
Packit 534379
                       .port_object_id = 0xf400000,
Packit 534379
                       .vendor_id = 0x8086,
Packit 534379
                       .device_id = 0x09c4,
Packit 534379
                       .fme_num_errors = 8,
Packit 534379
                       .port_num_errors = 3,
Packit 534379
                       .gbs_guid = "58656f6e-4650-4741-b747-425376303031",
Packit 534379
                       .mdata = rc_mdata}}}},
Packit 534379
   {"dcp-vc",
Packit 534379
     test_platform{.mock_sysfs = "mock_sys_tmp-dcp-vc.tar.gz",
Packit 534379
            	   .driver = fpga_driver::linux_intel,
Packit 534379
                   .devices = {test_device{
Packit 534379
                       .fme_guid = "CF9B1C50-37C9-45E9-8030-F921B17D2B3A",
Packit 534379
                       .afu_guid = "9AEFFE5F-8457-0612-C000-C9660D824272",
Packit 534379
                       .segment = 0x0,
Packit 534379
                       .bus = 0x05,
Packit 534379
                       .device = 0,
Packit 534379
                       .function = 0,
Packit 534379
                       .num_vfs = 0,
Packit 534379
                       .socket_id = 0,
Packit 534379
                       .num_slots = 1,
Packit 534379
                       .bbs_id = 0x222000200567bd1,
Packit 534379
                       .bbs_version = {2, 2, 2},
Packit 534379
                       .state = FPGA_ACCELERATOR_UNASSIGNED,
Packit 534379
                       .num_mmio = 0x2,
Packit 534379
                       .num_interrupts = 0,
Packit 534379
                       .fme_object_id = 0xf500000,
Packit 534379
                       .port_object_id = 0xf400000,
Packit 534379
                       .vendor_id = 0x8086,
Packit 534379
                       .device_id = 0x0b30,
Packit 534379
                       .fme_num_errors = 9,
Packit 534379
                       .port_num_errors = 3,
Packit 534379
                       .gbs_guid = "58656f6e-4650-4741-b747-425376303031",
Packit 534379
                       .mdata = vc_mdata}}}},
Packit 534379
   {"dcp-vc-dfl0",
Packit 534379
     test_platform{.mock_sysfs = "mock_sys_tmp-dcp-vc-dfl0_patchset2-nlb0.tar.gz",
Packit 534379
                   .driver = fpga_driver::linux_dfl0,
Packit 534379
                   .devices = {test_device{
Packit 534379
                       .fme_guid = "CF9B1C50-37C9-45E9-8030-F921B17D2B3A",
Packit 534379
                       .afu_guid = "9AEFFE5F-8457-0612-C000-C9660D824272",
Packit 534379
                       .segment = 0x0,
Packit 534379
                       .bus = 0x05,
Packit 534379
                       .device = 0,
Packit 534379
                       .function = 0,
Packit 534379
                       .num_vfs = 0,
Packit 534379
                       .socket_id = 0,
Packit 534379
                       .num_slots = 1,
Packit 534379
                       .bbs_id = 0x222000200567bd1,
Packit 534379
                       .bbs_version = {2, 2, 2},
Packit 534379
                       .state = FPGA_ACCELERATOR_UNASSIGNED,
Packit 534379
                       .num_mmio = 0x2,
Packit 534379
                       .num_interrupts = 0,
Packit 534379
                       .fme_object_id = 0xf500000,
Packit 534379
                       .port_object_id = 0xf400000,
Packit 534379
                       .vendor_id = 0x8086,
Packit 534379
                       .device_id = 0x0b30,
Packit 534379
                       .fme_num_errors = 9,
Packit 534379
                       .port_num_errors = 3,
Packit 534379
                       .gbs_guid = "58656f6e-4650-4741-b747-425376303031",
Packit 534379
                       .mdata = vc_mdata}}}}
Packit 534379
};
Packit 534379
Packit 534379
Packit 534379
test_platform test_platform::get(const std::string &key) {
Packit 534379
  return fpga_db::instance()->get(key);
Packit 534379
}
Packit 534379
Packit 534379
bool test_platform::exists(const std::string &key) {
Packit 534379
  return fpga_db::instance()->exists(key);
Packit 534379
}
Packit 534379
Packit 534379
std::vector<std::string> test_platform::keys(bool sorted) {
Packit 534379
  return fpga_db::instance()->keys(sorted);
Packit 534379
}
Packit 534379
Packit 534379
std::vector<std::string> test_platform::platforms(
Packit 534379
    std::initializer_list<std::string> names, fpga_driver drv) {
Packit 534379
  std::vector<std::string> keys(names);
Packit 534379
  if (keys.empty()) {
Packit 534379
    keys = fpga_db::instance()->keys();
Packit 534379
  }
Packit 534379
  // from the list of platform names requested, remove the ones not found in
Packit 534379
  // the platform db
Packit 534379
  keys.erase(
Packit 534379
    std::remove_if(keys.begin(), keys.end(), [drv](const std::string &n) {
Packit 534379
      auto db = fpga_db::instance();
Packit 534379
      return !db->exists(n) || (drv != fpga_driver::linux_any
Packit 534379
                                && drv != db->get(n).driver)
Packit 534379
                            || db->get(n).devices.empty();
Packit 534379
  }), keys.end());
Packit 534379
  return keys;
Packit 534379
}
Packit 534379
Packit 534379
std::vector<std::string> test_platform::mock_platforms(
Packit 534379
    std::initializer_list<std::string> names, fpga_driver drv) {
Packit 534379
  std::vector<std::string> keys(names);
Packit 534379
  if (keys.empty()) {
Packit 534379
    keys = fpga_db::instance()->keys();
Packit 534379
  }
Packit 534379
  std::vector<std::string> want;
Packit 534379
  std::copy_if(keys.begin(), keys.end(), std::back_inserter(want),
Packit 534379
               [drv](const std::string &k) {
Packit 534379
                 auto db = fpga_db::instance();
Packit 534379
                 return db->exists(k) && (drv == fpga_driver::linux_any ||
Packit 534379
                                          db->get(k).driver == drv),
Packit 534379
                        db->get(k).mock_sysfs != nullptr;
Packit 534379
               });
Packit 534379
  return want;
Packit 534379
}
Packit 534379
Packit 534379
std::vector<std::string> test_platform::hw_platforms(
Packit 534379
    std::initializer_list<std::string> names, fpga_driver drv) {
Packit 534379
  std::vector<std::string> keys(names);
Packit 534379
  if (keys.empty()) {
Packit 534379
    keys = fpga_db::instance()->keys();
Packit 534379
  }
Packit 534379
  std::vector<std::string> want;
Packit 534379
  std::copy_if(keys.begin(), keys.end(), std::back_inserter(want),
Packit 534379
               [drv](const std::string &k) {
Packit 534379
                 auto db = fpga_db::instance();
Packit 534379
                 return db->exists(k) && (drv == fpga_driver::linux_any ||
Packit 534379
                                          db->get(k).driver == drv) &&
Packit 534379
                        !db->get(k).devices.empty() &&
Packit 534379
                        db->get(k).mock_sysfs == nullptr;
Packit 534379
               });
Packit 534379
  return want;
Packit 534379
}
Packit 534379
Packit 534379
const std::string PCI_DEVICES = "/sys/bus/pci/devices";
Packit 534379
Packit 534379
typedef std::pair<uint16_t, uint64_t> ven_dev_id;
Packit 534379
typedef std::tuple<uint16_t, uint64_t, fpga_driver> platform_cfg;
Packit 534379
std::map<ven_dev_id, std::vector<std::string>> known_devices = {
Packit 534379
  { { 0x8086, 0xbcc0}, std::vector<std::string>() },
Packit 534379
  { { 0x8086, 0xbcc1}, std::vector<std::string>() },
Packit 534379
  { { 0x8086, 0x09c4}, std::vector<std::string>() },
Packit 534379
  { { 0x8086, 0x09c5}, std::vector<std::string>() },
Packit 534379
  { { 0x8086, 0x0b30}, std::vector<std::string>() },
Packit 534379
  { { 0x8086, 0x0b31}, std::vector<std::string>() },
Packit 534379
};
Packit 534379
Packit 534379
static std::vector<ven_dev_id> supported_devices() {
Packit 534379
  std::vector<ven_dev_id> devs;
Packit 534379
  for (auto kv : known_devices) {
Packit 534379
    devs.push_back(kv.first);
Packit 534379
  }
Packit 534379
  return devs;
Packit 534379
}
Packit 534379
Packit 534379
static std::string read_file(const std::string &path) {
Packit 534379
  std::ifstream df;
Packit 534379
  struct stat st;
Packit 534379
  std::string value_string;
Packit 534379
Packit 534379
  if (stat(path.c_str(), &st)) {
Packit 534379
    std::cerr << std::string("WARNING: stat:") + path <<  ":" << strerror(errno) << "\n";
Packit 534379
    return "";
Packit 534379
  }
Packit 534379
Packit 534379
  df.open(path);
Packit 534379
  if (!df.is_open()) {
Packit 534379
    std::cerr << std::string("WARNING: could not open file ") + path << "\n";
Packit 534379
    return "";
Packit 534379
  }
Packit 534379
  df >> value_string;
Packit 534379
  return value_string;
Packit 534379
}
Packit 534379
template<typename T>
Packit 534379
static T parse_file_int(const std::string &path) {
Packit 534379
  std::string value_string = read_file(path);
Packit 534379
Packit 534379
  if (value_string.empty())
Packit 534379
    return 0;
Packit 534379
Packit 534379
  T value;
Packit 534379
Packit 534379
  try {
Packit 534379
    value = std::stol(value_string, nullptr, 0);
Packit 534379
  }
Packit 534379
  catch (std::invalid_argument& e) {
Packit 534379
    std::cerr << "WARNING: unable to convert integer from file: " << path << std::endl;
Packit 534379
    return 0;
Packit 534379
  }
Packit 534379
  catch (std::out_of_range& e) {
Packit 534379
    std::cerr << "WARNING: value too large from file: " << path << std::endl;
Packit 534379
    return 0;
Packit 534379
  }
Packit 534379
Packit 534379
  return value;
Packit 534379
}
Packit 534379
Packit 534379
static std::string make_path(int seg, int bus, int dev, int func){
Packit 534379
    std::stringstream num;
Packit 534379
    num << std::setw(2) << std::hex << bus; 
Packit 534379
    std::string b (num.str());
Packit 534379
    num.clear();
Packit 534379
    num.str(std::string());
Packit 534379
Packit 534379
    num << std::setw(4) << std::setfill('0') << seg;
Packit 534379
    std::string s (num.str());
Packit 534379
Packit 534379
    num.clear();
Packit 534379
    num.str(std::string());
Packit 534379
    num << std::setw(2) << std::setfill('0') << dev;
Packit 534379
    std::string d (num.str());
Packit 534379
Packit 534379
    std::string device_string = s + ":" + b + ":" + d + "." + std::to_string(func);
Packit 534379
    return device_string;
Packit 534379
}
Packit 534379
Packit 534379
static std::string glob_first_path(const std::string path) {
Packit 534379
  glob_t glob_buf;
Packit 534379
  glob_buf.gl_pathc = 0;
Packit 534379
  glob_buf.gl_pathv = NULL;
Packit 534379
  int globres = glob(path.c_str(), 0, NULL, &glob_buf);
Packit 534379
  std::string found_path;
Packit 534379
Packit 534379
  if (!globres){
Packit 534379
    if (glob_buf.gl_pathc > 1) {
Packit 534379
        std::cerr << "Ambiguous object key - using first one" << std::endl;
Packit 534379
    }
Packit 534379
    found_path = std::string(glob_buf.gl_pathv[0]);
Packit 534379
  }
Packit 534379
  else {
Packit 534379
    switch (globres) {
Packit 534379
    case GLOB_NOSPACE:
Packit 534379
        std::cerr << "FPGA No Memory found." << std::endl;
Packit 534379
        break;
Packit 534379
    case GLOB_NOMATCH:
Packit 534379
        std::cerr << "FPGA Not found." << std::endl;
Packit 534379
        break;
Packit 534379
    }
Packit 534379
  }
Packit 534379
Packit 534379
  if (glob_buf.gl_pathc && glob_buf.gl_pathv) {
Packit 534379
    globfree(&glob_buf);
Packit 534379
  }
Packit 534379
Packit 534379
  return found_path;
Packit 534379
}
Packit 534379
Packit 534379
static std::string format_uuid(const std::string &uuid) {
Packit 534379
  std::string formatted_uuid = uuid;
Packit 534379
  formatted_uuid.insert(8, "-");
Packit 534379
  formatted_uuid.insert(13, "-");
Packit 534379
  formatted_uuid.insert(18, "-");
Packit 534379
  formatted_uuid.insert(23, "-");
Packit 534379
  std::transform(formatted_uuid.begin(), formatted_uuid.end(), formatted_uuid.begin(), ::toupper);
Packit 534379
  return formatted_uuid;
Packit 534379
}
Packit 534379
Packit 534379
template<typename T>
Packit 534379
static  T read_attribute(const std::string &pci_dir, const std::string &attr) {
Packit 534379
  std::string attr_path = pci_dir + "/" + attr;
Packit 534379
  struct stat st;
Packit 534379
Packit 534379
Packit 534379
  if (stat(attr_path.c_str(), &st)) {
Packit 534379
    std::cerr << std::string("WARNING: stat:") + attr_path <<  ":" << strerror(errno) << "\n";
Packit 534379
    return 0;
Packit 534379
  }
Packit 534379
   return parse_file_int<T>(attr_path);
Packit 534379
}
Packit 534379
Packit 534379
static uint16_t read_socket_id(const std::string devices) {
Packit 534379
  std::string glob_path = PCI_DEVICES + "/" + devices + "/fpga*/*/*fme.*/socket_id";
Packit 534379
  std::string socket_path = glob_first_path(glob_path);
Packit 534379
  return parse_file_int<uint16_t>(socket_path);
Packit 534379
}
Packit 534379
Packit 534379
static uint16_t read_device_id(const std::string &pci_dir) {
Packit 534379
  std::string device_path = pci_dir + "/device";
Packit 534379
  return parse_file_int<uint16_t>(device_path);
Packit 534379
}
Packit 534379
Packit 534379
static uint16_t read_vendor_id(const std::string &pci_dir) {
Packit 534379
  std::string vendor_path = pci_dir + "/vendor";
Packit 534379
  return parse_file_int<uint16_t>(vendor_path);
Packit 534379
}
Packit 534379
Packit 534379
static uint64_t read_bitstream_id(const std::string &pci_dir) {
Packit 534379
  std::string bitstream_path = pci_dir + "/fpga*/*/*-fme.*/bitstream_id";
Packit 534379
  bitstream_path = glob_first_path(bitstream_path);
Packit 534379
  return parse_file_int<uint64_t>(bitstream_path);
Packit 534379
}
Packit 534379
Packit 534379
static std::string read_afu_id(const std::string &pci_dir) {
Packit 534379
  std::string afu_path = pci_dir + "/fpga*/*/*-port.*/afu_id";
Packit 534379
Packit 534379
  afu_path = glob_first_path(afu_path);
Packit 534379
  return format_uuid(read_file(afu_path));
Packit 534379
}
Packit 534379
Packit 534379
static std::string read_pr_interface_id(const std::string &pci_dir) {
Packit 534379
  std::string pr_interface_path = pci_dir + "/fpga/intel-fpga-dev.*/intel-fpga-fme.*/pr/interface_id";
Packit 534379
  pr_interface_path = glob_first_path(pr_interface_path);
Packit 534379
Packit 534379
  if (pr_interface_path.empty()) {
Packit 534379
    pr_interface_path = pci_dir + "/fpga_region/region*/dfl-fme.*/dfl-fme-region.*/fpga_region/region*/compat_id";
Packit 534379
    pr_interface_path = glob_first_path(pr_interface_path);
Packit 534379
  }
Packit 534379
Packit 534379
  return format_uuid(read_file(pr_interface_path));
Packit 534379
}
Packit 534379
Packit 534379
int filter_fpga(const struct dirent *ent) {
Packit 534379
  std::string ename(ent->d_name);
Packit 534379
  if (ename[0] == '.') {
Packit 534379
    return 0;
Packit 534379
  }
Packit 534379
  std::string pci_path = PCI_DEVICES + "/" + ename;
Packit 534379
  auto did = read_device_id(pci_path);
Packit 534379
  auto vid = read_vendor_id(pci_path);
Packit 534379
Packit 534379
  auto devices = supported_devices();
Packit 534379
  std::vector<ven_dev_id>::const_iterator it = std::find(devices.begin(), devices.end(), ven_dev_id(vid, did));
Packit 534379
  if (it == devices.end()) {
Packit 534379
    return 0;
Packit 534379
  }
Packit 534379
  known_devices[ven_dev_id(vid, did)].push_back(pci_path);
Packit 534379
  return 1;
Packit 534379
}
Packit 534379
Packit 534379
std::vector<std::string> find_supported_devices() {
Packit 534379
  struct dirent **dirs;
Packit 534379
  int n = scandir(PCI_DEVICES.c_str(), &dirs, filter_fpga, alphasort);
Packit 534379
  if (n == -1) {
Packit 534379
    std::string msg = "error scanning pci devices: " + std::string(strerror(errno));
Packit 534379
    throw std::runtime_error(msg);
Packit 534379
  }
Packit 534379
  std::vector<std::string> entries;
Packit 534379
  while (n--) {
Packit 534379
    entries.push_back(std::string(dirs[n]->d_name));
Packit 534379
    free(dirs[n]);
Packit 534379
  }
Packit 534379
  free(dirs);
Packit 534379
  return entries;
Packit 534379
}
Packit 534379
Packit 534379
fpga_db *fpga_db::instance_ = nullptr;
Packit 534379
Packit 534379
fpga_db::fpga_db()
Packit 534379
{
Packit 534379
Packit 534379
}
Packit 534379
Packit 534379
fpga_db *fpga_db::instance() {
Packit 534379
  if (fpga_db::instance_ == nullptr) {
Packit 534379
    fpga_db::instance_ = new fpga_db();
Packit 534379
    fpga_db::instance_->discover_hw();
Packit 534379
  }
Packit 534379
  return fpga_db::instance_;
Packit 534379
}
Packit 534379
Packit 534379
static std::map<platform_cfg, std::string> platform_names = {
Packit 534379
  {  platform_cfg(0x8086, 0xbcc0, fpga_driver::linux_intel), "skx-p" },
Packit 534379
  {  platform_cfg(0x8086, 0xbcc1, fpga_driver::linux_intel), "skx-p-v" },
Packit 534379
  {  platform_cfg(0x8086, 0x09c4, fpga_driver::linux_intel), "dcp-rc" },
Packit 534379
  {  platform_cfg(0x8086, 0x09c5, fpga_driver::linux_intel), "dcp-rc-v" },
Packit 534379
  {  platform_cfg(0x8086, 0xbcc0, fpga_driver::linux_dfl0),  "skx-p-dfl0_patchset2" },
Packit 534379
  {  platform_cfg(0x8086, 0x09c4, fpga_driver::linux_dfl0),  "dcp-rc-dfl0_patchset2" },
Packit 534379
  {  platform_cfg(0x8086, 0xbcc0, fpga_driver::linux_dfl0),  "skx-p-dfl0" },
Packit 534379
  {  platform_cfg(0x8086, 0x0b30, fpga_driver::linux_intel), "dcp-vc" },
Packit 534379
  {  platform_cfg(0x8086, 0x0b31, fpga_driver::linux_intel), "dcp-vc-v" },
Packit 534379
  {  platform_cfg(0x8086, 0x0b30, fpga_driver::linux_dfl0),  "dcp-vc-dfl0" },
Packit 534379
  
Packit 534379
};
Packit 534379
Packit 534379
const char *PCI_DEV_PATTERN = "([0-9a-fA-F]{4}):([0-9a-fA-F]{2}):([0-9]{2})\\.([0-9])";
Packit 534379
Packit 534379
test_device make_device(uint16_t ven_id, uint16_t dev_id, const std::string &platform, const std::string &pci_path) {
Packit 534379
  test_device dev = MOCK_PLATFORMS[platform].devices[0];
Packit 534379
Packit 534379
  auto r = regex<>::create(PCI_DEV_PATTERN);
Packit 534379
  auto m = r->match(pci_path);
Packit 534379
  if (m) {
Packit 534379
    dev.segment = std::stoi(m->group(1), nullptr, 16);
Packit 534379
    dev.bus = std::stoi(m->group(2), nullptr, 16);
Packit 534379
    dev.device = std::stoi(m->group(3), nullptr, 10);
Packit 534379
    dev.function = std::stoi(m->group(4), nullptr, 10);
Packit 534379
    dev.num_vfs = read_attribute<uint8_t>(pci_path, "sriov_numvfs");
Packit 534379
    dev.vendor_id = ven_id;
Packit 534379
    dev.device_id = dev_id;
Packit 534379
Packit 534379
    std::string device_string = make_path(dev.segment, dev.bus, dev.device, dev.function);
Packit 534379
    dev.socket_id = read_socket_id(device_string);
Packit 534379
    uint64_t bitstream_id = read_bitstream_id(pci_path);
Packit 534379
    dev.bbs_id = bitstream_id;
Packit 534379
    dev.bbs_version = {(uint8_t)FPGA_BBS_VER_MAJOR(bitstream_id),
Packit 534379
                         (uint8_t)FPGA_BBS_VER_MINOR(bitstream_id),
Packit 534379
                         (uint16_t)FPGA_BBS_VER_PATCH(bitstream_id)};
Packit 534379
    strcpy(dev.fme_guid, read_pr_interface_id(pci_path).c_str());
Packit 534379
    strcpy(dev.afu_guid, read_afu_id(pci_path).c_str());
Packit 534379
  } else {
Packit 534379
    std::cerr << "error matching pci dev pattern (" << pci_path << ")\n";
Packit 534379
  }
Packit 534379
  return dev;
Packit 534379
}
Packit 534379
Packit 534379
/**
Packit 534379
 * @brief read the 'driver' symlink to determine if the driver is dfl or intel
Packit 534379
 *
Packit 534379
 * @param path a sysfs path representing a device (under
Packit 534379
 * /sys/bus/pci/<s:b:d:f>)
Packit 534379
 *
Packit 534379
 * @return fpga_driver enumerating indicating what kind of driver is bound to
Packit 534379
 * the device
Packit 534379
 */
Packit 534379
fpga_driver get_driver(const std::string &path)
Packit 534379
{
Packit 534379
  char buffer[PATH_MAX] = { 0 };
Packit 534379
  std::string sysfs_drvpath = path + "/driver";
Packit 534379
  ssize_t lnk_len = readlink(sysfs_drvpath.c_str(), buffer, PATH_MAX);
Packit 534379
  if (!lnk_len) {
Packit 534379
    auto msg = std::string("error readling link: ") + sysfs_drvpath;
Packit 534379
    throw std::runtime_error(msg);
Packit 534379
  }
Packit 534379
  std::string bname = basename(buffer);
Packit 534379
  if (bname == "intel-fpga-pci") {
Packit 534379
    return fpga_driver::linux_intel;
Packit 534379
  }
Packit 534379
  if (bname == "dfl-pci") {
Packit 534379
    return fpga_driver::linux_dfl0;
Packit 534379
  }
Packit 534379
  return fpga_driver::none;
Packit 534379
}
Packit 534379
Packit 534379
std::pair<std::string, test_platform> make_platform(uint16_t ven_id, uint16_t dev_id, const std::vector<std::string> &pci_paths) {
Packit 534379
  test_platform platform;
Packit 534379
  // test_platform data structure only supports one driver (for now)
Packit 534379
  // TODO: assert that all devices represented by pci_patsh are all bound to
Packit 534379
  // the same driver - for now, just use the first path
Packit 534379
  platform.driver = get_driver(pci_paths[0]);
Packit 534379
  // this is discovered hw platform, set mock_sysfs to null
Packit 534379
  platform.mock_sysfs = nullptr;
Packit 534379
  std::string name = platform_names[platform_cfg(ven_id, dev_id, platform.driver)];
Packit 534379
  for (auto p : pci_paths) {
Packit 534379
    platform.devices.push_back(make_device(ven_id, dev_id, name, p));
Packit 534379
  }
Packit 534379
  return std::make_pair(name, platform);
Packit 534379
}
Packit 534379
Packit 534379
void fpga_db::discover_hw() {
Packit 534379
  platform_db db;
Packit 534379
#ifdef OPAE_ENABLE_MOCK
Packit 534379
  std::cout << "Mock is enabled." << std::endl;
Packit 534379
  platforms_ = MOCK_PLATFORMS;
Packit 534379
#else
Packit 534379
  auto sys_pci_devs = find_supported_devices();
Packit 534379
Packit 534379
  for (auto kv : known_devices) {
Packit 534379
    if (!kv.second.empty()) {
Packit 534379
      ven_dev_id id = kv.first;
Packit 534379
      platforms_.insert(make_platform(id.first, id.second, kv.second));
Packit 534379
    }
Packit 534379
  }
Packit 534379
#endif // OPAE_ENABLE_MOCK
Packit 534379
}
Packit 534379
Packit 534379
std::vector<std::string> fpga_db::keys(bool sorted) {
Packit 534379
  std::vector<std::string> keys(platforms_.size());
Packit 534379
  std::transform(
Packit 534379
      platforms_.begin(), platforms_.end(), keys.begin(),
Packit 534379
      [](const std::pair<std::string, test_platform> &it) { return it.first; });
Packit 534379
  if (sorted) {
Packit 534379
    std::sort(keys.begin(), keys.end());
Packit 534379
  }
Packit 534379
Packit 534379
  return keys;
Packit 534379
}
Packit 534379
Packit 534379
test_platform fpga_db::get(const std::string &key) {
Packit 534379
  return platforms_[key];
Packit 534379
}
Packit 534379
Packit 534379
bool fpga_db::exists(const std::string &key) {
Packit 534379
  return platforms_.find(key) != platforms_.end();
Packit 534379
}
Packit 534379
Packit 534379
}  // end of namespace testing
Packit 534379
}  // end of namespace opae