Sysman: add firmware flash API (#1368)

* Sysman: add firmware flash API

Signed-off-by: Vilvaraj, T J Vivek <t.j.vivek.vilvaraj@intel.com>

* Sysman: fixed windows implementation of firmware flash API.

Signed-off-by: Vilvaraj, T J Vivek <t.j.vivek.vilvaraj@intel.com>

* add unit tests to test flashing.

Signed-off-by: Vilvaraj, T J Vivek <t.j.vivek.vilvaraj@intel.com>

* sysman: add firmware flashing support to zello sysman

Signed-off-by: T J Vivek Vilvaraj <t.j.vivek.vilvaraj@intel.com>

* sysman: added progress update function to firmware flash API

Signed-off-by: T J Vivek Vilvaraj <t.j.vivek.vilvaraj@intel.com>
This commit is contained in:
Vilvaraj, T J Vivek
2021-01-23 00:25:40 +05:30
committed by GitHub
parent 8c2cb54a3f
commit b41a8d29dd
15 changed files with 106 additions and 19 deletions

View File

@@ -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

View File

@@ -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; }

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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() {}
};

View File

@@ -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();

View File

@@ -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

View File

@@ -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

View File

@@ -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 <class T>
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<const uint8_t *>(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<FirmwareUtil *>(pFwUtilImp);
}
} // namespace L0
} // namespace L0

View File

@@ -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 <class T>
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

View File

@@ -8,10 +8,12 @@
#include <level_zero/zes_api.h>
#include <algorithm>
#include <fstream>
#include <getopt.h>
#include <iostream>
#include <map>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <vector>
@@ -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 <image> selectively run device firmware test <image> 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<uint32_t>(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;

View File

@@ -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<FirmwareInterface> : 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<FirmwareInterface>() = 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 {

View File

@@ -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<FirmwareInterface>::mockFwGetVersion));
ON_CALL(*pMockFwInterface.get(), getFirstDevice(_))
.WillByDefault(::testing::Invoke(pMockFwInterface.get(), &Mock<FirmwareInterface>::mockGetFirstDevice));
ON_CALL(*pMockFwInterface.get(), fwFlashGSC(_, _))
.WillByDefault(::testing::Invoke(pMockFwInterface.get(), &Mock<FirmwareInterface>::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