diff --git a/level_zero/api/sysman/zes_sysman.cpp b/level_zero/api/sysman/zes_sysman.cpp index 9e1e92150f..17eab8160e 100644 --- a/level_zero/api/sysman/zes_sysman.cpp +++ b/level_zero/api/sysman/zes_sysman.cpp @@ -388,7 +388,7 @@ zesFirmwareFlash( zes_firmware_handle_t hFirmware, void *pImage, uint32_t size) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + return L0::Firmware::fromHandle(hFirmware)->firmwareFlash(pImage, size); } ZE_APIEXPORT ze_result_t ZE_APICALL diff --git a/level_zero/tools/source/sysman/firmware/firmware.h b/level_zero/tools/source/sysman/firmware/firmware.h index f307959bcb..5b8a18d4e8 100644 --- a/level_zero/tools/source/sysman/firmware/firmware.h +++ b/level_zero/tools/source/sysman/firmware/firmware.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -22,6 +22,7 @@ class Firmware : _zes_firmware_handle_t { public: virtual ~Firmware() {} virtual ze_result_t firmwareGetProperties(zes_firmware_properties_t *pProperties) = 0; + virtual ze_result_t firmwareFlash(void *pImage, uint32_t size) = 0; inline zes_firmware_handle_t toHandle() { return this; } diff --git a/level_zero/tools/source/sysman/firmware/firmware_imp.cpp b/level_zero/tools/source/sysman/firmware/firmware_imp.cpp index 6227318bd5..a2fb668833 100644 --- a/level_zero/tools/source/sysman/firmware/firmware_imp.cpp +++ b/level_zero/tools/source/sysman/firmware/firmware_imp.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -20,6 +20,10 @@ ze_result_t FirmwareImp::firmwareGetProperties(zes_firmware_properties_t *pPrope return ZE_RESULT_SUCCESS; } +ze_result_t FirmwareImp::firmwareFlash(void *pImage, uint32_t size) { + return pOsFirmware->osFirmwareFlash(pImage, size); +} + void FirmwareImp::init() { this->isFirmwareEnabled = pOsFirmware->isFirmwareSupported(); } diff --git a/level_zero/tools/source/sysman/firmware/firmware_imp.h b/level_zero/tools/source/sysman/firmware/firmware_imp.h index 7633c0c0c8..0e4467bda1 100644 --- a/level_zero/tools/source/sysman/firmware/firmware_imp.h +++ b/level_zero/tools/source/sysman/firmware/firmware_imp.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -19,6 +19,7 @@ class OsFirmware; class FirmwareImp : public Firmware, NEO::NonCopyableOrMovableClass { public: 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() override; 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 12f8470b44..b128684f1a 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 @@ -27,6 +27,11 @@ void LinuxFirmwareImp::osGetFwProperties(zes_firmware_properties_t *pProperties) strncpy_s(pProperties->version, ZES_STRING_PROPERTY_SIZE, unknown.c_str(), ZES_STRING_PROPERTY_SIZE); } } + +ze_result_t LinuxFirmwareImp::osFirmwareFlash(void *pImage, uint32_t size) { + return pFwInterface->fwFlashGSC(pImage, size); +} + void LinuxFirmwareImp::getFirmwareVersion(char *firmwareVersion) { std::string fwVersion; pFwInterface->fwGetVersion(fwVersion); 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 1732684e18..659c38e0ad 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 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -18,6 +18,7 @@ class LinuxFirmwareImp : public OsFirmware, NEO::NonCopyableOrMovableClass { public: bool isFirmwareSupported(void) override; void osGetFwProperties(zes_firmware_properties_t *pProperties) override; + ze_result_t osFirmwareFlash(void *pImage, uint32_t size) override; LinuxFirmwareImp() = default; LinuxFirmwareImp(OsSysman *pOsSysman); ~LinuxFirmwareImp() override = default; diff --git a/level_zero/tools/source/sysman/firmware/os_firmware.h b/level_zero/tools/source/sysman/firmware/os_firmware.h index 68e8dcf83f..3d73573bc6 100644 --- a/level_zero/tools/source/sysman/firmware/os_firmware.h +++ b/level_zero/tools/source/sysman/firmware/os_firmware.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -16,7 +16,7 @@ class OsFirmware { public: 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); 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 0f2566922e..5d1986deca 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 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -14,6 +14,9 @@ bool WddmFirmwareImp::isFirmwareSupported(void) { } void WddmFirmwareImp::osGetFwProperties(zes_firmware_properties_t *pProperties){}; +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(); diff --git a/level_zero/tools/source/sysman/firmware/windows/os_firmware_imp.h b/level_zero/tools/source/sysman/firmware/windows/os_firmware_imp.h index ed534949ef..85facb50cc 100644 --- a/level_zero/tools/source/sysman/firmware/windows/os_firmware_imp.h +++ b/level_zero/tools/source/sysman/firmware/windows/os_firmware_imp.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -16,6 +16,7 @@ class WddmFirmwareImp : public OsFirmware { public: bool isFirmwareSupported(void) override; void osGetFwProperties(zes_firmware_properties_t *pProperties) override; + ze_result_t osFirmwareFlash(void *pImage, uint32_t size) override; }; } // 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 70fde24cef..c7c4cbb028 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 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -27,6 +27,7 @@ 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 fwFlashGSC(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 cf1babe40b..84b66945a2 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 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -15,6 +15,7 @@ const std::string FirmwareUtilImp::fwDeviceFwVersion = "igsc_device_fw_version"; const std::string FirmwareUtilImp::fwDeviceIteratorCreate = "igsc_device_iterator_create"; 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"; template bool FirmwareUtilImp::getSymbolAddr(const std::string name, T &proc) { @@ -30,9 +31,15 @@ bool FirmwareUtilImp::loadEntryPoints() { ok = ok && getSymbolAddr(fwDeviceIteratorCreate, deviceIteratorCreate); ok = ok && getSymbolAddr(fwDeviceIteratorNext, deviceItreatorNext); ok = ok && getSymbolAddr(fwDeviceIteratorDestroy, deviceItreatorDestroy); + ok = ok && getSymbolAddr(fwDeviceFwUpdate, deviceFwUpdate); return ok; } +static void progressFunc(uint32_t done, uint32_t total, void *ctx) { + uint32_t percent = (done * 100) / total; + PRINT_DEBUG_STRING(NEO::DebugManager.flags.PrintDebugMessages.get(), stdout, "Progess: %d/%d:%d/%\n", done, total, percent); +} + ze_result_t FirmwareUtilImp::getFirstDevice(igsc_device_info *info) { igsc_device_iterator *iter; int ret = deviceIteratorCreate(&iter); @@ -82,6 +89,14 @@ ze_result_t FirmwareUtilImp::fwGetVersion(std::string &fwVersion) { fwVersion.append(std::to_string(deviceFwVersion.build)); 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) { + return ZE_RESULT_ERROR_UNINITIALIZED; + } + return ZE_RESULT_SUCCESS; +} FirmwareUtilImp::FirmwareUtilImp(){}; FirmwareUtilImp::~FirmwareUtilImp() { @@ -106,4 +121,4 @@ FirmwareUtil *FirmwareUtil::create() { return static_cast(pFwUtilImp); } -} // namespace L0 \ No newline at end of file +} // namespace L0 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 bfacc83872..7dc33d73ff 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 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -26,6 +26,7 @@ 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); class FirmwareUtilImp : public FirmwareUtil, NEO::NonCopyableOrMovableClass { public: @@ -34,6 +35,7 @@ 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 fwFlashGSC(void *pImage, uint32_t size) override; template bool getSymbolAddr(const std::string name, T &proc); @@ -50,6 +52,7 @@ class FirmwareUtilImp : public FirmwareUtil, NEO::NonCopyableOrMovableClass { static const std::string fwDeviceIteratorCreate; static const std::string fwDeviceIteratorNext; static const std::string fwDeviceIteratorDestroy; + static const std::string fwDeviceFwUpdate; pIgscDeviceInitByDevice deviceInitByDevice = nullptr; pIgscDeviceGetDeviceInfo deviceGetDeviceInfo = nullptr; @@ -57,5 +60,6 @@ class FirmwareUtilImp : public FirmwareUtil, NEO::NonCopyableOrMovableClass { pIgscDeviceIteratorCreate deviceIteratorCreate = nullptr; pIgscDeviceIteratorNext deviceItreatorNext = nullptr; pIgscDeviceIteratorDestroy deviceItreatorDestroy = nullptr; + pIgscDeviceFwUpdate deviceFwUpdate = nullptr; }; } // namespace L0 \ No newline at end of file diff --git a/level_zero/tools/test/black_box_tests/zello_sysman.cpp b/level_zero/tools/test/black_box_tests/zello_sysman.cpp index b9fc34cea0..2d4cac4ada 100644 --- a/level_zero/tools/test/black_box_tests/zello_sysman.cpp +++ b/level_zero/tools/test/black_box_tests/zello_sysman.cpp @@ -8,10 +8,12 @@ #include #include +#include #include #include #include #include +#include #include #include @@ -92,6 +94,7 @@ void usage() { "\n -R, --ras selectively run ras black box test" "\n -E, --event set and listen to events black box test" "\n -r, --reset force|noforce selectively run device reset test" + "\n -i, --firmware selectively run device firmware test is the firmware binary needed to flash" "\n -h, --help display help message" "\n" "\n All L0 Syman APIs that set values require root privileged execution" @@ -629,10 +632,20 @@ void testSysmanMemory(ze_device_handle_t &device) { } } } -void testSysmanFirmware(ze_device_handle_t &device) { +void testSysmanFirmware(ze_device_handle_t &device, std::string imagePath) { std::cout << std::endl << " ---- firmware tests ---- " << std::endl; uint32_t count = 0; + std::ifstream imageFile; + uint64_t imgSize = 0; + if (imagePath.size() != 0) { + struct stat statBuf; + auto status = stat(imagePath.c_str(), &statBuf); + if (!status) { + imageFile.open(imagePath.c_str(), std::ios::binary); + imgSize = statBuf.st_size; + } + } VALIDATECALL(zesDeviceEnumFirmwares(device, &count, nullptr)); if (count == 0) { std::cout << "Could not retrieve Firmware domains" << std::endl; @@ -651,6 +664,19 @@ void testSysmanFirmware(ze_device_handle_t &device) { std::cout << "Subdevice Id = " << fwProperties.subdeviceId << std::endl; std::cout << "firmware version = " << fwProperties.version << std::endl; } + if (imagePath.size() != 0 && imgSize > 0) { + char img[imgSize]; + imageFile.read(img, imgSize); + VALIDATECALL(zesFirmwareFlash(handle, img, static_cast(imgSize))); + + VALIDATECALL(zesFirmwareGetProperties(handle, &fwProperties)); + if (verbose) { + std::cout << "firmware name = " << fwProperties.name << std::endl; + std::cout << "On Subdevice = " << fwProperties.onSubdevice << std::endl; + std::cout << "Subdevice Id = " << fwProperties.subdeviceId << std::endl; + std::cout << "firmware version = " << fwProperties.version << std::endl; + } + } } } void testSysmanReset(ze_device_handle_t &device, bool force) { @@ -836,6 +862,7 @@ int main(int argc, char *argv[]) { } getDeviceHandles(driver, devices, argc, argv); int opt; + static struct option long_opts[] = { {"help", no_argument, nullptr, 'h'}, {"pci", no_argument, nullptr, 'p'}, @@ -851,7 +878,7 @@ int main(int argc, char *argv[]) { {"event", no_argument, nullptr, 'E'}, {"reset", required_argument, nullptr, 'r'}, {"fabricport", no_argument, nullptr, 'F'}, - {"firmware", no_argument, nullptr, 'i'}, + {"firmware", optional_argument, nullptr, 'i'}, {0, 0, 0, 0}, }; bool force = false; @@ -911,11 +938,14 @@ int main(int argc, char *argv[]) { testSysmanRas(device); }); break; - case 'i': + case 'i': { + std::string filePathFirmware; + filePathFirmware = optarg; std::for_each(devices.begin(), devices.end(), [&](auto device) { - testSysmanFirmware(device); + testSysmanFirmware(device, filePathFirmware); }); break; + } case 'r': if (!strcmp(optarg, "force")) { force = true; 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 9b1d0da891..15f55f1a62 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 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -33,11 +33,15 @@ struct Mock : public FirmwareUtil { ze_result_t mockGetFirstDevice(igsc_device_info *info) { return ZE_RESULT_SUCCESS; } + ze_result_t mockFwFlashGSC(void *pImage, uint32_t size) { + return ZE_RESULT_SUCCESS; + } Mock() = default; MOCK_METHOD(ze_result_t, fwDeviceInit, (), (override)); MOCK_METHOD(ze_result_t, fwGetVersion, (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)); }; 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 d7c8b6db63..8681b241be 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 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -28,6 +28,8 @@ class ZesFirmwareFixture : public SysmanDeviceFixture { .WillByDefault(::testing::Invoke(pMockFwInterface.get(), &Mock::mockFwGetVersion)); ON_CALL(*pMockFwInterface.get(), getFirstDevice(_)) .WillByDefault(::testing::Invoke(pMockFwInterface.get(), &Mock::mockGetFirstDevice)); + ON_CALL(*pMockFwInterface.get(), fwFlashGSC(_, _)) + .WillByDefault(::testing::Invoke(pMockFwInterface.get(), &Mock::mockFwFlashGSC)); for (const auto &handle : pSysmanDeviceImp->pFirmwareHandleContext->handleList) { delete handle; } @@ -124,5 +126,20 @@ TEST_F(ZesFirmwareFixture, GivenValidFirmwareHandleWhenGettingFirmwareProperties pSysmanDeviceImp->pFirmwareHandleContext->handleList.pop_back(); delete ptestFirmwareImp; } + +TEST_F(ZesFirmwareFixture, GivenValidFirmwareHandleWhenFlashingGscFirmwareSuccessIsReturned) { + FirmwareImp *ptestFirmwareImp = new FirmwareImp(pSysmanDeviceImp->pFirmwareHandleContext->pOsSysman); + pSysmanDeviceImp->pFirmwareHandleContext->handleList.push_back(ptestFirmwareImp); + + auto handles = get_firmware_handles(mockHandleCount); + uint8_t testImage[ZES_STRING_PROPERTY_SIZE] = {}; + memset(testImage, 0xA, ZES_STRING_PROPERTY_SIZE); + for (auto handle : handles) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFirmwareFlash(handle, (void *)testImage, ZES_STRING_PROPERTY_SIZE)); + } + pSysmanDeviceImp->pFirmwareHandleContext->handleList.pop_back(); + delete ptestFirmwareImp; +} + } // namespace ult } // namespace L0