Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Update] usrclk DFHv0 -> DFHv1 migration #3111

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
119 changes: 105 additions & 14 deletions libraries/plugins/xfpga/usrclk/fpga_user_clk.c
Expand Up @@ -135,6 +135,8 @@
#define IOPLL_WRITE_POLL_TIMEOUT_US 1000000 /* Write poll timeout */

#define USRCLK_FEATURE_ID 0x14
const char USRCLK_GUID[] = "45AC5052C481412582380B8FF6C2F943";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Define GUID and Feature ID to opae-sdk/blob/master/libraries/plugins/xfpga/types_int.h



// DFHv0
struct dfh {
Expand All @@ -151,10 +153,29 @@ struct dfh {
uint64_t type : 4;
};
};
char guid_l[64];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

struct dfhv0 and dfhv1 sturct used by other function in xfpga , so define dfhv0 and dfhv1 in types_int.h

char guid_h[64];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fpga_guid is compatible with libuuid's uuid_t, so users can use libuuid
fpga_guid is defined in /include/opae/types.h
use fpga_guid varabile

};

static int using_iopll(char *sysfs_usrpath, const char *sysfs_path);

bool is_file_empty(char* file_path) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this function to sysfs.c

FILE *fp = fopen(file_path, "r");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check file_path is null or not
change char* file_path to const har* file_path

if(fp == NULL){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return true or false

printf("error opening file\n");
return 1;
}
int c = fgetc(fp);
if(c == EOF) {
fclose(fp);
return 1;
} else {
ungetc(c, fp);
fclose(fp);
return 0;
}
}

