Skip to content

Commit

Permalink
Merge 79aa019 into 67840c5
Browse files Browse the repository at this point in the history
  • Loading branch information
pajgaonk committed Feb 29, 2024
2 parents 67840c5 + 79aa019 commit 0a290fb
Showing 1 changed file with 105 additions and 14 deletions.
119 changes: 105 additions & 14 deletions libraries/plugins/xfpga/usrclk/fpga_user_clk.c
Original file line number Diff line number Diff line change
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";


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

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

bool is_file_empty(char* file_path) {
FILE *fp = fopen(file_path, "r");
if(fp == NULL){
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,
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

0 comments on commit 0a290fb

Please sign in to comment.