Add a PECI PCIe daemon
This daemon is responsible for collecting PCIe information for
the system over PECI and sharing it with other components,
such as Redfish.
Change-Id: I3332cb2584a6f496a0f2162536b24fb20380ad1d
Signed-off-by: Jason M. Bills <jason.m.bills@intel.com>
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..ce06cfd
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,114 @@
+---
+Language: Cpp
+# BasedOnStyle: LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: Yes
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+ AfterCaseLabel: true
+ AfterClass: true
+ AfterControlStatement: true
+ AfterEnum: true
+ AfterFunction: true
+ AfterNamespace: true
+ AfterObjCDeclaration: true
+ AfterStruct: true
+ AfterUnion: true
+ AfterExternBlock: true
+ BeforeCatch: true
+ BeforeElse: true
+ IndentBraces: false
+ SplitEmptyFunction: false
+ SplitEmptyRecord: false
+ SplitEmptyNamespace: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: AfterColon
+BreakInheritanceList: AfterColon
+BreakStringLiterals: true
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+PointerAlignment: Left
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IncludeBlocks: Regroup
+IncludeCategories:
+ - Regex: '^[<"](gtest|gmock)'
+ Priority: 7
+ - Regex: '^"config.h"'
+ Priority: -1
+ - Regex: '^".*\.h"'
+ Priority: 1
+ - Regex: '^".*\.hpp"'
+ Priority: 2
+ - Regex: '^<.*\.h>'
+ Priority: 3
+ - Regex: '^<.*\.hpp>'
+ Priority: 4
+ - Regex: '^<.*'
+ Priority: 5
+ - Regex: '.*'
+ Priority: 6
+IndentCaseLabels: true
+IndentWidth: 4
+IndentWrappedFunctionNames: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+ReflowComments: true
+SortIncludes: true
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Cpp11
+TabWidth: 4
+UseTab: Never
+...
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..4397728
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,34 @@
+cmake_minimum_required (VERSION 3.6)
+project (peci-pcie CXX)
+set (CMAKE_CXX_STANDARD 17)
+set (CMAKE_CXX_STANDARD_REQUIRED ON)
+
+add_executable (peci-pcie src/peci_pcie.cpp)
+
+target_include_directories (peci-pcie PRIVATE ${CMAKE_SOURCE_DIR})
+
+target_link_libraries (peci-pcie peci sdbusplus -lsystemd)
+
+include_directories (${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+install (TARGETS peci-pcie
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib/static)
+
+find_package (Boost 1.66 REQUIRED)
+include_directories (${BOOST_SRC_DIR})
+
+add_definitions (-DBOOST_ERROR_CODE_HEADER_ONLY)
+add_definitions (-DBOOST_SYSTEM_NO_DEPRECATED)
+add_definitions (-DBOOST_ALL_NO_LIB)
+add_definitions (-DBOOST_NO_RTTI)
+add_definitions (-DBOOST_NO_TYPEID)
+add_definitions (-DBOOST_ASIO_DISABLE_THREADS)
+
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
+set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti")
+
+set (SERVICE_FILES
+ ${PROJECT_SOURCE_DIR}/service_files/xyz.openbmc_project.PCIe.service)
+install (FILES ${SERVICE_FILES} DESTINATION /lib/systemd/system/)
diff --git a/include/pciDeviceClass.hpp b/include/pciDeviceClass.hpp
new file mode 100644
index 0000000..6a6895c
--- /dev/null
+++ b/include/pciDeviceClass.hpp
@@ -0,0 +1,45 @@
+/*
+// Copyright (c) 2019 intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#pragma once
+#include <boost/container/flat_map.hpp>
+
+static constexpr char const* coprocessorSubClass = "Coprocessor";
+static constexpr char const* otherClass = "Other";
+
+static boost::container::flat_map<int, std::string> pciDeviceClasses{
+ {0x00, "UnclassifiedDevice"},
+ {0x01, "MassStorageController"},
+ {0x02, "NetworkController"},
+ {0x03, "DisplayController"},
+ {0x04, "MultimediaController"},
+ {0x05, "MemoryController"},
+ {0x06, "Bridge"},
+ {0x07, "CommunicationController"},
+ {0x08, "GenericSystemPeripheral"},
+ {0x09, "InputDeviceController"},
+ {0x0a, "DockingStation"},
+ {0x0b, "Processor"},
+ {0x0c, "SerialBusController"},
+ {0x0d, "WirelessController"},
+ {0x0e, "IntelligentController"},
+ {0x0f, "SatelliteCommunicationsController"},
+ {0x10, "EncryptionController"},
+ {0x11, "SignalProcessingController"},
+ {0x12, "ProcessingAccelerators"},
+ {0x13, "NonEssentialInstrumentation"},
+ {0xff, "UnassignedClass"},
+};
diff --git a/include/pciVendors.hpp b/include/pciVendors.hpp
new file mode 100644
index 0000000..fb6c139
--- /dev/null
+++ b/include/pciVendors.hpp
@@ -0,0 +1,846 @@
+/*
+// Copyright (c) 2019 intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#pragma once
+#include <boost/container/flat_map.hpp>
+
+static constexpr char const* otherVendor = "Other";
+
+// This list of Vendors is extracted from the PCI-SIG member-companies page
+// ('https://pcisig.com/membership/member-companies') using
+// GetPCI-SIGVendorIDMap.py
+static boost::container::flat_map<int, std::string> pciVendors{
+ {0x1E4A, "2CRSI SA"},
+ {0x1DA0, "3M Company"},
+ {0x38EF, "4Links Limited"},
+ {0x1872, "A & D Company, Ltd"},
+ {0x160D, "AAEON Electronics, Inc."},
+ {0x1D28, "Aava Mobile Oy"},
+ {0x1D92, "Abaco Systems Inc."},
+ {0x13DE, "ABB AB"},
+ {0x1C85, "ABLIC Inc."},
+ {0xAC1A, "Acacia Communications Inc"},
+ {0x14D6, "Accusys Storage LTD."},
+ {0x18E4, "Acer Inc."},
+ {0x1C94, "Aces Electronics Co., Ltd."},
+ {0x1B59, "Achronix Semiconductor"},
+ {0x1528, "ACKSYS"},
+ {0x1DE8, "Acqiris SA"},
+ {0x1C2A, "Acromag inc"},
+ {0x1DE2, "Action Star Technology Co., Ltd."},
+ {0x4153, "Active Silicon, Ltd."},
+ {0x1CC1, "ADATA Technology Co., Ltd."},
+ {0x15B8, "ADDI-DATA Gmbh"},
+ {0x144A, "Adlink Technology, Inc."},
+ {0x1CDA, "ADTEC Corporation"},
+ {0x1022, "Advanced Micro Devices"},
+ {0x130F, "Advanet, Inc."},
+ {0x13FE, "Advantech Co., Ltd."},
+ {0x1850, "Advantest Corporation"},
+ {0x1D7C, "Aerotech Inc"},
+ {0x1CF6, "Aetina Corporation"},
+ {0x1DC4, "Agylstor, Inc."},
+ {0x193F, "AHA Products Group of Comtech EF Data Corp."},
+ {0x1B76, "AIC Inc."},
+ {0x1447, "AIM GmbH"},
+ {0x4149, "AIMOTIVE Kft."},
+ {0x1D36, "Airbus Defence and Space GmbH"},
+ {0x1ACD, "Airbus DS Electronics and Border Security GmbH"},
+ {0xF1D0, "AJA Video"},
+ {0x1CF0, "Akitio"},
+ {0x1096, "Alacron"},
+ {0x1096, "Alacron, Inc"},
+ {0x1C0B, "Alazar Technologies, Inc."},
+ {0x1DC2, "Alco Digital Devices Limited"},
+ {0x1DED, "Alibaba (China) Co., Ltd."},
+ {0x1B49, "ALLDIS Computersystem GmbH"},
+ {0x1259, "Allied Telesis Inc."},
+ {0x1D04, "Allied Vision Technologies"},
+ {0x194F, "Allion Labs, Inc."},
+ {0x1D67, "Alltop Technology Co., Ltd"},
+ {0x4144, "Alpha Data Parallel Systems, Ltd."},
+ {0xAD00, "Alta Data Technologies"},
+ {0x1D0F, "Amazon"},
+ {0x101E, "American Megatrends Inc."},
+ {0x1DEF, "Ampere Computing, LLC"},
+ {0x18F8, "Amphenol Corp."},
+ {0x1BFB, "Analog Bits, Inc"},
+ {0x11D4, "Analog Devices Inc."},
+ {0x12D6, "Analogic Corp"},
+ {0x1B12, "Analogix Semiconductor"},
+ {0x12DB, "Annapolis Micro Systems, Inc."},
+ {0x1C36, "Annapurna Labs"},
+ {0x1852, "Anritsu Corporation"},
+ {0x19EC, "ANSYS, Inc."},
+ {0x1D6B, "AO Kraftway corporation PLC"},
+ {0x1BCD, "Apacer Technology Inc."},
+ {0x106B, "Apple Computer"},
+ {0x1D6A, "Aquantia Corp"},
+ {0x13E6, "ARGOSY RESEARCH INC."},
+ {0x1E28, "Aricent INC"},
+ {0x1AA1, "Aristocrat Technologies Australia Pty Ltd."},
+ {0x1A83, "ARKUS Inc."},
+ {0x13B5, "ARM Ltd."},
+ {0x1E17, "Arnold & Richter Cine Technik GmbH & Co. Betriebs KG"},
+ {0x1E42, "ART Beijing Science and Technology Development Co., Ltd."},
+ {0x1DB4, "Arteris Inc."},
+ {0x1223, "Artesyn Embedded Technologies"},
+ {0x1792, "Artiza Networks, Inc."},
+ {0x1AC0, "Aselsan Inc."},
+ {0x144F, "Askey Computer Corporation"},
+ {0x1E4D, "Asolid Technology Co., Ltd."},
+ {0x1A03, "ASPEED Technology Inc."},
+ {0x1C18, "Asset InterTech Inc"},
+ {0x1C18, "ASSET InterTech, Inc."},
+ {0x19D7, "Astek Corporation"},
+ {0x11BF, "Astrodesign, Inc."},
+ {0x1BD0, "Astronics Corporation"},
+ {0x1043, "Asustek Computer, Inc."},
+ {0x1D58, "Atech Flash Technology, Inc"},
+ {0x1735, "Aten International Co., Ltd."},
+ {0x1DB2, "ATP Electronics, Inc."},
+ {0x1BDD, "Atrust Computer Corp."},
+ {0x1D8B, "Attala Systems"},
+ {0x175C, "AudioScience Inc."},
+ {0x1D50, "Aurotek Corporation"},
+ {0x1A1F, "Avago Technologies"},
+ {0x1DD7, "AVAL DATA Corporation"},
+ {0x1264, "Aval Nagasaki Corporation"},
+ {0x1461, "AVerMedia Technologies, Inc."},
+ {0x18EF, "Avery Design systems, Inc."},
+ {0x1A15, "Axell Corporation"},
+ {0x1E0C, "Axiomtek Co., Ltd."},
+ {0x1A3B, "AzureWave Technologies Inc."},
+ {0x1D84, "b-plus GmbH"},
+ {0x119D, "B.U.G. MORI SEIKI CO., LTD."},
+ {0x1B9F, "BAE Systems"},
+ {0x1D22, "Baidu"},
+ {0x13CC, "Barco, Inc."},
+ {0x1D1C, "Barefoot Networks, Inc."},
+ {0x1217, "BayHub Technology Inc"},
+ {0x17CE, "BCM Advanced Research"},
+ {0x1C78, "Bechtel Marine Propulsion Corporation"},
+ {0x1C2F, "Beckhoff Automation GmbH & Co. KG"},
+ {0x1E18, "Beijing GuangRunTong Technology Development Co.,Ltd"},
+ {0x9588, "Beijing JCZ Technology Co., Ltd"},
+ {0x1C5F, "Beijing Memblaze Technology Co. Ltd."},
+ {0x1D6F, "Beijing Pinecone Electronics Co., Ltd"},
+ {0x1DCF, "Beijing Sinead Technology Co., Ltd."},
+ {0x9D32, "Beijing Starblaze Technology Co., LTD."},
+ {0x8088, "Beijing Wangxun Technology Co., Ltd."},
+ {0x1799, "Belkin Corporation"},
+ {0x1C75, "Bellwether Electronic Corp."},
+ {0x1B05, "Benchmark Electronics, Inc."},
+ {0x3442, "Bihl + Wiedemann GmbH"},
+ {0x1C6F, "Bios Corporation"},
+ {0x1A11, "BitifEye Digital Test Solutions GmbH"},
+ {0x1E30, "Bitmain Technologies Inc."},
+ {0x192A, "BiTMICRO Networks, Inc."},
+ {0x12BA, "Bittware, Inc."},
+ {0x7248, "BizLink Technology, Inc."},
+ {0x1C05, "Blackberry QNX"},
+ {0x1D74, "BlackLynx, Inc."},
+ {0xBDBD, "Blackmagic Design Pty Ltd"},
+ {0x15E0, "Blue Coat Systems"},
+ {0x16F2, "Bosch Rexroth AG"},
+ {0x1E16, "BOXX Technologies, LLC"},
+ {0x14E4, "Broadcom Limited"},
+ {0x1154, "Buffalo Inc."},
+ {0x1E3D, "Burlywood, Inc"},
+ {0x1BCB, "Bustec Production Ltd."},
+ {0x1E3A, "Cactus Technologies, Limited"},
+ {0x17CD, "Cadence Design Systems"},
+ {0xCABC, "Cambricon Technologies Corporation Limited"},
+ {0xCA3B, "Cambrionix Ltd."},
+ {0x11AC, "Canon, Inc."},
+ {0x197D, "Cap Co., Ltd."},
+ {0x1C96, "Carina System Co., Ltd."},
+ {0x1DD9, "Casa Systems, Inc."},
+ {0x1ACD, "Cassidian"},
+ {0x1D69, "Celeno Communications (Israel) LTD"},
+ {0x18D4, "Celestica"},
+ {0x123C, "Century Systems, Inc."},
+ {0x10DC, "CERN"},
+ {0x0731, "Changsha Jingjia Microelectronics Co., Ltd."},
+ {0x1CEE, "Chant Sincere Co., Ltd."},
+ {0x1E08, "Charon Technologies"},
+ {0x1425, "Chelsio Communications"},
+ {0x1D94, "Chengdu Higon Integrated Circuit Design Co., Ltd."},
+ {0x1E4E, "Chongqing Unisinsight Technology Co.,Ltd."},
+ {0x1A43, "Chuo Electronics Co., Ltd."},
+ {0x1D47, "Ciena Corporation"},
+ {0x1013, "Cirrus Logic, Inc."},
+ {0x1137, "Cisco Systems, Inc."},
+ {0x5853, "Citrix Systems UK Ltd"},
+ {0x1558, "Clevo Co."},
+ {0x1D1D, "CNEX LABS Inc."},
+ {0x12B7, "Cognex Corporation"},
+ {0x1830, "Cohu, Inc."},
+ {0x1D38, "Colorado Engineering Inc."},
+ {0x18F7, "Commtech, Inc."},
+ {0x1DE6, "Communication Automation Corporation"},
+ {0x14C0, "Compal Electronics, Inc."},
+ {0x1C69, "Comtel Electronics GmbH"},
+ {0x125F, "Concurrent Technologies"},
+ {0x1C9B, "Conduant Corporation"},
+ {0x1A2F, "Congatec AG"},
+ {0x12C4, "Connect Tech Inc"},
+ {0x1221, "Contec Co., Ltd"},
+ {0x1571, "Contemporary Controls Systems Inc."},
+ {0x1C6B, "Corsair Memory"},
+ {0x1C46, "Cosmotechs Co., Ltd."},
+ {0x1D80, "COTS Technology"},
+ {0x136C, "CPI Technologies, Inc."},
+ {0x17DB, "Cray, Inc."},
+ {0x1102, "Creative Technology"},
+ {0x1E23, "Credo Semiconductor, Inc."},
+ {0x1DFD, "CRU-INC"},
+ {0xCCEC, "Curtiss-Wright Controls Embedded Computing"},
+ {0x18F2, "Dai-Ichi Seiko Co., Ltd(I-PEX)"},
+ {0x19EB, "DAIHEN Corporation"},
+ {0x1BFA, "Daiichi Jitsugyo Viswill Co., Ltd"},
+ {0x1C33, "Daktronics"},
+ {0x1E35, "Danaks, UAB"},
+ {0x194A, "Dap Holding B.V."},
+ {0x0303, "DAQ System"},
+ {0x1D91, "DAQRI LABS"},
+ {0x1E1A, "DataDirect Networks"},
+ {0x1D4C, "Datawise Systems, Inc."},
+ {0x1CB8, "Dawning Information Industry Co., Ltd."},
+ {0x1DC3, "Deep Insights Inc."},
+ {0x1A0E, "DekTec Digital Video B.V."},
+ {0x1E33, "Delkin Devices"},
+ {0x1028, "Dell Computer Corporation"},
+ {0x1A05, "Delta Electronics, Inc."},
+ {0x1B66, "Deltatec"},
+ {0x1192, "Densan Co., Ltd."},
+ {0x1192, "DENSAN Co.,Ltd."},
+ {0x1C04, "Dexon Systems Ltd"},
+ {0x15BD, "DFI Inc."},
+ {0x1D4C, "Diamanti, Inc."},
+ {0x1369, "Digigram"},
+ {0xDD01, "Digital Devices"},
+ {0x18FD, "Digital Media Professionals, Inc."},
+ {0xD161, "Digium, Inc."},
+ {0x17DF, "Dini Group LaJolla Inc."},
+ {0x12D8, "Diodes Incorporated"},
+ {0x1B31, "DisplayLink (UK) Ltd"},
+ {0x119D, "DMG MORI B.U.G. CO., LTD."},
+ {0x1D0C, "Dolby Laboratories, Inc."},
+ {0x11C8, "Dolphin Interconnect Solutions AS"},
+ {0x4453, "dSPACE GmbH"},
+ {0x1D3E, "DTS INSIGHT CORPORATION"},
+ {0x1BFC, "duagon AG"},
+ {0x3100, "Dynabook Inc."},
+ {0x1197, "DynamicSignals, LLC"},
+ {0x1B98, "E.E.P.D. GmbH"},
+ {0x1974, "Eberspächer Electronics GmbH & Co. KG"},
+ {0x177C, "EBRAINS, INC."},
+ {0x1DD6, "ECRIN SYSTEMS"},
+ {0x1428, "EDEC Linsey System"},
+ {0x1E2D, "Edge Networks LLC"},
+ {0x1DE5, "Eideticom"},
+ {0x181D, "eInfochips, Inc."},
+ {0x1227, "EIZO Rugged Solutions"},
+ {0xE4BF, "EKF Elektronik GmbH"},
+ {0x1E13, "Elbit Systems"},
+ {0xE1C5, "Elcus Electronic Company JSC"},
+ {0x13B9, "ELECOM CO LTD"},
+ {0x1C7F, "Elektrobit Austria GmbH"},
+ {0x1D4B, "Elektrosfera LTD."},
+ {0x1019, "Elitegroup Computer Systems Inc."},
+ {0x1E25, "Elk Solutions, LLC"},
+ {0x1C24, "Elma Bustronic Corp."},
+ {0x1C24, "Elma Electronic Inc"},
+ {0x1433, "Eltec Elektronik AG"},
+ {0x2782, "Emdoor Digital Technology Co., Ltd."},
+ {0xEACE, "Endace Technology Ltd."},
+ {0x123D, "Engineering Design Team, Inc."},
+ {0x1D8F, "ENYX"},
+ {0x1D89, "EpoStar Electronics Corp."},
+ {0x1A25, "Ericsson AS"},
+ {0x1E20, "ERNI Deutschland GmbH"},
+ {0x12FE, "esd electronics gmbh"},
+ {0x1E10, "eSOL Co.,Ltd."},
+ {0x1E0A, "Esperanto Technologies, Inc"},
+ {0x1E45, "ESSENCORE Limited"},
+ {0x1DF3, "Ethernity Networks Ltd"},
+ {0x1977, "Etion Create (Pty) Ltd."},
+ {0x1058, "ETRI"},
+ {0x1B6F, "Etron Technology, Inc."},
+ {0x1805, "Euresys SA"},
+ {0x1E19, "Eurofins Digital Testing Belgium NV"},
+ {0x1766, "Eurotech Spa"},
+ {0x1D86, "Evertz Microsystems Ltd."},
+ {0x3842, "EVGA Corporation"},
+ {0x1BC1, "EXFO Inc."},
+ {0x1E05, "Exicon Co., Ltd."},
+ {0x1CAD, "EXTOLL GmbH"},
+ {0x5845, "Extreme Engineering Solutions"},
+ {0xF5F5, "F5 Networks, Inc."},
+ {0x1D9B, "Facebook"},
+ {0x1DC5, "FADU Inc."},
+ {0x188B, "Faraday Technology Corporation"},
+ {0x1463, "Fast Corporation"},
+ {0x1D8C, "FASTWEL Group Co. Ltd"},
+ {0x1D8D, "Fiberhome Telecommunication Technologies"},
+ {0x1CF8, "Fibocom Wireless Inc."},
+ {0x1E1B, "Firm INFORMTEST Ltd."},
+ {0x22B8, "Flex Logix Technologies, Inc."},
+ {0x1895, "Flextronics International"},
+ {0x1CB5, "Focusrite Audio Engineering Ltd"},
+ {0x1778, "For-A Company Limited"},
+ {0x1165, "Foresight Imaging LLC"},
+ {0x1E1D, "Form, LLC"},
+ {0x1A29, "Fortinet, Inc."},
+ {0x1DC6, "Fox Crypto B.V."},
+ {0x105B, "Foxconn Interconnect Technology, Ltd."},
+ {0x1B73, "Fresco Logic, Inc."},
+ {0x16EA, "Fuji Electric Systems Co., Ltd."},
+ {0x1135, "Fuji Xerox Co Ltd"},
+ {0x127F, "FUJIFILM Corporation"},
+ {0x1183, "Fujikura Ltd."},
+ {0x10CF, "Fujitsu Limited"},
+ {0x1E1F, "Full Wise Technology Limited"},
+ {0x1DAD, "Fungible, Inc."},
+ {0x1D87, "Fuzhou Rockchip Electronics Co., Ltd"},
+ {0x1796, "FZ Juelich"},
+ {0x1B4C, "Galaxy Microsystems Ltd."},
+ {0x17F9, "GemTek Technology Co., Ltd."},
+ {0x123, "General Dynamics"},
+ {0x1775, "General Electric"},
+ {0x1C6E, "General Standards Corp"},
+ {0x1D32, "Genesis Co.,Ltd"},
+ {0x1DCB, "Genesis Technology USA, Inc."},
+ {0x17A0, "Genesys Logic, Inc."},
+ {0x15E7, "GET Engineering Corp."},
+ {0x15E7, "GET Engineering Corporation"},
+ {0x165C, "Gidel Ltd."},
+ {0x1458, "Giga-Byte Technology Co., Ltd."},
+ {0x1AC1, "Global Unichip Corp."},
+ {0x1D70, "GLOBALFOUNDRIES U.S. 2 LLC"},
+ {0x1D56, "Glyph Production Technologies"},
+ {0x140E, "GOEPEL electronic GmbH"},
+ {0x1D2D, "Good Way Technology Co., Ltd."},
+ {0x1AE0, "Google, Inc."},
+ {0x1A83, "Gopher Inc."},
+ {0x1C5E, "GopherTec Inc."},
+ {0x1BD7, "Granite River Labs Inc."},
+ {0x1D95, "Graphcore Ltd"},
+ {0x1FCA, "Grass Valley"},
+ {0x1B95, "Green Hills Software"},
+ {0x1BF5, "Greenliant"},
+ {0x1BF5, "Greenliant Systems"},
+ {0x1DE0, "Groq, Inc."},
+ {0x1E4C, "GSI Technology"},
+ {0x1DBF, "Guizhou Huaxintong Semiconductor Technology Co.,Ltd"},
+ {0x6D5E, "Guntermann & Drunck GmbH"},
+ {0x1253, "Guzik Technical Enterprises"},
+ {0x1E00, "Gyrfalcon Technology Inc"},
+ {0x1DA3, "Habana Labs"},
+ {0x1D29, "Hagiwara Solutions Co., Ltd."},
+ {0x11A1, "Hamamatsu Photonics K.K."},
+ {0x3086, "Hangzhou Hikvision Digital Technology Co., Ltd."},
+ {0x1C42, "Harman Automotive Division"},
+ {0x1738, "Harris Corporation (GCSD)"},
+ {0x19CB, "Hartmann Electronic GmbH"},
+ {0x19CB, "Hartmann Elektronik GmbH"},
+ {0x19A6, "HDL Design House"},
+ {0x112B, "Heidelberger Druckmaschinen AG"},
+ {0x1ACD, "Hensoldt Sensors GmbH"},
+ {0x103C, "Hewlett Packard"},
+ {0x1590, "Hewlett Packard Enterprise"},
+ {0x1DEA, "Hibertek International Limited"},
+ {0x15CF, "Hilscher Gesellschaft fuer Systemautomation mbH"},
+ {0x15CF, "Hilscher GmbH"},
+ {0x184C, "Hirose Electric USA Inc."},
+ {0x1FCD, "Hitachi High-Technologies Corporation"},
+ {0x1250, "Hitachi Ulsi Systems Co Ltd"},
+ {0x1367, "Hitachi Zosen Corporation"},
+ {0x1054, "Hitachi, Ltd"},
+ {0x14A9, "Hivertec Inc."},
+ {0x1BEE, "HMS Technology Center Ravensburg GmbH"},
+ {0x10AC, "Honeywell Inc."},
+ {0x103C, "HP Inc."},
+ {0x1426, "HRCP Research and Development Partnership"},
+ {0x19E5, "Huawei Technologies Co., Ltd."},
+ {0x21B4, "Hunan Goke Microelectronics Co., Ltd."},
+ {0x1DD2, "I-CUBE TECHNOLOGY co., ltd"},
+ {0x10FC, "I-O Data Device, Inc."},
+ {0x18F2, "I-PEX (Dai-ichi Seiko)"},
+ {0x1AAC, "IBASE Technology Inc."},
+ {0x11CA, "IBEX Technology, Co. Ltd."},
+ {0x1014, "IBM"},
+ {0x1B53, "iD corporation"},
+ {0x180C, "IEI Integration Corp."},
+ {0x1C9D, "Illumina"},
+ {0x1E3E, "Iluvatar CoreX Inc. Nanjing"},
+ {0x1D65, "Imagine Communications Corp."},
+ {0x1898, "Imaging Business Machines LLC"},
+ {0x15D1, "Infineon Technologies AG"},
+ {0x1D5B, "Infinera Corp."},
+ {0x1C1D, "Infocus Corp"},
+ {0x1BC0, "InnoDisk Corporation"},
+ {0x1DBE, "INNOGRIT CORPORATION"},
+ {0x1CFB, "Innotech Corporation"},
+ {0x1771, "InnoVISION Multimedia Limited."},
+ {0x1771, "InnoVision Multimedia, Ltd."},
+ {0x1D98, "Innovium, Inc."},
+ {0x1BD4, "Inspur Electronic Information Industry Co., Ltd."},
+ {0x1D4D, "Integrated Design Tools, Inc."},
+ {0x111D, "Integrated Device Technology"},
+ {0x8086, "Intel Corporation"},
+ {0x1739, "Interface Concept"},
+ {0x1147, "Interface Corporation"},
+ {0x1A6E, "International Game Technology"},
+ {0x1BDC, "Intrado Inc."},
+ {0x1E12, "Introspect Technology"},
+ {0x1B26, "INVEA-TECH a.s."},
+ {0x1D2F, "INVECAS, Inc."},
+ {0x1170, "Inventec Corporation"},
+ {0x1546, "IOI Technology Corporation"},
+ {0x1E50, "IP3 Tech (HK) Limited"},
+ {0x1DB6, "Irvin Technologies, Inc."},
+ {0x1BEE, "IXXAT Automation GmbH"},
+ {0x1817, "JAE"},
+ {0x1D12, "JESS-LINK PRODUCTS CO., LTD."},
+ {0x1DBC, "JitterLabs LLC"},
+ {0x197B, "JMicron Technology Corporation"},
+ {0x1E2B, "Jorjin Technologies Inc."},
+ {0x1304, "Juniper Networks"},
+ {0x13D6, "K.I. Technology Co., Ltd"},
+ {0x18B2, "K.K. Rocky"},
+ {0x1D26, "KALRAY"},
+ {0x13A1, "Kawasaki Heavy Industries Ltd."},
+ {0x1D2A, "KAYA Instruments Ltd"},
+ {0xCEBA, "KEBA AG"},
+ {0x1A3F, "KEL Corporation"},
+ {0x1B2A, "Keyence Corporation"},
+ {0x15BC, "Keysight Technologies"},
+ {0x1E04, "KeyW Corporation"},
+ {0x2646, "Kingston Technology Company"},
+ {0x1D7E, "KISTI"},
+ {0x1BBA, "KLA-Tencor"},
+ {0x1CA2, "KnowledgeTek, Inc."},
+ {0x1D93, "KNS Group"},
+ {0x1D90, "KnuEdge Inc."},
+ {0x1629, "Kongsberg Spacetec A.S."},
+ {0x16CB, "Konica Minolta Holdings Inc."},
+ {0x16CB, "Konica Minolta Inc."},
+ {0x1059, "Kontron"},
+ {0x1A07, "Kvaser AB"},
+ {0x1893, "Kyocera Corporation"},
+ {0x1341, "Kyoto Microcomputer Co., Ltd."},
+ {0x1C2D, "L-3 Chesapeake Sciences Corporation"},
+ {0x1204, "Lattice Semiconductor Corporation"},
+ {0x1407, "Lava Computer Mfg Inc"},
+ {0x107D, "Leadtek Research Inc."},
+ {0x1CE1, "Lecoln Technology Co., Ltd."},
+ {0x17AA, "Lenovo"},
+ {0x126A, "Lexmark International, Inc."},
+ {0x1E29, "LIBERTRON Co., Ltd."},
+ {0x1D9A, "LightBits Labs Ltd."},
+ {0x1E3F, "Linaro Limited"},
+ {0x1D14, "Lintes Technology Co., Ltd."},
+ {0x1DCD, "Liqid Inc"},
+ {0x14A4, "Lite-On Technology Corporation"},
+ {0x1E03, "Logic Supply, Inc."},
+ {0x1DBD, "Logic-Fruit Technologies Pvt. Ltd"},
+ {0x0014, "Loongson Technology Corporation Limited"},
+ {0x1880, "LOTES Co., Ltd"},
+ {0x1DFC, "LTD NTCOM"},
+ {0x1BDF, "LUXSHARE-ICT Co., Ltd."},
+ {0x1CAB, "Lynx Software Technologies, Inc."},
+ {0x1D27, "M31 Technology Corporation"},
+ {0x1916, "Macnica Inc."},
+ {0x137A, "Mark of the Unicorn Inc"},
+ {0x1148, "Marvell Semiconductor, Inc."},
+ {0x16E2, "Marvin Test Solutions, Inc."},
+ {0x102B, "Matrox Graphics, Inc."},
+ {0x1BBF, "Maxeler Technologies Ltd."},
+ {0x1E4B, "Maxio Technology (Hangzhou) Ltd."},
+ {0x1DB8, "Maxiotek Corporation"},
+ {0x1E43, "MaxLinear Inc"},
+ {0x1DD0, "McDowell Signal Processing, LLC"},
+ {0x1AA2, "Media Links Co., LTD."},
+ {0x14C3, "MediaTek Incorporation"},
+ {0x1E39, "MEDION AG"},
+ {0x136B, "MegaChips Corporation"},
+ {0x10A0, "Meidensha Corporation"},
+ {0x1360, "Meinberg Funkuhren GmbH & Co. KG"},
+ {0x152E, "Melec Inc"},
+ {0x15B3, "Mellanox Technologies"},
+ {0x1CA0, "MEMORIGHT"},
+ {0x1A88, "MEN Mikro Elektronik GmbH"},
+ {0x14AB, "Mentor Graphics Corporation"},
+ {0x1E2E, "Mercedes-Benz R&D North America, Inc."},
+ {0x1134, "Mercury Computer Systems"},
+ {0x1E06, "Micro Brain, Inc."},
+ {0x1A3E, "Micro-Research Finland Oy"},
+ {0x1462, "Micro-Star International Co ., Ltd."},
+ {0x0054, "Microchip Technology"},
+ {0x1344, "Micron Technology Inc"},
+ {0x1414, "Microsoft"},
+ {0x4D54, "Microtechnica Co., Ltd."},
+ {0x22DB, "Missing Link Electronics, Inc."},
+ {0x1DAF, "MIT Lincoln Laboratory"},
+ {0x1071, "MiTAC International Corporation"},
+ {0x10BA, "Mitsubishi Electric Corporation"},
+ {0x1547, "Mitutoyo Corporation"},
+ {0x1C8C, "Mobiveil"},
+ {0x10D2, "Molex Inc."},
+ {0x1B00, "Montage Technology"},
+ {0xC0FE, "Motion Engineering"},
+ {0x1DFE, "Motorola Solutions"},
+ {0x18E6, "MPL AG"},
+ {0x1B08, "MSC Technologies GmbH"},
+ {0x1B08, "MSC Vertriebs GmbH"},
+ {0x1322, "MTT Corporation"},
+ {0x1B7B, "Multisuns Corporation"},
+ {0x1E53, "Mythic - AI"},
+ {0x198A, "Nallatech"},
+ {0x1CFC, "Naltec, Inc."},
+ {0x1B8F, "Nanoteq (Pty) Ltd"},
+ {0x18F4, "Napatech A/S"},
+ {0x1093, "National Instruments"},
+ {0x1BCF, "NEC"},
+ {0x1D85, "Neosem Holdings Inc"},
+ {0x1275, "NetApp"},
+ {0x1275, "NetApp, Inc."},
+ {0x1B26, "Netcope Technologies a.s."},
+ {0x1D82, "NETINT Technologies Inc."},
+ {0x1C1B, "Netlist, Inc."},
+ {0x19EE, "Netronome"},
+ {0x193D, "New H3C Technologies Co., Ltd."},
+ {0x1E61, "New Telecommunication Technologies LLC"},
+ {0xAD10, "New Wave Design and Verification, LLC"},
+ {0x149D, "NewTek"},
+ {0x1933, "Nexcom International"},
+ {0x1DBB, "NGD Systems, Inc."},
+ {0x1BB2, "Nikon Corporation"},
+ {0x12E1, "Nintendo Co., Ltd."},
+ {0x13B8, "Nokia Solutions and Networks"},
+ {0x1E11, "Northern Han Trade Co., Limited"},
+ {0x1B0C, "Northrop Grumman Corp., Electronic Systems"},
+ {0x19AA, "Northwest Logic, Inc."},
+ {0x0222, "Not for Radio, LLC"},
+ {0x1CBD, "Novachips Co., Ltd."},
+ {0x1D37, "NovaSparks"},
+ {0x1E09, "Novatek Microelectronics Corporation"},
+ {0x1E02, "NSITEXE, Inc."},
+ {0x12A4, "NTT Electronics Corp."},
+ {0x1808, "nVent, Schroff GmbH"},
+ {0x10DE, "NVidia Corporation"},
+ {0x1DE9, "NVXL Technology Inc."},
+ {0x1131, "NXP Semiconductors"},
+ {0x0C10, "Oclaro Inc"},
+ {0x16C8, "Octasic Inc."},
+ {0x1795, "OKB SAPR"},
+ {0x1021, "Oki Electric Industry Co. Ltd."},
+ {0x1270, "Olympus Corporation"},
+ {0x10CB, "Omron Corporation"},
+ {0x160C, "OMS Motion, Inc."},
+ {0x160C, "OMS Motoin, Inc."},
+ {0x1529, "ON Semiconductor"},
+ {0x1954, "One Stop Systems, Inc."},
+ {0x1DF7, "opencpi.org"},
+ {0x18FE, "Opex Corporation"},
+ {0x17E3, "OPTEON Corporation"},
+ {0x148A, "OPTO 22"},
+ {0x108E, "Oracle"},
+ {0x1DA4, "Orient Semiconductor Electronics, Ltd."},
+ {0x1576, "Osprey Video"},
+ {0x169A, "Otari, Inc."},
+ {0x1C7A, "Other World Computing"},
+ {0x19A4, "Owl Cyber Defense Solutions LLC"},
+ {0x1569, "Palit Microsystems Ltd."},
+ {0x1DA6, "Palodex Group Oy"},
+ {0x1189, "Panasonic Corporation"},
+ {0x1AF8, "Parade Technologies, Inc."},
+ {0x1AB8, "Parallels International GmbH"},
+ {0x1CE5, "PARPRO, Inc."},
+ {0x1D99, "Pattern Computer Inc."},
+ {0x174B, "PC Partner Limited"},
+ {0x001C, "PEAK-System Technik GmbH"},
+ {0x1B0A, "Pegatron Corporation"},
+ {0x1DD8, "Pensando Systems"},
+ {0x12D8, "Pericom Semiconductor"},
+ {0x1FCB, "PerkinElmer"},
+ {0x155F, "Perle Systems Limited"},
+ {0x9753, "PEZY Computing K.K."},
+ {0x1987, "Phison Electronics Corporation"},
+ {0x1442, "Phoenix Contact Gmbh & Co. KG"},
+ {0x1363, "Phoenix Technologies"},
+ {0x115C, "Photron Ltd."},
+ {0x1761, "Pickering Interfaces Ltd."},
+ {0x1718, "Pixela Corporation"},
+ {0x1556, "PLDA"},
+ {0x1C79, "Plexus Corp."},
+ {0x1D7F, "Plugable"},
+ {0x15BB, "Portwell Inc"},
+ {0x1D51, "Powerleader Science & Technology Co. Ltd"},
+ {0x1C67, "PreSonus Audio Electronics Inc."},
+ {0x160C, "Pro-Dex, Oregon Micro Systems"},
+ {0x1D10, "Procera Networks, Inc."},
+ {0x1C72, "ProDesign Electronic GmbH"},
+ {0x105A, "Promise Technology, Inc."},
+ {0x19D5, "Protech Systems"},
+ {0x17C3, "Protogate, Inc."},
+ {0x1D00, "Pure Storage, Inc."},
+ {0x1BAA, "QNAP Systems, Inc."},
+ {0x1E34, "Qrypt, Inc."},
+ {0x1A9D, "QSC Audio Products, Inc."},
+ {0x5143, "Qualcomm Inc."},
+ {0x152D, "Quanta Computer Inc."},
+ {0x1BB5, "Quantenna Communications, Inc."},
+ {0x1D64, "Quarch Technology Ltd"},
+ {0x11E3, "Quicklogic Corporation"},
+ {0x19D4, "Quixant Plc"},
+ {0x1CC6, "Radian Memory Systems Inc."},
+ {0x186F, "Radixon Group Pty Ltd."},
+ {0x1195, "Ratoc Systems Inc."},
+ {0x10B2, "Raytheon Company"},
+ {0x1A58, "Razer Inc."},
+ {0x17F3, "RDC Semiconductor Co., Ltd."},
+ {0x10EC, "Realtek Semiconductor Corporation"},
+ {0x1B36, "Red Hat, Inc."},
+ {0x17D2, "Red Rapids"},
+ {0x1960, "REJ Co., Ltd."},
+ {0x1912, "Renesas Electronics Corporation"},
+ {0x163F, "Renishaw PLC"},
+ {0x1180, "Ricoh Company, Ltd."},
+ {0x1D76, "Rincon Research Corporation"},
+ {0x1B2E, "Riverbed Technology, Inc."},
+ {0x1D18, "RME GmbH"},
+ {0x12A0, "Rockwell Automation Inc. (Allen-Bradley)"},
+ {0x15D7, "Rockwell Collins, Inc."},
+ {0x162F, "Rohde & Schwarz Gmbh & Co Kg"},
+ {0x10DB, "Rohm Co., Ltd."},
+ {0x16CE, "Roland Corporation"},
+ {0x1B6B, "Roper Scientific dba Photometrics, dba Qimaging"},
+ {0x1CBF, "Ross Video"},
+ {0x1DF4, "ROW6, Inc."},
+ {0x1435, "RTD Embedded Technologies, Inc."},
+ {0x1B86, "Saab AB"},
+ {0x16AE, "SafeNet, Inc."},
+ {0x1DD3, "Sage Microelectronics Corp."},
+ {0x1E0D, "SambaNova Systems, Inc."},
+ {0x144D, "Samsung Electronics Co., Ltd."},
+ {0x1A82, "Samtec Inc."},
+ {0x1923, "Sangoma Technologies Corporation"},
+ {0x1CC3, "Sanmina"},
+ {0x1380, "Sanritz Automation Co., Ltd."},
+ {0x194D, "Sansei System Co., Ltd."},
+ {0x1DA2, "Sapphire Technology Limited"},
+ {0x174F, "SAXA, Inc."},
+ {0xCC53, "ScaleFlux Inc."},
+ {0x8686, "ScaleMP"},
+ {0x1C2E, "Schneider Electric Japan Holdings Ltd."},
+ {0x1AA9, "Schweitzer Engineering Labs, Inc."},
+ {0x1D60, "Scietera Technologies, Inc"},
+ {0x11C6, "SCREEN Graphic and Precision Solutions Co., Ltd."},
+ {0x11C6, "SCREEN GRAPHIC SOLUTIONS CO., LTD."},
+ {0x1BB1, "Seagate Technology LLC"},
+ {0x1A0D, "SEAKR Engineering Inc."},
+ {0x135E, "Sealevel Systems, Inc."},
+ {0x1BEC, "SECO Srl"},
+ {0x1CDD, "Secunet Security Networks AG"},
+ {0x11DB, "Sega Corporation"},
+ {0x11DB, "SEGA Interactive Co., Ltd."},
+ {0x1C85, "Seiko Instruments, Inc."},
+ {0x1CB4, "SerialTek"},
+ {0x1E27, "Shanghai Denglin Technology Co., Ltd"},
+ {0x1E36, "Shanghai Enflame Technology Co. Ltd"},
+ {0x1E2A, "Shanghai JYTEK Co., Ltd"},
+ {0x1D17, "Shanghai Zhaoxin Semiconductor Co., Ltd."},
+ {0x1CB0, "Shannon Systems"},
+ {0x1D08, "Shen Zhen Deren Electronic Co., LTD."},
+ {0x8009, "Shengli Financial Software Development Co.Ltd"},
+ {0x1642, "Shenzhen Bitland Information Technology Co., Ltd"},
+ {0x1E3B, "Shenzhen DAPU Microelectronics Co., Ltd"},
+ {0x1E0B, "Shenzhen Decenta Technology Co.,LTD"},
+ {0x4C52, "Shenzhen Lianrui Electronics Co.,Ltd"},
+ {0x1D97, "Shenzhen Longsys Electronics Co., Ltd."},
+ {0x1DF5, "ShenZhen TIGO Semiconductor Co., Ltd."},
+ {0x1CC4, "Shenzhen Unionmemory information system limited"},
+ {0x1C37, "Shikino High-Tech Co., Ltd"},
+ {0x1C71, "Shimadzu Corporation"},
+ {0x110A, "Siemens AG"},
+ {0x18D7, "Sierra Wireless, Inc."},
+ {0xF15E, "SiFive, Inc."},
+ {0x1BE9, "Signal Integrity Software, Inc."},
+ {0x1BEB, "SignalCore, Inc."},
+ {0x131F, "SIIG, Inc."},
+ {0x1BCE, "Silex Technology, Inc."},
+ {0x1374, "SiLicom, Ltd"},
+ {0x1E14, "Silicon Creations, LLC"},
+ {0xA23B, "Silicon Integrated Systems"},
+ {0x1543, "Silicon Labs"},
+ {0x126F, "Silicon Motion, Inc."},
+ {0x1AE8, "Silicon Software GmbH"},
+ {0x1DF9, "Simula Technology Inc."},
+ {0x1C5C, "SK Hynix"},
+ {0x1A4A, "SLAC National Accelerator Lab PPA-REG"},
+ {0x1235, "SMART Modular Technologies"},
+ {0x1CDF, "SmartDV North America, LLC"},
+ {0x1E4F, "Smiths Interconnect"},
+ {0x50C1, "Socionext Inc."},
+ {0x8322, "Sodick America Corporation"},
+ {0x14A0, "Softing AG"},
+ {0x1924, "Solarflare Communications, Inc."},
+ {0x1D1E, "Solid State System"},
+ {0x1BC9, "Sonifex Ltd"},
+ {0x104D, "Sony Corporation"},
+ {0x1E31, "SORD Corporation"},
+ {0x1B37, "SP Devices"},
+ {0x1BB8, "Space Exploration Technologies"},
+ {0x1DAC, "SparkLAN Communications, Inc."},
+ {0x1E41, "Spectra7 Microsystems"},
+ {0x18F1, "Spectrum Instrumentation GmbH"},
+ {0x174A, "Spirent Communications"},
+ {0x1DB3, "Spreadtrum Communications (Shanghai) Co., Ltd."},
+ {0x1E24, "Squirrels, Inc"},
+ {0x191E, "SRISA"},
+ {0x1DC7, "SSI Computer Corp"},
+ {0x1A8A, "Star Bridge, Inc."},
+ {0x1BCA, "Star Communications, Inc."},
+ {0x1974, "STAR Electronics GmbH & Co. KG"},
+ {0x1B5E, "Star-Dundee Ltd."},
+ {0x1B45, "StarTech.com Ltd."},
+ {0x104A, "STMicroelectronics International NV"},
+ {0x1D63, "StorArt Technology Co., Ltd"},
+ {0x159C, "Stratus Technologies, Inc."},
+ {0x1CF7, "Subspace Dynamics LLC"},
+ {0x1FD4, "Sunix Co., Ltd."},
+ {0x15D9, "Super Micro Computer Inc."},
+ {0x1E0E, "Suruga Seiki Co.,Ltd."},
+ {0x1DD4, "Swissbit AG"},
+ {0x15E0, "Symantec (Canada) Corp."},
+ {0x1E01, "Synaptics, Inc."},
+ {0x1CA1, "Sync-n-Scale, LLC"},
+ {0x16C3, "Synopsys, Inc."},
+ {0x184B, "SYSTEC Corporation"},
+ {0x1E47, "SZ DJI Technology Co., Ltd."},
+ {0x1B80, "T-Systems International GmbH"},
+ {0x1BF7, "T.P.A. s.p.a."},
+ {0x1A12, "Taiwan Commate Computer"},
+ {0x1CEB, "Taiwan Pulse Motion Co., Ltd."},
+ {0x12AF, "TDK Corporation"},
+ {0x1513, "TE Connectivity"},
+ {0x1A9F, "Tech S.A.T. GmbH"},
+ {0x1227, "Tech Source Inc."},
+ {0x1D61, "Technobox, Inc."},
+ {0x1C4E, "Techway"},
+ {0x1DA1, "Teko Telecom S.r.l. a Socio Unico"},
+ {0x1268, "Tektronix"},
+ {0x1D88, "Telechips Inc."},
+ {0x1570, "Teledyne LeCroy"},
+ {0x1B37, "Teledyne SP Devices"},
+ {0x13E5, "Telesoft Technologies Ltd."},
+ {0x1C5D, "Telit Communications SPA"},
+ {0x1E52, "Tenstorrent Inc"},
+ {0x6549, "Teradici Corporation"},
+ {0x1316, "Teradyne, Inc."},
+ {0x1DCC, "TERMINUS CIRCUITS Pvt Ltd"},
+ {0x1E37, "Testmetrix Inc"},
+ {0x1498, "TEWS Technologies GmbH"},
+ {0x104C, "Texas Instruments"},
+ {0x1269, "Thales"},
+ {0x1BD5, "The FreeBSD Foundation"},
+ {0x1E38, "ThinCI, Inc."},
+ {0x1168, "Thine Electronics, Inc."},
+ {0x1E40, "ThinkRF Corp."},
+ {0x1DDD, "Thorlabs, Inc."},
+ {0x1E2F, "Tiburn Technology Co., Ltd."},
+ {0x1D72, "Timi Personal Computing Co., Ltd."},
+ {0x14D2, "TITAN Electronics Inc."},
+ {0x1BC8, "Tokushu Denshi Kairo Inc."},
+ {0x1BC8, "TokushuDenshiKairo Inc."},
+ {0x1679, "Tokyo Electron Device Ltd."},
+ {0x138B, "TOKYO KEIKI INC."},
+ {0x1E22, "Tongfang Computer Co.,Ltd"},
+ {0x1D05, "TONGFANG HONGKONG LIMITED"},
+ {0x1D31, "TOSEI ENGINEERING CORP."},
+ {0x1179, "Toshiba Corporation"},
+ {0x1E0F, "Toshiba Memory Corporation"},
+ {0x1D79, "Transcend Information, Inc."},
+ {0x11D7, "Trenton Systems, Inc."},
+ {0x1A3D, "Tritek Co., Ltd."},
+ {0x1C64, "TRS-RenTelco"},
+ {0x1DAB, "Tsinghua University"},
+ {0x189E, "TSMC"},
+ {0x1C7E, "TTTech Computertechnik AG"},
+ {0x148C, "Tul Corporation"},
+ {0x1E32, "Tuxera Inc."},
+ {0x14FF, "Twinhead International Corporation"},
+ {0x1ADD, "u-blox AG"},
+ {0x1E51, "UAB Neurotechnologijos"},
+ {0x0A7C, "UATC, LLC"},
+ {0x19BC, "Ueda Japan Radio Co., Ltd."},
+ {0x1D44, "ULINK Technology, Inc."},
+ {0x18D1, "ULVAC-PHI, Inc."},
+ {0x1C1A, "UNH InterOperability Laboratory"},
+ {0x1C1A, "UNH InterOperability Laboratory (UNH-IOL)"},
+ {0x1D78, "UNIC Memory Technology Co., Ltd."},
+ {0x19BF, "Unicom Engineering Inc"},
+ {0x1018, "Unisys Corporation"},
+ {0x1DC9, "UniTest Inc."},
+ {0x1A00, "Universal Audio, Inc."},
+ {0x14CD, "Universal Global Scientific Industrial Co., Ltd"},
+ {0x1DA5, "UTran Technology Inc."},
+ {0x1DF8, "V&G Information System Co.,Ltd"},
+ {0xABCD, "Vadatech Inc."},
+ {0x1D19, "VAIO Corporation"},
+ {0x1DDE, "Valens Semiconductor Ltd."},
+ {0x1E44, "Valve Software"},
+ {0x1E1C, "Vanguard Rugged Storage, LLC"},
+ {0x1FCB, "Varex Imaging Deutschland AG"},
+ {0x1E46, "Varjo Technologies Oy"},
+ {0x1DAE, "Vectology,Inc."},
+ {0x19E2, "Vector Informatik GmbH"},
+ {0x144B, "Verint"},
+ {0x1106, "VIA Technologies, Inc."},
+ {0x1D7D, "Viavi Solutions"},
+ {0x1E07, "ViGEM GmbH"},
+ {0x1C60, "Viking Technology"},
+ {0x1DF0, "Virtuozzo International GmbH"},
+ {0x156C, "VMagic Electronics GmbH"},
+ {0x15AD, "Vmware, Inc."},
+ {0x5658, "VX Instruments GmbH"},
+ {0x1DC8, "Wave Computing, Inc."},
+ {0x1B96, "Western Digital Technologies, Inc."},
+ {0x1C6C, "Wibtek Electronics Co., Ltd"},
+ {0x1E15, "Wieson Technologies Co., LTD."},
+ {0x1CCE, "Wilder Technologies"},
+ {0x1B17, "WinSystems, Inc."},
+ {0x1811, "Wipro Technologies"},
+ {0x17C0, "Wistron Corporation"},
+ {0x301F, "WOLF Advanced Technology"},
+ {0x10C5, "Xerox Corporation"},
+ {0x1C40, "Xia LLC"},
+ {0x10EE, "Xilinx, Inc."},
+ {0xDEDA, "XIMEA"},
+ {0x1C5B, "XJTAG Ltd."},
+ {0x1073, "Yamaha Corporation"},
+ {0x18B4, "Yamaichi Electronics"},
+ {0x150B, "Yamashita Systems Corp"},
+ {0x1E49, "Yangtze Memory Technologies Co.,Ltd"},
+ {0x1313, "YASKAWA Electric Corporation"},
+ {0x1281, "Yokogawa Electric Corporation"},
+ {0x1D6B, "ZAO Kraftway Corporation PLC"},
+ {0x1E21, "ZF Friedrichshafen AG"},
+ {0x1CCF, "Zoom Corporation"},
+};
\ No newline at end of file
diff --git a/include/peci_pcie.hpp b/include/peci_pcie.hpp
new file mode 100644
index 0000000..3771699
--- /dev/null
+++ b/include/peci_pcie.hpp
@@ -0,0 +1,35 @@
+/*
+// Copyright (c) 2019 intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#pragma once
+#include <peci.h>
+
+#include <cstdint>
+#include <vector>
+
+namespace peci_pcie
+{
+static constexpr char const* peciPCIeObject = "xyz.openbmc_project.PCIe";
+static constexpr char const* peciPCIePath = "/xyz/openbmc_project/PCIe";
+static constexpr char const* peciPCIeDeviceInterface =
+ "xyz.openbmc_project.PCIe.Device";
+
+static constexpr const int maxPCIBuses = 256;
+static constexpr const int maxPCIDevices = 32;
+static constexpr const int maxPCIFunctions = 8;
+
+static constexpr const int peciCheckInterval = 10;
+} // namespace peci_pcie
diff --git a/service_files/xyz.openbmc_project.PCIe.service b/service_files/xyz.openbmc_project.PCIe.service
new file mode 100644
index 0000000..7c48a03
--- /dev/null
+++ b/service_files/xyz.openbmc_project.PCIe.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Service to get PCIe info over PECI
+
+[Service]
+Restart=always
+ExecStart=/usr/bin/peci-pcie
+Type=simple
+
+[Install]
+WantedBy=multi-user.target
diff --git a/src/peci_pcie.cpp b/src/peci_pcie.cpp
new file mode 100644
index 0000000..8db1f89
--- /dev/null
+++ b/src/peci_pcie.cpp
@@ -0,0 +1,540 @@
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include "peci_pcie.hpp"
+
+#include "pciDeviceClass.hpp"
+#include "pciVendors.hpp"
+
+#include <boost/container/flat_map.hpp>
+#include <boost/container/flat_set.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+#include <iomanip>
+#include <iostream>
+#include <set>
+#include <sstream>
+
+namespace peci_pcie
+{
+static boost::container::flat_map<
+ int, boost::container::flat_map<
+ int, boost::container::flat_map<
+ int, std::shared_ptr<sdbusplus::asio::dbus_interface>>>>
+ pcieDeviceDBusMap;
+
+namespace function
+{
+static constexpr char const* functionTypeName = "FunctionType";
+static constexpr char const* deviceClassName = "DeviceClass";
+static constexpr char const* vendorIdName = "VendorId";
+static constexpr char const* deviceIdName = "DeviceId";
+static constexpr char const* classCodeName = "ClassCode";
+static constexpr char const* revisionIdName = "RevisionId";
+static constexpr char const* subsystemIdName = "SubsystemId";
+static constexpr char const* subsystemVendorIdName = "SubsystemVendorId";
+} // namespace function
+} // namespace peci_pcie
+
+// PECI Client Address Map
+static void getClientAddrMap(std::vector<int>& clientAddrs)
+{
+ for (int i = MIN_CLIENT_ADDR; i <= MAX_CLIENT_ADDR; i++)
+ {
+ if (peci_Ping(i) == PECI_CC_SUCCESS)
+ {
+ clientAddrs.push_back(i);
+ }
+ }
+}
+
+static bool isPECIAvailable(void)
+{
+ std::vector<int> clientAddrs;
+ getClientAddrMap(clientAddrs);
+ if (clientAddrs.empty())
+ {
+ return false;
+ }
+ return true;
+}
+
+static bool getDataFromPCIeConfig(const int& clientAddr, const int& bus,
+ const int& dev, const int& func,
+ const int& offset, const int& size,
+ uint32_t& pciData)
+{
+ // PECI RdPCIConfig() currently only supports 4 byte reads, so adjust
+ // the offset and size to get the right data
+ static constexpr const int pciReadSize = 4;
+ int mod = offset % pciReadSize;
+ int pciOffset = offset - mod;
+ if (mod + size > pciReadSize)
+ {
+ return false;
+ }
+
+ std::array<uint8_t, pciReadSize> data;
+ uint8_t cc;
+ int ret = peci_RdPCIConfig(clientAddr, // CPU Address
+ bus, // PCI Bus
+ dev, // PCI Device
+ func, // PCI Function
+ pciOffset, // PCI Offset
+ data.data(), // PCI Read Data
+ &cc); // PECI Completion Code
+
+ if (ret != PECI_CC_SUCCESS || cc != PECI_DEV_CC_SUCCESS)
+ {
+ return false;
+ }
+
+ // Now build the requested data into a single number
+ pciData = 0;
+ for (int i = mod; i < mod + size; i++)
+ {
+ pciData |= data[i] << 8 * (i - mod);
+ }
+
+ return true;
+}
+
+static std::string getStringFromPCIeConfig(const int& clientAddr,
+ const int& bus, const int& dev,
+ const int& func, const int& offset,
+ const int& size)
+{
+ // Get the requested data
+ uint32_t data = 0;
+ if (!getDataFromPCIeConfig(clientAddr, bus, dev, func, offset, size, data))
+ {
+ return std::string();
+ }
+
+ // And convert it to a string
+ std::stringstream dataStream;
+ dataStream << "0x" << std::hex << std::setfill('0') << std::setw(size * 2)
+ << data;
+ return dataStream.str();
+}
+
+static std::string getVendorName(const int& clientAddr, const int& bus,
+ const int& dev)
+{
+ static constexpr const int vendorIDOffset = 0x00;
+ static constexpr const int vendorIDSize = 2;
+
+ // Get the header type register from function 0
+ uint32_t vendorID = 0;
+ if (!getDataFromPCIeConfig(clientAddr, bus, dev, 0, vendorIDOffset,
+ vendorIDSize, vendorID))
+ {
+ return std::string();
+ }
+ // Get the vendor name or use Other if it doesn't exist
+ return pciVendors.try_emplace(vendorID, otherVendor).first->second;
+}
+
+static std::string getDeviceClass(const int& clientAddr, const int& bus,
+ const int& dev, const int& func)
+{
+ static constexpr const int baseClassOffset = 0x0b;
+ static constexpr const int baseClassSize = 1;
+
+ // Get the Device Base Class
+ uint32_t baseClass = 0;
+ if (!getDataFromPCIeConfig(clientAddr, bus, dev, func, baseClassOffset,
+ baseClassSize, baseClass))
+ {
+ return std::string();
+ }
+ // Get the base class name or use Other if it doesn't exist
+ return pciDeviceClasses.try_emplace(baseClass, otherClass).first->second;
+}
+
+static bool isMultiFunction(const int& clientAddr, const int& bus,
+ const int& dev)
+{
+ static constexpr const int headerTypeOffset = 0x0e;
+ static constexpr const int headerTypeSize = 1;
+ static constexpr const int multiFuncBit = 1 << 7;
+
+ // Get the header type register from function 0
+ uint32_t headerType = 0;
+ if (!getDataFromPCIeConfig(clientAddr, bus, dev, 0, headerTypeOffset,
+ headerTypeSize, headerType))
+ {
+ return false;
+ }
+ // Check if it's a multifunction device
+ if (headerType & multiFuncBit)
+ {
+ return true;
+ }
+ return false;
+}
+
+static bool pcieFunctionExists(const int& clientAddr, const int& bus,
+ const int& dev, const int& func)
+{
+ constexpr const int pciIDOffset = 0;
+ constexpr const int pciIDSize = 4;
+ uint32_t pciID = 0;
+ if (!getDataFromPCIeConfig(clientAddr, bus, dev, func, pciIDOffset,
+ pciIDSize, pciID))
+ {
+ return false;
+ }
+
+ // if VID and DID are all 0s or 1s, then the device doesn't exist
+ if (pciID == 0x00000000 || pciID == 0xFFFFFFFF)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+static bool pcieDeviceExists(const int& clientAddr, const int& bus,
+ const int& dev)
+{
+ // Check if this device exists by checking function 0
+ return (pcieFunctionExists(clientAddr, bus, dev, 0));
+}
+
+static void setPCIeProperty(const int& clientAddr, const int& bus,
+ const int& dev, const std::string& propertyName,
+ const std::string& propertyValue)
+{
+ std::shared_ptr<sdbusplus::asio::dbus_interface> iface =
+ peci_pcie::pcieDeviceDBusMap[clientAddr][bus][dev];
+
+ if (iface->is_initialized())
+ {
+ iface->set_property(propertyName, propertyValue);
+ }
+ else
+ {
+ iface->register_property(propertyName, propertyValue);
+ }
+}
+
+static void setDefaultPCIeFunctionProperties(const int& clientAddr,
+ const int& bus, const int& dev,
+ const int& func)
+{
+ // Set the function-specific properties
+ static constexpr const std::array functionProperties{
+ peci_pcie::function::functionTypeName,
+ peci_pcie::function::deviceClassName,
+ peci_pcie::function::vendorIdName,
+ peci_pcie::function::deviceIdName,
+ peci_pcie::function::classCodeName,
+ peci_pcie::function::revisionIdName,
+ peci_pcie::function::subsystemIdName,
+ peci_pcie::function::subsystemVendorIdName,
+ };
+
+ for (const char* name : functionProperties)
+ {
+ setPCIeProperty(clientAddr, bus, dev,
+ "Function" + std::to_string(func) + std::string(name),
+ std::string());
+ }
+}
+
+static void setPCIeFunctionProperties(const int& clientAddr, const int& bus,
+ const int& dev, const int& func)
+{
+ // Set the function type always to physical for now
+ setPCIeProperty(clientAddr, bus, dev,
+ "Function" + std::to_string(func) +
+ std::string(peci_pcie::function::functionTypeName),
+ "Physical");
+
+ // Set the function Device Class
+ setPCIeProperty(clientAddr, bus, dev,
+ "Function" + std::to_string(func) +
+ std::string(peci_pcie::function::deviceClassName),
+ getDeviceClass(clientAddr, bus, dev, func));
+
+ // Get PCI Function Properties that come from PCI config with the following
+ // offset and size info
+ static constexpr const std::array pciConfigInfo{
+ std::tuple<const char*, int, int>{peci_pcie::function::vendorIdName, 0,
+ 2},
+ std::tuple<const char*, int, int>{peci_pcie::function::deviceIdName, 2,
+ 2},
+ std::tuple<const char*, int, int>{peci_pcie::function::classCodeName, 9,
+ 3},
+ std::tuple<const char*, int, int>{peci_pcie::function::revisionIdName,
+ 8, 1},
+ std::tuple<const char*, int, int>{peci_pcie::function::subsystemIdName,
+ 0x2e, 2},
+ std::tuple<const char*, int, int>{
+ peci_pcie::function::subsystemVendorIdName, 0x2c, 2}};
+
+ for (const auto& [name, offset, size] : pciConfigInfo)
+ {
+ setPCIeProperty(
+ clientAddr, bus, dev,
+ "Function" + std::to_string(func) + std::string(name),
+ getStringFromPCIeConfig(clientAddr, bus, dev, func, offset, size));
+ }
+}
+
+static void setPCIeDeviceProperties(const int& clientAddr, const int& bus,
+ const int& dev)
+{
+ // Set the device manufacturer
+ setPCIeProperty(clientAddr, bus, dev, "Manufacturer",
+ getVendorName(clientAddr, bus, dev));
+
+ // Set the device type
+ constexpr char const* deviceTypeName = "DeviceType";
+ if (isMultiFunction(clientAddr, bus, dev))
+ {
+ setPCIeProperty(clientAddr, bus, dev, deviceTypeName, "MultiFunction");
+ }
+ else
+ {
+ setPCIeProperty(clientAddr, bus, dev, deviceTypeName, "SingleFunction");
+ }
+}
+
+static void updatePCIeDevice(const int& clientAddr, const int& bus,
+ const int& dev)
+{
+ setPCIeDeviceProperties(clientAddr, bus, dev);
+
+ // Walk through and populate the functions for this device
+ for (int func = 0; func < peci_pcie::maxPCIFunctions; func++)
+ {
+ if (pcieFunctionExists(clientAddr, bus, dev, func))
+ {
+ // Set the properties for this function
+ setPCIeFunctionProperties(clientAddr, bus, dev, func);
+ }
+ else
+ {
+ // Set default properties for unused functions
+ setDefaultPCIeFunctionProperties(clientAddr, bus, dev, func);
+ }
+ }
+}
+
+static void addPCIeDevice(sdbusplus::asio::object_server& objServer,
+ const int& clientAddr, const int& cpu, const int& bus,
+ const int& dev)
+{
+ std::string pathName = std::string(peci_pcie::peciPCIePath) + "/S" +
+ std::to_string(cpu) + "B" + std::to_string(bus) +
+ "D" + std::to_string(dev);
+ std::shared_ptr<sdbusplus::asio::dbus_interface> iface =
+ objServer.add_interface(pathName, peci_pcie::peciPCIeDeviceInterface);
+ peci_pcie::pcieDeviceDBusMap[clientAddr][bus][dev] = iface;
+
+ // Update the properties for the new device
+ updatePCIeDevice(clientAddr, bus, dev);
+
+ iface->initialize();
+}
+
+static void removePCIeDevice(sdbusplus::asio::object_server& objServer,
+ const int& clientAddr, const int& bus,
+ const int& dev)
+{
+ std::shared_ptr<sdbusplus::asio::dbus_interface> iface =
+ peci_pcie::pcieDeviceDBusMap[clientAddr][bus][dev];
+
+ objServer.remove_interface(iface);
+
+ peci_pcie::pcieDeviceDBusMap[clientAddr][bus].erase(dev);
+ if (peci_pcie::pcieDeviceDBusMap[clientAddr][bus].empty())
+ {
+ peci_pcie::pcieDeviceDBusMap[clientAddr].erase(bus);
+ }
+ if (peci_pcie::pcieDeviceDBusMap[clientAddr].empty())
+ {
+ peci_pcie::pcieDeviceDBusMap.erase(clientAddr);
+ }
+}
+
+static bool pcieDeviceInDBusMap(const int& clientAddr, const int& bus,
+ const int& dev)
+{
+ if (auto clientAddrIt = peci_pcie::pcieDeviceDBusMap.find(clientAddr);
+ clientAddrIt != peci_pcie::pcieDeviceDBusMap.end())
+ {
+ if (auto busIt = clientAddrIt->second.find(bus);
+ busIt != clientAddrIt->second.end())
+ {
+ if (auto devIt = busIt->second.find(dev);
+ devIt != busIt->second.end())
+ {
+ if (devIt->second)
+ {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+static void scanPCIeDevice(boost::asio::io_service& io,
+ sdbusplus::asio::object_server& objServer,
+ std::vector<int> clientAddrs, int cpu, int bus,
+ int dev)
+{
+ if (pcieDeviceExists(clientAddrs[cpu], bus, dev))
+ {
+ if (pcieDeviceInDBusMap(clientAddrs[cpu], bus, dev))
+ {
+ // This device is already in D-Bus, so update it
+ updatePCIeDevice(clientAddrs[cpu], bus, dev);
+ }
+ else
+ {
+ // This device is not in D-Bus, so add it
+ addPCIeDevice(objServer, clientAddrs[cpu], cpu, bus, dev);
+ }
+ }
+ else
+ {
+ // If PECI is not available, then stop scanning
+ if (!isPECIAvailable())
+ {
+ return;
+ }
+
+ if (pcieDeviceInDBusMap(clientAddrs[cpu], bus, dev))
+ {
+ // This device is in D-Bus, so remove it
+ removePCIeDevice(objServer, clientAddrs[cpu], bus, dev);
+ }
+ }
+
+ // PCIe Device scan completed, so move to the next device
+ if (++dev >= peci_pcie::maxPCIDevices)
+ {
+ // All devices scanned, so move to the next bus
+ dev = 0;
+ if (++bus >= peci_pcie::maxPCIBuses)
+ {
+ // All buses scanned, so move to the next CPU
+ bus = 0;
+ if (++cpu >= clientAddrs.size())
+ {
+ // All CPUs scanned, so we're done
+ return;
+ }
+ }
+ }
+ boost::asio::post(io, [&io, &objServer, clientAddrs, cpu, bus, dev]() {
+ scanPCIeDevice(io, objServer, clientAddrs, cpu, bus, dev);
+ });
+}
+
+static void peciAvailableCheck(boost::asio::steady_timer& peciWaitTimer,
+ boost::asio::io_service& io,
+ sdbusplus::asio::object_server& objServer)
+{
+ static bool lastPECIState;
+ bool peciAvailable = isPECIAvailable();
+ if (peciAvailable && !lastPECIState)
+ {
+ lastPECIState = true;
+
+ static boost::asio::steady_timer pcieTimeout(io);
+ constexpr const int pcieWaitTime = 60;
+ pcieTimeout.expires_after(std::chrono::seconds(pcieWaitTime));
+ pcieTimeout.async_wait(
+ [&io, &objServer](const boost::system::error_code& ec) {
+ if (ec)
+ {
+ // operation_aborted is expected if timer is canceled
+ // before completion.
+ if (ec != boost::asio::error::operation_aborted)
+ {
+ std::cerr << "PECI PCIe async_wait failed " << ec;
+ }
+ return;
+ }
+ // get the PECI client address list
+ std::vector<int> clientAddrs;
+ getClientAddrMap(clientAddrs);
+ // scan PCIe starting from CPU 0, Bus 0, Device 0
+ scanPCIeDevice(io, objServer, clientAddrs, 0, 0, 0);
+ });
+ }
+ else if (!peciAvailable && lastPECIState)
+ {
+ lastPECIState = false;
+ }
+
+ peciWaitTimer.expires_after(
+ std::chrono::seconds(peci_pcie::peciCheckInterval));
+ peciWaitTimer.async_wait([&peciWaitTimer, &io,
+ &objServer](const boost::system::error_code& ec) {
+ if (ec)
+ {
+ // operation_aborted is expected if timer is canceled
+ // before completion.
+ if (ec != boost::asio::error::operation_aborted)
+ {
+ std::cerr << "PECI Available Check async_wait failed " << ec;
+ }
+ return;
+ }
+ peciAvailableCheck(peciWaitTimer, io, objServer);
+ });
+}
+
+int main(int argc, char* argv[])
+{
+ // setup connection to dbus
+ boost::asio::io_service io;
+ std::shared_ptr<sdbusplus::asio::connection> conn =
+ std::make_shared<sdbusplus::asio::connection>(io);
+
+ // PECI PCIe Object
+ conn->request_name(peci_pcie::peciPCIeObject);
+ sdbusplus::asio::object_server server =
+ sdbusplus::asio::object_server(conn);
+
+ // Start the PECI check loop
+ boost::asio::steady_timer peciWaitTimer(
+ io, std::chrono::seconds(peci_pcie::peciCheckInterval));
+ peciWaitTimer.async_wait([&peciWaitTimer, &io,
+ &server](const boost::system::error_code& ec) {
+ if (ec)
+ {
+ // operation_aborted is expected if timer is canceled
+ // before completion.
+ if (ec != boost::asio::error::operation_aborted)
+ {
+ std::cerr << "PECI Available Check async_wait failed " << ec;
+ }
+ return;
+ }
+ peciAvailableCheck(peciWaitTimer, io, server);
+ });
+
+ io.run();
+
+ return 0;
+}
diff --git a/utils/GetPCI-SIGVendorIDMap.py b/utils/GetPCI-SIGVendorIDMap.py
new file mode 100644
index 0000000..1a8132f
--- /dev/null
+++ b/utils/GetPCI-SIGVendorIDMap.py
@@ -0,0 +1,56 @@
+#!/usr/bin/python3
+import sys
+import requests
+import re
+import argparse
+from bs4 import BeautifulSoup
+
+
+def parse_args(argv):
+ """Parse the command-line arguments"""
+ parser = argparse.ArgumentParser(description='Get the PCI-SIG Vendor IDs')
+ parser.add_argument('--http-proxy', action='store', help="HTTP Proxy Address")
+ parser.add_argument('--https-proxy', action='store', help="HTTPS Proxy Address")
+ args = parser.parse_args(argv)
+ return args
+
+
+def main(argv):
+ """Go to the PCI-SIG members page and construct a
+ dictionary of member companies to their Vendor IDs"""
+ args = parse_args(argv)
+
+ proxyDict = {
+ "http": args.http_proxy,
+ "https": args.https_proxy
+ }
+ page = 'https://pcisig.com/membership/member-companies'
+ pciVendorIDs = {}
+ while True:
+ r = requests.get(page, proxies=proxyDict)
+ soup = BeautifulSoup(r.text)
+
+ for row in soup.table.tbody.find_all("tr"):
+ fields = row.find_all("td")
+ vendorID = fields[1].text.strip()
+ if 'hex' in vendorID.lower():
+ match = re.match(r'\w+ \((\w+) hex\)', vendorID, re.I)
+ if match is not None:
+ vendorID = match.group(1)
+ else:
+ vendorID = ''
+ if vendorID != '':
+ vendorName = fields[0].text.replace('"', '').strip()
+ pciVendorIDs[vendorName] = vendorID
+
+ page = soup.find("a", title="Go to next page")
+ if page is None:
+ break
+ page = 'https://pcisig.com' + page["href"]
+
+ for name, vid in sorted(pciVendorIDs.items(), key=lambda x: x[0].lower()):
+ print("{{0x{}, \"{}\"}},".format(vid, name))
+
+
+if __name__ == '__main__':
+ main(sys.argv[1:])