fpga_result usrclk_reset(uint8_t *uio_ptr)
{
uint64_t v = 0;
Expand Down Expand Up @@ -501,15 +522,20 @@ fpga_result usrclk_calibrate(uint8_t *uio_ptr, uint8_t *seq)

fpga_result get_usrclk_uio(const char *sysfs_path,
uint32_t feature_id,
const char* guid,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

define enum_fpga_feature() or find_fpga_feature() new function in common.c file, it enums fpga features and returns dfl_dev.x

struct opae_uio *uio,
uint8_t **uio_ptr)
{
fpga_result res = FPGA_NOT_FOUND;
char feature_path[SYSFS_PATH_MAX] = { 0 };
char guid_path[SYSFS_PATH_MAX] = { 0 };
char dfl_dev_str[SYSFS_PATH_MAX] = { 0 };
int gres, ret = 0;
int feature_gres, guid_gres,ret = 0;
size_t i = 0;
uint64_t value = 0;
char userclk_guid[128] = { 0 };
glob_t feature_pglob;
glob_t guid_pglob;
glob_t pglob;

if (sysfs_path == NULL) {
Expand All @@ -524,29 +550,90 @@ fpga_result get_usrclk_uio(const char *sysfs_path,
return FPGA_EXCEPTION;
}

gres = opae_glob(feature_path, GLOB_NOSORT, NULL, &pglob);
if (gres) {
OPAE_ERR("Failed pattern match %s: %s",
feature_path, strerror(errno));
opae_globfree(&pglob);
if (snprintf(guid_path, sizeof(guid_path),
"%s/dfl_dev*/guid",
sysfs_path) < 0) {
OPAE_ERR("snprintf buffer overflow");
return FPGA_EXCEPTION;
}

feature_gres = opae_glob(feature_path, GLOB_NOSORT, NULL, &feature_pglob);
/* Loop over sysfs feature_id file paths to check if any file is not empty, if all files are empty then we need non empty guid file or it's an error;
We need to do this because I see empty guid file in dfhv0 sysfs path eg - /sys/class/fpga_region/region0/dfl-port.0/dfl_dev.0/guid
It is possible feature_id can be empty by some mistake which would need to be flagged
*/
for (i = 0; i < feature_pglob.gl_pathc; i++) {
if(!is_file_empty(feature_pglob.gl_pathv[i])){
feature_gres = 0;
break;
} else{
feature_gres = 1;
}
}

guid_gres = opae_glob(guid_path, GLOB_NOSORT, NULL, &guid_pglob);
/* Loop over sysfs guid file paths to check if any file is not empty, if all files are empty then we need non empty feature_id file or it's an error;
We need to do this because I see empty guid file in dfhv0 sysfs path eg - /sys/class/fpga_region/region0/dfl-port.0/dfl_dev.0/guid
*/
for (i = 0; i < guid_pglob.gl_pathc; i++) {
if(!is_file_empty(guid_pglob.gl_pathv[i])){
guid_gres = 0;
break;
} else{
guid_gres = 1;
}
}

/* If we don't find guid or feature_id files in sysfs paths then error out
*/
if ((feature_gres) && (guid_gres)) {
OPAE_ERR("Failed pattern match feature id - %s: %s ,guid - %s: %s ",
feature_path, strerror(errno), guid_path, strerror(errno));
opae_globfree(&feature_pglob);
opae_globfree(&guid_pglob);
return FPGA_INVALID_PARAM;
}

/* guid gets priority over feature_id
non-empty guid file being present in sysfs path (eg /sys/class/fpga_region/region0/dfl-port.0/dfl_dev.0/guid) implies user is using dfhv1 IP
*/
if (!guid_gres) {
pglob = guid_pglob;
} else {
pglob = feature_pglob;
}

for (i = 0; i < pglob.gl_pathc; i++) {
res = sysfs_read_u64(pglob.gl_pathv[i], &value);
if (res != FPGA_OK) {
OPAE_MSG("Failed to read sysfs value");
continue;
if (!guid_gres) {
int fd = open(pglob.gl_pathv[i],O_RDONLY);
if(fd == -1) {
OPAE_MSG("Could not open file %s\n", pglob.gl_pathv[i]);
continue;
}
ssize_t bytes_read = read(fd, userclk_guid, sizeof(userclk_guid));
if (bytes_read == -1) {
OPAE_MSG("Could not read from file %s\n",pglob.gl_pathv[i]);
continue;
}
if(close(fd) == -1) {
OPAE_MSG("Could not close file %s\n", pglob.gl_pathv[i]);
goto free;
}
} else {
res = sysfs_read_u64(pglob.gl_pathv[i], &value);
if (res != FPGA_OK) {
OPAE_MSG("Failed to read sysfs value");
continue;
}
}

if (value == feature_id) {
if ((value == feature_id) || (*guid == *userclk_guid)) {
res = FPGA_OK;
char *p = strstr(pglob.gl_pathv[i], "dfl_dev");
if (p == NULL) {
res = FPGA_NOT_FOUND;
goto free;
}

char *end = strchr(p, '/');
if (end == NULL) {
res = FPGA_NOT_FOUND;
Expand Down Expand Up @@ -574,7 +661,8 @@ fpga_result get_usrclk_uio(const char *sysfs_path,
}

free:
opae_globfree(&pglob);
opae_globfree(&feature_pglob);
opae_globfree(&guid_pglob);
return res;
}

Expand Down Expand Up @@ -616,6 +704,7 @@ fpga_result get_userclock(const char *sysfs_path,

result = get_usrclk_uio(sysfs_path,
USRCLK_FEATURE_ID,
USRCLK_GUID,
&uio,
&uio_ptr);
if (result != FPGA_OK) {
Expand Down Expand Up @@ -742,6 +831,7 @@ fpga_result set_userclock(const char *sysfs_path,

result = get_usrclk_uio(sysfs_path,
USRCLK_FEATURE_ID,
USRCLK_GUID,
&uio,
&uio_ptr);
if (result != FPGA_OK) {
Expand Down Expand Up @@ -827,6 +917,7 @@ fpga_result get_userclk_revision(const char *sysfs_path,
// get user clock dfh revision from UIO
result = get_usrclk_uio(sysfs_path,
USRCLK_FEATURE_ID,
USRCLK_GUID,
&uio,
&uio_ptr);
if (result == FPGA_OK) {
Expand Down