diff --git a/level_zero/tools/source/sysman/firmware/firmware.cpp b/level_zero/tools/source/sysman/firmware/firmware.cpp index 62e6f952c8..65eb0cdcf7 100644 --- a/level_zero/tools/source/sysman/firmware/firmware.cpp +++ b/level_zero/tools/source/sysman/firmware/firmware.cpp @@ -1,18 +1,16 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * */ -#include "firmware.h" - #include "shared/source/helpers/basic_math.h" -#include "firmware_imp.h" +#include "level_zero/tools/source/sysman/firmware/firmware_imp.h" namespace L0 { - +class OsFirmware; FirmwareHandleContext::~FirmwareHandleContext() { for (Firmware *pFirmware : handleList) { delete pFirmware; @@ -20,8 +18,8 @@ FirmwareHandleContext::~FirmwareHandleContext() { handleList.clear(); } -void FirmwareHandleContext::init() { - Firmware *pFirmware = new FirmwareImp(pOsSysman); +void FirmwareHandleContext::createHandle(const std::string &fwType) { + Firmware *pFirmware = new FirmwareImp(pOsSysman, fwType); if (pFirmware->isFirmwareEnabled == true) { handleList.push_back(pFirmware); } else { @@ -29,6 +27,14 @@ void FirmwareHandleContext::init() { } } +void FirmwareHandleContext::init() { + std::vector supportedFwTypes = {}; + OsFirmware::getSupportedFwTypes(supportedFwTypes, pOsSysman); + for (const std::string &fwType : supportedFwTypes) { + createHandle(fwType); + } +} + ze_result_t FirmwareHandleContext::firmwareGet(uint32_t *pCount, zes_firmware_handle_t *phFirmware) { uint32_t handleListSize = static_cast(handleList.size()); uint32_t numToCopy = std::min(*pCount, handleListSize); diff --git a/level_zero/tools/source/sysman/firmware/firmware.h b/level_zero/tools/source/sysman/firmware/firmware.h index 5b8a18d4e8..c9102d4906 100644 --- a/level_zero/tools/source/sysman/firmware/firmware.h +++ b/level_zero/tools/source/sysman/firmware/firmware.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include struct _zes_firmware_handle_t { @@ -42,6 +43,9 @@ struct FirmwareHandleContext { OsSysman *pOsSysman = nullptr; std::vector handleList = {}; + + private: + void createHandle(const std::string &fwType); }; } // namespace L0 diff --git a/level_zero/tools/source/sysman/firmware/firmware_imp.cpp b/level_zero/tools/source/sysman/firmware/firmware_imp.cpp index a2fb668833..576cb8992b 100644 --- a/level_zero/tools/source/sysman/firmware/firmware_imp.cpp +++ b/level_zero/tools/source/sysman/firmware/firmware_imp.cpp @@ -17,6 +17,7 @@ namespace L0 { ze_result_t FirmwareImp::firmwareGetProperties(zes_firmware_properties_t *pProperties) { pOsFirmware->osGetFwProperties(pProperties); + strncpy_s(pProperties->name, ZES_STRING_PROPERTY_SIZE, fwType.c_str(), fwType.size()); return ZE_RESULT_SUCCESS; } @@ -28,17 +29,14 @@ void FirmwareImp::init() { this->isFirmwareEnabled = pOsFirmware->isFirmwareSupported(); } -FirmwareImp::FirmwareImp(OsSysman *pOsSysman) { - pOsFirmware = OsFirmware::create(pOsSysman); +FirmwareImp::FirmwareImp(OsSysman *pOsSysman, const std::string &initalizedFwType) { + pOsFirmware = OsFirmware::create(pOsSysman, initalizedFwType); + fwType = initalizedFwType; UNRECOVERABLE_IF(nullptr == pOsFirmware); init(); } FirmwareImp::~FirmwareImp() { - if (pOsFirmware != nullptr) { - delete pOsFirmware; - pOsFirmware = nullptr; - } } } // namespace L0 diff --git a/level_zero/tools/source/sysman/firmware/firmware_imp.h b/level_zero/tools/source/sysman/firmware/firmware_imp.h index 0e4467bda1..cd243c66b2 100644 --- a/level_zero/tools/source/sysman/firmware/firmware_imp.h +++ b/level_zero/tools/source/sysman/firmware/firmware_imp.h @@ -7,11 +7,12 @@ #pragma once #include "shared/source/helpers/non_copyable_or_moveable.h" +#include "shared/source/helpers/string.h" +#include "level_zero/tools/source/sysman/firmware/firmware.h" +#include "level_zero/tools/source/sysman/firmware/os_firmware.h" #include -#include "firmware.h" - namespace L0 { class OsFirmware; @@ -21,9 +22,10 @@ class FirmwareImp : public Firmware, NEO::NonCopyableOrMovableClass { ze_result_t firmwareGetProperties(zes_firmware_properties_t *pProperties) override; ze_result_t firmwareFlash(void *pImage, uint32_t size) override; FirmwareImp() = default; - FirmwareImp(OsSysman *pOsSysman); + FirmwareImp(OsSysman *pOsSysman, const std::string &fwType); ~FirmwareImp() override; - OsFirmware *pOsFirmware = nullptr; + std::unique_ptr pOsFirmware = nullptr; + std::string fwType = "Unknown"; void init(); }; diff --git a/level_zero/tools/source/sysman/firmware/linux/os_firmware_imp.cpp b/level_zero/tools/source/sysman/firmware/linux/os_firmware_imp.cpp index b128684f1a..2599736e45 100644 --- a/level_zero/tools/source/sysman/firmware/linux/os_firmware_imp.cpp +++ b/level_zero/tools/source/sysman/firmware/linux/os_firmware_imp.cpp @@ -11,41 +11,77 @@ namespace L0 { -bool LinuxFirmwareImp::isFirmwareSupported(void) { - if (pFwInterface != nullptr) { - isFWInitalized = ((ZE_RESULT_SUCCESS == pFwInterface->fwDeviceInit()) ? true : false); +static const std::string mtdDescriptor("/proc/mtd"); + +std::vector deviceSupportedFwTypes = {"GSC", "OptionROM"}; + +ze_result_t OsFirmware::getSupportedFwTypes(std::vector &supportedFwTypes, OsSysman *pOsSysman) { + LinuxSysmanImp *pLinuxSysmanImp = static_cast(pOsSysman); + + FsAccess *pFsAccess = &pLinuxSysmanImp->getFsAccess(); + std::vector mtdDescriptorStrings; + ze_result_t result = pFsAccess->read(mtdDescriptor, mtdDescriptorStrings); + if (result != ZE_RESULT_SUCCESS) { + return result; } - return isFWInitalized; + for (std::string readByteLine : mtdDescriptorStrings) { + for (std::string fwType : deviceSupportedFwTypes) { + if (std::string::npos != readByteLine.find(fwType)) { + supportedFwTypes.push_back(fwType); + } + } + } + return ZE_RESULT_SUCCESS; +} +bool LinuxFirmwareImp::isFirmwareSupported(void) { + isFWInitalized = ((ZE_RESULT_SUCCESS == pFwInterface->fwDeviceInit()) ? true : false); + return this->isFWInitalized; } void LinuxFirmwareImp::osGetFwProperties(zes_firmware_properties_t *pProperties) { - if (isFWInitalized) { - getFirmwareVersion(pProperties->name); + if (osFwType == deviceSupportedFwTypes[0]) { //GSC getFirmwareVersion(pProperties->version); - } else { - strncpy_s(pProperties->name, ZES_STRING_PROPERTY_SIZE, unknown.c_str(), ZES_STRING_PROPERTY_SIZE); - strncpy_s(pProperties->version, ZES_STRING_PROPERTY_SIZE, unknown.c_str(), ZES_STRING_PROPERTY_SIZE); + } + if (osFwType == deviceSupportedFwTypes[1]) { //oprom + getOpromVersion(pProperties->version); } } - ze_result_t LinuxFirmwareImp::osFirmwareFlash(void *pImage, uint32_t size) { - return pFwInterface->fwFlashGSC(pImage, size); + if (osFwType == deviceSupportedFwTypes[0]) { //GSC + return pFwInterface->fwFlashGSC(pImage, size); + } + if (osFwType == deviceSupportedFwTypes[1]) { //oprom + return pFwInterface->fwFlashOprom(pImage, size); + } + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; } void LinuxFirmwareImp::getFirmwareVersion(char *firmwareVersion) { std::string fwVersion; - pFwInterface->fwGetVersion(fwVersion); - strncpy_s(firmwareVersion, ZES_STRING_PROPERTY_SIZE, fwVersion.c_str(), ZES_STRING_PROPERTY_SIZE); + if (ZE_RESULT_SUCCESS == pFwInterface->fwGetVersion(fwVersion)) { + strncpy_s(firmwareVersion, ZES_STRING_PROPERTY_SIZE, fwVersion.c_str(), ZES_STRING_PROPERTY_SIZE); + } else { + strncpy_s(firmwareVersion, ZES_STRING_PROPERTY_SIZE, unknown.c_str(), ZES_STRING_PROPERTY_SIZE); + } } -LinuxFirmwareImp::LinuxFirmwareImp(OsSysman *pOsSysman) { +void LinuxFirmwareImp::getOpromVersion(char *firmwareVersion) { + std::string fwVersion; + if (ZE_RESULT_SUCCESS == pFwInterface->opromGetVersion(fwVersion)) { + strncpy_s(firmwareVersion, ZES_STRING_PROPERTY_SIZE, fwVersion.c_str(), ZES_STRING_PROPERTY_SIZE); + } else { + strncpy_s(firmwareVersion, ZES_STRING_PROPERTY_SIZE, unknown.c_str(), ZES_STRING_PROPERTY_SIZE); + } +} + +LinuxFirmwareImp::LinuxFirmwareImp(OsSysman *pOsSysman, const std::string &fwType) : osFwType(fwType) { LinuxSysmanImp *pLinuxSysmanImp = static_cast(pOsSysman); pFwInterface = pLinuxSysmanImp->getFwUtilInterface(); } -OsFirmware *OsFirmware::create(OsSysman *pOsSysman) { - LinuxFirmwareImp *pLinuxFirmwareImp = new LinuxFirmwareImp(pOsSysman); - return static_cast(pLinuxFirmwareImp); +std::unique_ptr OsFirmware::create(OsSysman *pOsSysman, const std::string &fwType) { + std::unique_ptr pLinuxFirmwareImp = std::make_unique(pOsSysman, fwType); + return pLinuxFirmwareImp; } } // namespace L0 diff --git a/level_zero/tools/source/sysman/firmware/linux/os_firmware_imp.h b/level_zero/tools/source/sysman/firmware/linux/os_firmware_imp.h index 659c38e0ad..f7406c16f3 100644 --- a/level_zero/tools/source/sysman/firmware/linux/os_firmware_imp.h +++ b/level_zero/tools/source/sysman/firmware/linux/os_firmware_imp.h @@ -20,15 +20,17 @@ class LinuxFirmwareImp : public OsFirmware, NEO::NonCopyableOrMovableClass { void osGetFwProperties(zes_firmware_properties_t *pProperties) override; ze_result_t osFirmwareFlash(void *pImage, uint32_t size) override; LinuxFirmwareImp() = default; - LinuxFirmwareImp(OsSysman *pOsSysman); + LinuxFirmwareImp(OsSysman *pOsSysman, const std::string &fwType); ~LinuxFirmwareImp() override = default; protected: FirmwareUtil *pFwInterface = nullptr; bool isFWInitalized = false; + std::string osFwType; private: void getFirmwareVersion(char *); + void getOpromVersion(char *); }; } // namespace L0 diff --git a/level_zero/tools/source/sysman/firmware/os_firmware.h b/level_zero/tools/source/sysman/firmware/os_firmware.h index 3d73573bc6..4ad42f7124 100644 --- a/level_zero/tools/source/sysman/firmware/os_firmware.h +++ b/level_zero/tools/source/sysman/firmware/os_firmware.h @@ -10,6 +10,10 @@ #include "level_zero/tools/source/sysman/os_sysman.h" #include +#include +#include +#include + namespace L0 { class OsFirmware { @@ -17,7 +21,8 @@ class OsFirmware { virtual bool isFirmwareSupported(void) = 0; virtual void osGetFwProperties(zes_firmware_properties_t *pProperties) = 0; virtual ze_result_t osFirmwareFlash(void *pImage, uint32_t size) = 0; - static OsFirmware *create(OsSysman *pOsSysman); + static std::unique_ptr create(OsSysman *pOsSysman, const std::string &fwType); + static ze_result_t getSupportedFwTypes(std::vector &supportedFwTypes, OsSysman *pOsSysman); virtual ~OsFirmware() {} }; diff --git a/level_zero/tools/source/sysman/firmware/windows/os_firmware_imp.cpp b/level_zero/tools/source/sysman/firmware/windows/os_firmware_imp.cpp index 5d1986deca..ea5b1bcbcc 100644 --- a/level_zero/tools/source/sysman/firmware/windows/os_firmware_imp.cpp +++ b/level_zero/tools/source/sysman/firmware/windows/os_firmware_imp.cpp @@ -18,9 +18,13 @@ ze_result_t WddmFirmwareImp::osFirmwareFlash(void *pImage, uint32_t size) { return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; }; -OsFirmware *OsFirmware::create(OsSysman *pOsSysman) { - WddmFirmwareImp *pWddmFirmwareImp = new WddmFirmwareImp(); - return static_cast(pWddmFirmwareImp); +std::unique_ptr OsFirmware::create(OsSysman *pOsSysman, const std::string &fwType) { + std::unique_ptr pWddmFirmwareImp = std::make_unique(); + return pWddmFirmwareImp; +} + +ze_result_t OsFirmware::getSupportedFwTypes(std::vector &supportedFwTypes, OsSysman *pOsSysman) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; } } // namespace L0 diff --git a/level_zero/tools/source/sysman/linux/firmware_util/firmware_util.h b/level_zero/tools/source/sysman/linux/firmware_util/firmware_util.h index c7c4cbb028..a8fc679a8a 100644 --- a/level_zero/tools/source/sysman/linux/firmware_util/firmware_util.h +++ b/level_zero/tools/source/sysman/linux/firmware_util/firmware_util.h @@ -27,7 +27,9 @@ class FirmwareUtil { virtual ze_result_t fwDeviceInit() = 0; virtual ze_result_t getFirstDevice(igsc_device_info *) = 0; virtual ze_result_t fwGetVersion(std::string &fwVersion) = 0; + virtual ze_result_t opromGetVersion(std::string &fwVersion) = 0; virtual ze_result_t fwFlashGSC(void *pImage, uint32_t size) = 0; + virtual ze_result_t fwFlashOprom(void *pImage, uint32_t size) = 0; virtual ~FirmwareUtil() = default; }; } // namespace L0 diff --git a/level_zero/tools/source/sysman/linux/firmware_util/firmware_util_imp.cpp b/level_zero/tools/source/sysman/linux/firmware_util/firmware_util_imp.cpp index 84b66945a2..b8b7ce07de 100644 --- a/level_zero/tools/source/sysman/linux/firmware_util/firmware_util_imp.cpp +++ b/level_zero/tools/source/sysman/linux/firmware_util/firmware_util_imp.cpp @@ -16,6 +16,10 @@ const std::string FirmwareUtilImp::fwDeviceIteratorCreate = "igsc_device_iterato const std::string FirmwareUtilImp::fwDeviceIteratorNext = "igsc_device_iterator_next"; const std::string FirmwareUtilImp::fwDeviceIteratorDestroy = "igsc_device_iterator_destroy"; const std::string FirmwareUtilImp::fwDeviceFwUpdate = "igsc_device_fw_update"; +const std::string FirmwareUtilImp::fwImageOpromInit = "igsc_image_oprom_init"; +const std::string FirmwareUtilImp::fwImageOpromType = "igsc_image_oprom_type"; +const std::string FirmwareUtilImp::fwDeviceOpromUpdate = "igsc_device_oprom_update"; +const std::string FirmwareUtilImp::fwDeviceOpromVersion = "igsc_device_oprom_version"; template bool FirmwareUtilImp::getSymbolAddr(const std::string name, T &proc) { @@ -32,6 +36,10 @@ bool FirmwareUtilImp::loadEntryPoints() { ok = ok && getSymbolAddr(fwDeviceIteratorNext, deviceItreatorNext); ok = ok && getSymbolAddr(fwDeviceIteratorDestroy, deviceItreatorDestroy); ok = ok && getSymbolAddr(fwDeviceFwUpdate, deviceFwUpdate); + ok = ok && getSymbolAddr(fwImageOpromInit, imageOpromInit); + ok = ok && getSymbolAddr(fwImageOpromType, imageOpromType); + ok = ok && getSymbolAddr(fwDeviceOpromUpdate, deviceOpromUpdate); + ok = ok && getSymbolAddr(fwDeviceOpromVersion, deviceOpromVersion); return ok; } @@ -90,6 +98,30 @@ ze_result_t FirmwareUtilImp::fwGetVersion(std::string &fwVersion) { return ZE_RESULT_SUCCESS; } +ze_result_t FirmwareUtilImp::opromGetVersion(std::string &fwVersion) { + igsc_oprom_version opromVersion; + memset(&opromVersion, 0, sizeof(opromVersion)); + int ret = deviceOpromVersion(&fwDeviceHandle, IGSC_OPROM_CODE, &opromVersion); + if (ret != IGSC_SUCCESS) { + return ZE_RESULT_ERROR_UNINITIALIZED; + } + fwVersion.append("OPROM CODE VERSION:"); + for (int i = 0; i < IGSC_OPROM_VER_SIZE; i++) { + fwVersion.append(std::to_string(static_cast(opromVersion.version[i]))); + } + fwVersion.append("_"); + memset(&opromVersion, 0, sizeof(opromVersion)); + ret = deviceOpromVersion(&fwDeviceHandle, IGSC_OPROM_DATA, &opromVersion); + if (ret != IGSC_SUCCESS) { + return ZE_RESULT_ERROR_UNINITIALIZED; + } + fwVersion.append("OPROM DATA VERSION:"); + for (int i = 0; i < IGSC_OPROM_VER_SIZE; i++) { + fwVersion.append(std::to_string(static_cast(opromVersion.version[i]))); + } + return ZE_RESULT_SUCCESS; +} + ze_result_t FirmwareUtilImp::fwFlashGSC(void *pImage, uint32_t size) { int ret = deviceFwUpdate(&fwDeviceHandle, static_cast(pImage), size, progressFunc, nullptr); if (ret != IGSC_SUCCESS) { @@ -97,6 +129,31 @@ ze_result_t FirmwareUtilImp::fwFlashGSC(void *pImage, uint32_t size) { } return ZE_RESULT_SUCCESS; } + +ze_result_t FirmwareUtilImp::fwFlashOprom(void *pImage, uint32_t size) { + struct igsc_oprom_image *opromImg = nullptr; + uint32_t opromImgType = 0; + int retData = 0, retCode = 0; + int ret = imageOpromInit(&opromImg, static_cast(pImage), size); + if (ret != IGSC_SUCCESS) { + return ZE_RESULT_ERROR_UNINITIALIZED; + } + ret = imageOpromType(opromImg, &opromImgType); + if (ret != IGSC_SUCCESS) { + return ZE_RESULT_ERROR_UNINITIALIZED; + } + if (opromImgType & IGSC_OPROM_DATA) { + retData = deviceOpromUpdate(&fwDeviceHandle, IGSC_OPROM_DATA, opromImg, progressFunc, nullptr); + } + if (opromImgType & IGSC_OPROM_CODE) { + retCode = deviceOpromUpdate(&fwDeviceHandle, IGSC_OPROM_CODE, opromImg, progressFunc, nullptr); + } + if ((retData != IGSC_SUCCESS) && (retCode != IGSC_SUCCESS)) { + return ZE_RESULT_ERROR_UNINITIALIZED; + } + return ZE_RESULT_SUCCESS; +} + FirmwareUtilImp::FirmwareUtilImp(){}; FirmwareUtilImp::~FirmwareUtilImp() { diff --git a/level_zero/tools/source/sysman/linux/firmware_util/firmware_util_imp.h b/level_zero/tools/source/sysman/linux/firmware_util/firmware_util_imp.h index 7dc33d73ff..1cefa8830e 100644 --- a/level_zero/tools/source/sysman/linux/firmware_util/firmware_util_imp.h +++ b/level_zero/tools/source/sysman/linux/firmware_util/firmware_util_imp.h @@ -26,7 +26,24 @@ typedef int (*pIgscDeviceIteratorCreate)(struct igsc_device_iterator **iter); typedef int (*pIgscDeviceIteratorNext)(struct igsc_device_iterator *iter, struct igsc_device_info *info); typedef void (*pIgscDeviceIteratorDestroy)(struct igsc_device_iterator *iter); -typedef int (*pIgscDeviceFwUpdate)(struct igsc_device_handle *handle, const uint8_t *buffer, const uint32_t buffer_len, igsc_progress_func_t progress_f, void *ctx); +typedef int (*pIgscDeviceFwUpdate)(struct igsc_device_handle *handle, + const uint8_t *buffer, + const uint32_t buffer_len, + igsc_progress_func_t progress_f, + void *ctx); +typedef int (*pIgscImageOpromInit)(struct igsc_oprom_image **img, + const uint8_t *buffer, + uint32_t buffer_len); +typedef int (*pIgscImageOpromType)(struct igsc_oprom_image *img, + uint32_t *oprom_type); +typedef int (*pIgscDeviceOpromUpdate)(struct igsc_device_handle *handle, + uint32_t oprom_type, + struct igsc_oprom_image *img, + igsc_progress_func_t progress_f, + void *ctx); +typedef int (*pIgscDeviceOpromVersion)(struct igsc_device_handle *handle, + uint32_t oprom_type, + struct igsc_oprom_version *version); class FirmwareUtilImp : public FirmwareUtil, NEO::NonCopyableOrMovableClass { public: @@ -35,7 +52,9 @@ class FirmwareUtilImp : public FirmwareUtil, NEO::NonCopyableOrMovableClass { ze_result_t fwDeviceInit() override; ze_result_t getFirstDevice(igsc_device_info *) override; ze_result_t fwGetVersion(std::string &fwVersion) override; + ze_result_t opromGetVersion(std::string &fwVersion) override; ze_result_t fwFlashGSC(void *pImage, uint32_t size) override; + ze_result_t fwFlashOprom(void *pImage, uint32_t size) override; template bool getSymbolAddr(const std::string name, T &proc); @@ -53,6 +72,10 @@ class FirmwareUtilImp : public FirmwareUtil, NEO::NonCopyableOrMovableClass { static const std::string fwDeviceIteratorNext; static const std::string fwDeviceIteratorDestroy; static const std::string fwDeviceFwUpdate; + static const std::string fwImageOpromInit; + static const std::string fwImageOpromType; + static const std::string fwDeviceOpromUpdate; + static const std::string fwDeviceOpromVersion; pIgscDeviceInitByDevice deviceInitByDevice = nullptr; pIgscDeviceGetDeviceInfo deviceGetDeviceInfo = nullptr; @@ -61,5 +84,9 @@ class FirmwareUtilImp : public FirmwareUtil, NEO::NonCopyableOrMovableClass { pIgscDeviceIteratorNext deviceItreatorNext = nullptr; pIgscDeviceIteratorDestroy deviceItreatorDestroy = nullptr; pIgscDeviceFwUpdate deviceFwUpdate = nullptr; + pIgscImageOpromInit imageOpromInit = nullptr; + pIgscImageOpromType imageOpromType = nullptr; + pIgscDeviceOpromUpdate deviceOpromUpdate = nullptr; + pIgscDeviceOpromVersion deviceOpromVersion = nullptr; }; } // namespace L0 \ No newline at end of file diff --git a/level_zero/tools/test/unit_tests/sources/sysman/firmware/linux/mock_zes_sysman_firmware.h b/level_zero/tools/test/unit_tests/sources/sysman/firmware/linux/mock_zes_sysman_firmware.h index 15f55f1a62..92cffd99d0 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/firmware/linux/mock_zes_sysman_firmware.h +++ b/level_zero/tools/test/unit_tests/sources/sysman/firmware/linux/mock_zes_sysman_firmware.h @@ -13,10 +13,28 @@ namespace L0 { namespace ult { -constexpr uint32_t mockHandleCount = 1; +constexpr uint32_t mockHandleCount = 2; const std::string mockFwVersion("DG01->0->2026"); - +const std::string mockOpromVersion("OPROM CODE VERSION:123_OPROM DATA VERSION:456"); +std::vector mockSupportedFwTypes = {"GSC", "OptionROM"}; +std::vector mockUnsupportedFwTypes = {"unknown"}; +std::string mockEmpty = {}; class FirmwareInterface : public FirmwareUtil {}; +class FirmwareFsAccess : public FsAccess {}; + +template <> +struct Mock : public FirmwareFsAccess { + MOCK_METHOD(ze_result_t, read, (const std::string file, std::vector &val), (override)); + ze_result_t readValSuccess(const std::string file, std::vector &val) { + val.push_back("mtd3: 005ef000 00001000 \"i915-spi.42.auto.GSC\""); + val.push_back("mtd5: 00200000 00001000 \"i915-spi.42.auto.OptionROM\""); + return ZE_RESULT_SUCCESS; + } + ze_result_t readValFailure(const std::string file, std::vector &val) { + return ZE_RESULT_ERROR_NOT_AVAILABLE; + } +}; + template <> struct Mock : public FirmwareUtil { @@ -30,18 +48,28 @@ struct Mock : public FirmwareUtil { fwVersion = mockFwVersion; return ZE_RESULT_SUCCESS; } + ze_result_t mockOpromGetVersion(std::string &fwVersion) { + fwVersion = mockOpromVersion; + return ZE_RESULT_SUCCESS; + } ze_result_t mockGetFirstDevice(igsc_device_info *info) { return ZE_RESULT_SUCCESS; } - ze_result_t mockFwFlashGSC(void *pImage, uint32_t size) { + ze_result_t mockFwFlash(void *pImage, uint32_t size) { return ZE_RESULT_SUCCESS; } + ze_result_t mockFwGetVersionFailed(std::string &fwVersion) { + return ZE_RESULT_ERROR_UNINITIALIZED; + } + Mock() = default; MOCK_METHOD(ze_result_t, fwDeviceInit, (), (override)); MOCK_METHOD(ze_result_t, fwGetVersion, (std::string & fwVersion), (override)); + MOCK_METHOD(ze_result_t, opromGetVersion, (std::string & fwVersion), (override)); MOCK_METHOD(ze_result_t, getFirstDevice, (igsc_device_info * info), (override)); MOCK_METHOD(ze_result_t, fwFlashGSC, (void *pImage, uint32_t size), (override)); + MOCK_METHOD(ze_result_t, fwFlashOprom, (void *pImage, uint32_t size), (override)); }; class PublicLinuxFirmwareImp : public L0::LinuxFirmwareImp { diff --git a/level_zero/tools/test/unit_tests/sources/sysman/firmware/linux/test_zes_sysman_firmware.cpp b/level_zero/tools/test/unit_tests/sources/sysman/firmware/linux/test_zes_sysman_firmware.cpp index 8681b241be..e793458f24 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/firmware/linux/test_zes_sysman_firmware.cpp +++ b/level_zero/tools/test/unit_tests/sources/sysman/firmware/linux/test_zes_sysman_firmware.cpp @@ -16,9 +16,15 @@ class ZesFirmwareFixture : public SysmanDeviceFixture { zes_firmware_handle_t hSysmanFirmware = {}; std::unique_ptr> pMockFwInterface; FirmwareUtil *pFwUtilInterfaceOld = nullptr; + std::unique_ptr> pFsAccess; + FsAccess *pFsAccessOriginal = nullptr; void SetUp() override { SysmanDeviceFixture::SetUp(); + pFsAccessOriginal = pLinuxSysmanImp->pFsAccess; + pFsAccess = std::make_unique>>(); + pLinuxSysmanImp->pFsAccess = pFsAccess.get(); + pFwUtilInterfaceOld = pLinuxSysmanImp->pFwUtilInterface; pMockFwInterface = std::make_unique>>(); pLinuxSysmanImp->pFwUtilInterface = pMockFwInterface.get(); @@ -26,10 +32,16 @@ class ZesFirmwareFixture : public SysmanDeviceFixture { .WillByDefault(::testing::Invoke(pMockFwInterface.get(), &Mock::mockFwDeviceInit)); ON_CALL(*pMockFwInterface.get(), fwGetVersion(_)) .WillByDefault(::testing::Invoke(pMockFwInterface.get(), &Mock::mockFwGetVersion)); + ON_CALL(*pMockFwInterface.get(), opromGetVersion(_)) + .WillByDefault(::testing::Invoke(pMockFwInterface.get(), &Mock::mockOpromGetVersion)); ON_CALL(*pMockFwInterface.get(), getFirstDevice(_)) .WillByDefault(::testing::Invoke(pMockFwInterface.get(), &Mock::mockGetFirstDevice)); ON_CALL(*pMockFwInterface.get(), fwFlashGSC(_, _)) - .WillByDefault(::testing::Invoke(pMockFwInterface.get(), &Mock::mockFwFlashGSC)); + .WillByDefault(::testing::Invoke(pMockFwInterface.get(), &Mock::mockFwFlash)); + ON_CALL(*pMockFwInterface.get(), fwFlashOprom(_, _)) + .WillByDefault(::testing::Invoke(pMockFwInterface.get(), &Mock::mockFwFlash)); + ON_CALL(*pFsAccess.get(), read(_, _)) + .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock::readValSuccess)); for (const auto &handle : pSysmanDeviceImp->pFirmwareHandleContext->handleList) { delete handle; } @@ -39,6 +51,7 @@ class ZesFirmwareFixture : public SysmanDeviceFixture { void TearDown() override { SysmanDeviceFixture::TearDown(); pLinuxSysmanImp->pFwUtilInterface = pFwUtilInterfaceOld; + pLinuxSysmanImp->pFsAccess = pFsAccessOriginal; } std::vector get_firmware_handles(uint32_t count) { @@ -70,7 +83,7 @@ TEST_F(ZesFirmwareFixture, GivenComponentCountZeroWhenCallingzesFirmwareGetThenZ EXPECT_EQ(ZE_RESULT_SUCCESS, result); EXPECT_EQ(count, mockHandleCount); - FirmwareImp *ptestFirmwareImp = new FirmwareImp(pSysmanDeviceImp->pFirmwareHandleContext->pOsSysman); + FirmwareImp *ptestFirmwareImp = new FirmwareImp(pSysmanDeviceImp->pFirmwareHandleContext->pOsSysman, mockSupportedFwTypes[0]); pSysmanDeviceImp->pFirmwareHandleContext->handleList.push_back(ptestFirmwareImp); result = zesDeviceEnumFirmwares(device->toHandle(), &count, nullptr); @@ -91,44 +104,50 @@ TEST_F(ZesFirmwareFixture, GivenComponentCountZeroWhenCallingzesFirmwareGetThenZ } TEST_F(ZesFirmwareFixture, GivenValidFirmwareHandleWhenGettingFirmwarePropertiesThenVersionIsReturned) { - FirmwareImp *ptestFirmwareImp = new FirmwareImp(pSysmanDeviceImp->pFirmwareHandleContext->pOsSysman); + FirmwareImp *ptestFirmwareImp = new FirmwareImp(pSysmanDeviceImp->pFirmwareHandleContext->pOsSysman, mockSupportedFwTypes[0]); pSysmanDeviceImp->pFirmwareHandleContext->handleList.push_back(ptestFirmwareImp); auto handles = get_firmware_handles(mockHandleCount); - for (auto handle : handles) { - zes_firmware_properties_t properties = {}; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesFirmwareGetProperties(handle, &properties)); - EXPECT_STREQ(mockFwVersion.c_str(), properties.name); - EXPECT_STREQ(mockFwVersion.c_str(), properties.version); - } + zes_firmware_properties_t properties = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFirmwareGetProperties(handles[0], &properties)); + EXPECT_STREQ(mockSupportedFwTypes[0].c_str(), properties.name); + EXPECT_STREQ(mockFwVersion.c_str(), properties.version); + pSysmanDeviceImp->pFirmwareHandleContext->handleList.pop_back(); delete ptestFirmwareImp; } -TEST_F(ZesFirmwareFixture, GivenValidFirmwareHandleWhenGettingFirmwarePropertiesThenUnknownIsReturned) { + +TEST_F(ZesFirmwareFixture, GivenValidFirmwareHandleWhenGettingOpromPropertiesThenVersionIsReturned) { + FirmwareImp *ptestFirmwareImp = new FirmwareImp(pSysmanDeviceImp->pFirmwareHandleContext->pOsSysman, mockSupportedFwTypes[1]); + pSysmanDeviceImp->pFirmwareHandleContext->handleList.push_back(ptestFirmwareImp); + + auto handles = get_firmware_handles(mockHandleCount); + + zes_firmware_properties_t properties = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFirmwareGetProperties(handles[1], &properties)); + EXPECT_STREQ(mockSupportedFwTypes[1].c_str(), properties.name); + EXPECT_STREQ(mockOpromVersion.c_str(), properties.version); + + pSysmanDeviceImp->pFirmwareHandleContext->handleList.pop_back(); + delete ptestFirmwareImp; +} + +TEST_F(ZesFirmwareFixture, GivenFailedFirmwareInitializationWhenInitializingFirmwareContextThenexpectNoHandles) { for (const auto &handle : pSysmanDeviceImp->pFirmwareHandleContext->handleList) { delete handle; } pSysmanDeviceImp->pFirmwareHandleContext->handleList.clear(); ON_CALL(*pMockFwInterface.get(), fwDeviceInit()) .WillByDefault(::testing::Invoke(pMockFwInterface.get(), &Mock::mockFwDeviceInitFail)); - FirmwareImp *ptestFirmwareImp = new FirmwareImp(pSysmanDeviceImp->pFirmwareHandleContext->pOsSysman); - pSysmanDeviceImp->pFirmwareHandleContext->handleList.push_back(ptestFirmwareImp); - auto handles = get_firmware_handles(mockHandleCount); + pSysmanDeviceImp->pFirmwareHandleContext->init(); - for (auto handle : handles) { - zes_firmware_properties_t properties = {}; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesFirmwareGetProperties(handle, &properties)); - EXPECT_STREQ("Unknown", properties.name); - EXPECT_STREQ("Unknown", properties.version); - } - pSysmanDeviceImp->pFirmwareHandleContext->handleList.pop_back(); - delete ptestFirmwareImp; + EXPECT_EQ(0u, pSysmanDeviceImp->pFirmwareHandleContext->handleList.size()); } TEST_F(ZesFirmwareFixture, GivenValidFirmwareHandleWhenFlashingGscFirmwareSuccessIsReturned) { - FirmwareImp *ptestFirmwareImp = new FirmwareImp(pSysmanDeviceImp->pFirmwareHandleContext->pOsSysman); + FirmwareImp *ptestFirmwareImp = new FirmwareImp(pSysmanDeviceImp->pFirmwareHandleContext->pOsSysman, mockSupportedFwTypes[0]); pSysmanDeviceImp->pFirmwareHandleContext->handleList.push_back(ptestFirmwareImp); auto handles = get_firmware_handles(mockHandleCount); @@ -141,5 +160,54 @@ TEST_F(ZesFirmwareFixture, GivenValidFirmwareHandleWhenFlashingGscFirmwareSucces delete ptestFirmwareImp; } +TEST_F(ZesFirmwareFixture, GivenValidFirmwareHandleWhenFlashingUnkownFirmwareFailureIsReturned) { + for (const auto &handle : pSysmanDeviceImp->pFirmwareHandleContext->handleList) { + delete handle; + } + pSysmanDeviceImp->pFirmwareHandleContext->handleList.clear(); + FirmwareImp *ptestFirmwareImp = new FirmwareImp(pSysmanDeviceImp->pFirmwareHandleContext->pOsSysman, mockUnsupportedFwTypes[0]); + pSysmanDeviceImp->pFirmwareHandleContext->handleList.push_back(ptestFirmwareImp); + + uint8_t testImage[ZES_STRING_PROPERTY_SIZE] = {}; + memset(testImage, 0xA, ZES_STRING_PROPERTY_SIZE); + auto handle = pSysmanDeviceImp->pFirmwareHandleContext->handleList[0]->toHandle(); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesFirmwareFlash(handle, (void *)testImage, ZES_STRING_PROPERTY_SIZE)); + + pSysmanDeviceImp->pFirmwareHandleContext->handleList.pop_back(); + delete ptestFirmwareImp; +} + +TEST_F(ZesFirmwareFixture, GivenFirmwareInitializationFailureCreateHandleMustFail) { + for (const auto &handle : pSysmanDeviceImp->pFirmwareHandleContext->handleList) { + delete handle; + } + pSysmanDeviceImp->pFirmwareHandleContext->handleList.clear(); + ON_CALL(*pMockFwInterface.get(), fwDeviceInit()) + .WillByDefault(::testing::Invoke(pMockFwInterface.get(), &Mock::mockFwDeviceInitFail)); + pSysmanDeviceImp->pFirmwareHandleContext->init(); + EXPECT_EQ(0u, pSysmanDeviceImp->pFirmwareHandleContext->handleList.size()); +} + +TEST_F(ZesFirmwareFixture, GivenValidFirmwareHandleFirmwareLibraryCallFailureWhenGettingFirmwarePropertiesThenUnknownIsReturned) { + for (const auto &handle : pSysmanDeviceImp->pFirmwareHandleContext->handleList) { + delete handle; + } + pSysmanDeviceImp->pFirmwareHandleContext->handleList.clear(); + ON_CALL(*pMockFwInterface.get(), fwGetVersion(_)) + .WillByDefault(::testing::Invoke(pMockFwInterface.get(), &Mock::mockFwGetVersionFailed)); + ON_CALL(*pMockFwInterface.get(), opromGetVersion(_)) + .WillByDefault(::testing::Invoke(pMockFwInterface.get(), &Mock::mockFwGetVersionFailed)); + pSysmanDeviceImp->pFirmwareHandleContext->init(); + auto handles = get_firmware_handles(mockHandleCount); + + zes_firmware_properties_t properties = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFirmwareGetProperties(handles[0], &properties)); + EXPECT_STREQ(mockSupportedFwTypes[0].c_str(), properties.name); + EXPECT_STREQ("Unknown", properties.version); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFirmwareGetProperties(handles[1], &properties)); + EXPECT_STREQ(mockSupportedFwTypes[1].c_str(), properties.name); + EXPECT_STREQ("Unknown", properties.version); +} } // namespace ult } // namespace L0