Refactor device handling to allow finding multiple devices and select appropiate one.
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
DataHoarder 2021-12-19 15:24:41 +01:00
parent ab1bffe446
commit f13923f5da
4 changed files with 135 additions and 89 deletions

View file

@ -35,13 +35,9 @@
#include "fm10k.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char **argv) {
int fdBAR4;
FILE *fdOutput;
if (argc < 2) {
@ -56,35 +52,18 @@ int main(int argc, char **argv) {
return 1;
}
FM10K_PCI_DEVICE device = fm10k_pci_findDevice();
FM10K_PCI_MAPPED_DEVICE map;
FM10K_PCI_DEVICES devices = fm10k_pci_findDevices();
if (device.vendor == 0) {
printf("Unable to find FM10K device with BAR4 port access. Check bifurcation settings?\n");
return 1;
}
if(fm10k_pci_findDevice(&devices, &map)){
printf("Unable to find FM10K device with BAR4 port access, or could not take SPI lock. Check bifurcation settings?\n");
return 1;
}
fdBAR4 = open(device.bar4Path, O_RDWR);
if (fdBAR4 <= 0) {
printf("Unable to open BAR4 resource %s to read NVM\n", device.bar4Path);
return 1;
}
void *memmapAddr;
memmapAddr = mmap(NULL, FM10K_BAR4_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fdBAR4, 0);
if (memmapAddr == MAP_FAILED) {
printf("Unable to map BAR4 resource %s to read NVM\n", device.bar4Path);
close(fdBAR4);
return 1;
}
if(fm10k_mem_TakePlatformLock((uintptr_t) memmapAddr)){
printf("Error taking SPI Lock\n");
return 1;
}
SPI_COMMAND_READ_MANUFACTURER_RESULT manufacturerInfo = fm10k_mem_spi_ReadManufacturerData((uintptr_t) memmapAddr);
SPI_COMMAND_READ_MANUFACTURER_RESULT manufacturerInfo = fm10k_mem_spi_ReadManufacturerData((uintptr_t) map.map);
if (manufacturerInfo.value == 0) {
printf("Error getting manufacturer information\n");
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
return 1;
}
printf("Manufacturer Info 0x%08x :: JEDEC Manufacturer ID 0x%02x family 0x%02x density 0x%02x %02x:%02x\n",
@ -113,13 +92,13 @@ int main(int argc, char **argv) {
if (mbitsToRead > 1024) {
printf("Too many MBit: %u\n", mbitsToRead);
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
return 1;
}
if (mbitsToRead < 8) {
printf("Too few MBit: %u\n", mbitsToRead);
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
return 1;
}
@ -131,8 +110,8 @@ int main(int argc, char **argv) {
for (uint32_t addr = 0; addr < bootImageSize; addr += strideSize) {
printf("\rread @ 0x%08x / 0x%08x %d bytes", addr, bootImageSize, strideSize);
if (fm10k_mem_spi_ReadFlash((uintptr_t) memmapAddr, addr, value + addr, strideSize)) {
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
if (fm10k_mem_spi_ReadFlash((uintptr_t) map.map, addr, value + addr, strideSize)) {
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
return 2;
}
}
@ -146,7 +125,9 @@ int main(int argc, char **argv) {
printf("\n");
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
fm10k_pci_unmapDevice(&map);
printf("Read %u bytes\n", bootImageSize);

View file

@ -36,13 +36,11 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char **argv) {
int fdBAR4;
FILE *fdBackup;
FILE *fdInput;
@ -78,35 +76,18 @@ int main(int argc, char **argv) {
return 1;
}
FM10K_PCI_DEVICE device = fm10k_pci_findDevice();
FM10K_PCI_MAPPED_DEVICE map;
FM10K_PCI_DEVICES devices = fm10k_pci_findDevices();
if (device.vendor == 0) {
printf("Unable to find FM10K device with BAR4 port access. Check bifurcation settings?\n");
return 1;
}
if(fm10k_pci_findDevice(&devices, &map)){
printf("Unable to find FM10K device with BAR4 port access, or could not take SPI lock. Check bifurcation settings?\n");
return 1;
}
fdBAR4 = open(device.bar4Path, O_RDWR);
if (fdBAR4 <= 0) {
printf("Unable to open BAR4 resource %s to read NVM\n", device.bar4Path);
return 1;
}
void *memmapAddr;
memmapAddr = mmap(NULL, FM10K_BAR4_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fdBAR4, 0);
if (memmapAddr == MAP_FAILED) {
printf("Unable to map BAR4 resource %s to read NVM\n", device.bar4Path);
close(fdBAR4);
return 1;
}
if(fm10k_mem_TakePlatformLock((uintptr_t) memmapAddr)){
printf("Error taking SPI Lock\n");
return 1;
}
SPI_COMMAND_READ_MANUFACTURER_RESULT manufacturerInfo = fm10k_mem_spi_ReadManufacturerData((uintptr_t) memmapAddr);
SPI_COMMAND_READ_MANUFACTURER_RESULT manufacturerInfo = fm10k_mem_spi_ReadManufacturerData((uintptr_t) map.map);
if (manufacturerInfo.value == 0) {
printf("Error getting manufacturer information\n");
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
return 1;
}
printf("Manufacturer Info 0x%08x :: JEDEC Manufacturer ID 0x%02x family 0x%02x density 0x%02x %02x:%02x\n",
@ -127,13 +108,13 @@ int main(int argc, char **argv) {
if (mbitsToReadMax > 1024) {
printf("Too many MBit: %u\n", mbitsToReadMax);
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
return 1;
}
if (mbitsToReadMax == 0) {
printf("Too few MBit: %u\n", mbitsToReadMax);
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
return 1;
}
@ -142,7 +123,7 @@ int main(int argc, char **argv) {
if (fileSize > bootImageSizeMax) {
printf("Image too large: have %d, can write max %d bytes.\n", fileSize, bootImageSizeMax);
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
return 1;
} else if (fileSize < bootImageSizeMax) {
do {
@ -156,13 +137,13 @@ int main(int argc, char **argv) {
if (fread(value, 1, bootImageSizeMax, fdInput) != bootImageSizeMax) {
printf("Error reading image file.\n");
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
return 1;
}
if (fread(valueBackup, 1, bootImageSizeMax, fdBackup) != bootImageSizeMax) {
printf("Error reading backup image file.\n");
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
return 1;
}
@ -173,8 +154,8 @@ int main(int argc, char **argv) {
for (uint32_t addr = 0; addr < bootImageSizeMax; addr += strideSize) {
printf("\rbackup check @ 0x%08x / 0x%08x %d bytes", addr, bootImageSizeMax, strideSize);
if (fm10k_mem_spi_ReadFlash((uintptr_t) memmapAddr, addr, valueCheck + addr, strideSize)) {
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
if (fm10k_mem_spi_ReadFlash((uintptr_t) map.map, addr, valueCheck + addr, strideSize)) {
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
return 2;
}
}
@ -183,7 +164,7 @@ int main(int argc, char **argv) {
if (memcmp(valueBackup, valueCheck, bootImageSizeMax) != 0) {
printf("Backup image mismatch! Dump image again.\n");
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
return 1;
} else {
printf("Backup matches.\n");
@ -192,7 +173,7 @@ int main(int argc, char **argv) {
sleep(1);
printf("Disabling sector protection.\n");
fm10k_mem_spi_DisableSectorProtection((uintptr_t) memmapAddr);
fm10k_mem_spi_DisableSectorProtection((uintptr_t) map.map);
sleep(1);
@ -200,8 +181,8 @@ int main(int argc, char **argv) {
for (uint32_t addr = 0; addr < bootImageSizeMax; addr += strideSize) {
if (memcmp(valueBackup + addr, value + addr, strideSize) != 0) {
printf("write @ 0x%08x\n", addr);
if (fm10k_mem_spi_WriteFlash((uintptr_t) memmapAddr, addr, value + addr, strideSize)) {
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
if (fm10k_mem_spi_WriteFlash((uintptr_t) map.map, addr, value + addr, strideSize)) {
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
return 2;
}
sleep(1);
@ -215,8 +196,8 @@ int main(int argc, char **argv) {
for (uint32_t addr = 0; addr < bootImageSizeMax; addr += strideSize) {
printf("\rverify check @ 0x%08x / 0x%08x %d bytes", addr, bootImageSizeMax, strideSize);
if (fm10k_mem_spi_ReadFlash((uintptr_t) memmapAddr, addr, valueCheck + addr, strideSize)) {
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
if (fm10k_mem_spi_ReadFlash((uintptr_t) map.map, addr, valueCheck + addr, strideSize)) {
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
return 2;
}
}
@ -238,8 +219,8 @@ int main(int argc, char **argv) {
for (uint32_t addr = 0; addr < bootImageSizeMax; addr += strideSize) {
if (memcmp(valueBackup + addr, valueCheck + addr, strideSize) != 0) {
printf("write backup @ 0x%08x\n", addr);
if (fm10k_mem_spi_WriteFlash((uintptr_t) memmapAddr, addr, valueBackup + addr, strideSize)) {
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
if (fm10k_mem_spi_WriteFlash((uintptr_t) map.map, addr, valueBackup + addr, strideSize)) {
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
return 2;
}
sleep(1);
@ -253,7 +234,9 @@ int main(int argc, char **argv) {
printf("\n");
fm10k_mem_ReleasePlatformLock((uintptr_t) memmapAddr);
fm10k_mem_ReleasePlatformLock((uintptr_t) map.map);
fm10k_pci_unmapDevice(&map);
free(value);

View file

@ -36,6 +36,8 @@
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/mman.h>
#include <fcntl.h>
KNOWN_FLASH_DEVICE KNOWN_FLASH_DEVICE_LIST[] = {
{{0x0101271f}, "Adesto AT45DB321E 32-Mbit", 32}, // Present on Silicom PE3100G2DQiRM-QX4
@ -503,14 +505,76 @@ void fm10k_mem_ReleasePlatformLock(uintptr_t mem){
fm10k_mem_bsm_RestoreInterrupts(mem);
}
FM10K_PCI_DEVICE fm10k_pci_findDevice() {
int fm10k_pci_unmapDevice(FM10K_PCI_MAPPED_DEVICE* map){
if(map->map != NULL && map->map != MAP_FAILED){
if(munmap(map->map, FM10K_BAR4_SIZE) != 0){
return 1;
}
map->map = NULL;
}
if (map->fd > 0) {
if(close(map->fd) != 0){
return 1;
}
map->fd = 0;
}
return 0;
}
int fm10k_pci_mapDevice(const FM10K_PCI_DEVICE* device, FM10K_PCI_MAPPED_DEVICE* map){
int fdBAR4;
fdBAR4 = open(device->bar4Path, O_RDWR);
if (fdBAR4 <= 0) {
printf("Unable to open BAR4 resource %s to read NVM\n", device->bar4Path);
return 1;
}
void *memmapAddr;
memmapAddr = mmap(NULL, FM10K_BAR4_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fdBAR4, 0);
if (memmapAddr == MAP_FAILED) {
printf("Unable to map BAR4 resource %s to read NVM\n", device->bar4Path);
close(fdBAR4);
return 1;
}
map->device = device;
map->fd = fdBAR4;
map->map = memmapAddr;
if(fm10k_mem_TakePlatformLock((uintptr_t) map->map)){
//Error taking lock
fm10k_pci_unmapDevice(map);
return 1;
}
return 0;
}
int fm10k_pci_findDevice(const FM10K_PCI_DEVICES* devices, FM10K_PCI_MAPPED_DEVICE* map) {
if(devices->count == 0){
return 1;
}
for(uint32_t i = 0; i < devices->count; ++i){
if(fm10k_pci_mapDevice(&devices->devices[i], map) == 0){
return 0;
}
}
return 1;
}
FM10K_PCI_DEVICES fm10k_pci_findDevices() {
DIR *folder;
char fileName[PATH_MAX];
FM10K_PCI_DEVICE device = {0, 0, ""};
FM10K_PCI_DEVICES devices;
devices.count = 0;
folder = opendir("/sys/bus/pci/devices");
if (folder == NULL) {
return device;
return devices;
}
struct dirent *entry;
@ -524,7 +588,7 @@ FM10K_PCI_DEVICE fm10k_pci_findDevice() {
size_t vendorBytesLen;
size_t vendorBytesRead = getdelim(&vendorBytesBuffer, &vendorBytesLen, '\0', vendorBytesPointer);
if (vendorBytesRead != -1) {
int vendor = (int) strtol(vendorBytesBuffer, NULL, 0);
unsigned int vendor = (unsigned int) strtoul(vendorBytesBuffer, NULL, 0);
if (vendor == 0x8086) { //Intel Corporation
@ -536,15 +600,16 @@ FM10K_PCI_DEVICE fm10k_pci_findDevice() {
size_t classBytesRead = getdelim(&classBytesBuffer, &classBytesLen, '\0',
classBytesPointer);
if (classBytesRead != -1) {
int class = (int) strtol(classBytesBuffer, NULL, 0);
unsigned int class = (unsigned int) strtoul(classBytesBuffer, NULL, 0);
if (class == 0x15a4 || class == 0x15d0 || class == 0x15d5) { //FM10000 devices
sprintf(fileName, "/sys/bus/pci/devices/%s/resource4", entry->d_name);
if (access(fileName, F_OK) == 0) {
device.vendor = vendor;
device.class = class;
devices.devices[devices.count].vendor = vendor;
devices.devices[devices.count].class = class;
sprintf(device.bar4Path, "/sys/bus/pci/devices/%s/resource4", entry->d_name);
sprintf(devices.devices[devices.count].bar4Path, "/sys/bus/pci/devices/%s/resource4", entry->d_name);
++devices.count;
}
}
}
@ -563,7 +628,7 @@ FM10K_PCI_DEVICE fm10k_pci_findDevice() {
fclose(vendorBytesPointer);
}
if (device.vendor != 0) {
if (devices.count >= FM10K_PCI_DEVICE_MAX) {
break;
}
@ -572,5 +637,5 @@ FM10K_PCI_DEVICE fm10k_pci_findDevice() {
closedir(folder);
return device;
return devices;
}

View file

@ -160,11 +160,28 @@ uint32_t fm10k_mem_spi_ReadFlash(uintptr_t mem, uint32_t address, uint8_t *data,
uint32_t fm10k_mem_spi_WriteFlash(uintptr_t mem, uint32_t address, const uint8_t *data, uint32_t len);
#define FM10K_PCI_DEVICE_MAX 16
typedef struct {
uint16_t vendor;
uint16_t class;
char bar4Path[PATH_MAX];
} FM10K_PCI_DEVICE;
FM10K_PCI_DEVICE fm10k_pci_findDevice();
typedef struct {
const FM10K_PCI_DEVICE* device;
void* map;
int fd;
} FM10K_PCI_MAPPED_DEVICE;
typedef struct {
uint32_t count;
FM10K_PCI_DEVICE devices[FM10K_PCI_DEVICE_MAX];
} FM10K_PCI_DEVICES;
FM10K_PCI_DEVICES fm10k_pci_findDevices();
int fm10k_pci_findDevice(const FM10K_PCI_DEVICES* devices, FM10K_PCI_MAPPED_DEVICE* map);
int fm10k_pci_mapDevice(const FM10K_PCI_DEVICE* device, FM10K_PCI_MAPPED_DEVICE* map);
int fm10k_pci_unmapDevice(FM10K_PCI_MAPPED_DEVICE* map);