Made it not depend on IES

This commit is contained in:
DataHoarder 2020-12-16 17:17:58 +01:00
parent b8db6e9dc4
commit 5c26080348

View file

@ -1,155 +1,241 @@
/*
*
* Requires FM10K and UIO module working.
*
* Install IES on /root/install, via: ./configure --prefix /root/install && make && make install
*
gcc -DFM_SUPPORT_FM10000 -D_FM_ARCH_X86_64 \
-I/root/install/include -I/root/install/include/alos -I/root/install/include/alos/linux -I/root/install/include/std/intel -I/root/install/include/common -I/root/install/include/platforms -I/root/install/include/platforms/libertyTrail -L/usr/local/lib \
-lFocalpointSDK -ldl -lpthread -lm \
-o fm10k-dump fm10k-dump.c
gcc -o fm10k-dump fm10k-dump.c
*
*/
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include "fm_sdk.h"
#include "fm_sdk_fm10000_int.h"
#include "util/fm10000/fm10000_util_spi.h"
#define FM10K_UIO_SIZE 0x0000000004000000
#define FM10K_UIO_OFFSET 0
#define FM_MAIN_SWITCH 0
#define FM_DEFAULT_VLAN 1
#define ETHTOOL_SPFLAGS 0x00000028
#define ETHTOOL_PRV_FLAG_IES_DISABLE (0 << 0)
//From Datasheet, 11.25.1 MGMT Map, Table 11-37
#define FM10K_REGISTER_BASE 0
#define SPI_FREQ_KHZ 50000
#define FM10K_REGISTER_SPI_TX_DATA ((0xC26) + (FM10K_REGISTER_BASE))
#define FM10K_REGISTER_SPI_RX_DATA ((0xC27) + (FM10K_REGISTER_BASE))
#define FM10K_REGISTER_SPI_HEADER ((0xC28) + (FM10K_REGISTER_BASE))
#define FM10K_REGISTER_SPI_CTRL ((0xC29) + (FM10K_REGISTER_BASE))
fm_semaphore seqSem;
fm_int sw = FM_MAIN_SWITCH;
#define FM10K_SPI_FREQ_KHZ 50000
/*****************************************************************************/
/** RegRead32
* \ingroup intPlatform
*
* \desc Read register value.
*
* \param[in] switchMem is pointer to mapped memory
*
* \param[in] addr is the address of the register
*
* \param[out] value is a pointer to the register value
*
* \return FM_OK if successful.
* \return FM_ERR_INVALID_ARGUMENT if either switchMem or value is NULL.
*
*****************************************************************************/
static fm_status RegRead32(fm_uintptr switchMem,
fm_uint addr,
fm_uint32 *value)
{
FM_LOG_ENTRY(FM_LOG_CAT_PLATFORM,
"switchMem %p addr 0x%x value %p\n",
(void*)switchMem,
addr,
(void*)value);
if ( ((fm_uint32*)switchMem == NULL) || (value == NULL) )
{
FM_LOG_EXIT(FM_LOG_CAT_PLATFORM, FM_ERR_INVALID_ARGUMENT);
void ReadRegister32(uintptr_t mem, uint32_t addr, uint32_t* value) {
*value = *(((uint32_t*)mem) + addr);
}
void WriteRegister32(uintptr_t mem, uint32_t addr, uint32_t value) {
*(uint32_t volatile*)(((uint32_t*)mem) + addr) = value;
//If returning instantly this will caused missed writes. nanosleep wait of 1 nsec was too much. Busy wait works
volatile uint32_t dummy;
for(uint32_t i = 0; i < 100; ++i){
dummy = i;
}
}
uint32_t get_interval_diff(struct timeval *begin, struct timeval *end) {
struct timeval endT;
struct timeval diff;
if (end == NULL) {
gettimeofday(&endT, NULL);
} else {
endT.tv_sec = end->tv_sec;
endT.tv_usec = end->tv_usec;
}
*value = *(((fm_uint32*)switchMem) + addr);
diff.tv_sec = endT.tv_sec - begin->tv_sec;
diff.tv_usec = endT.tv_usec - begin->tv_usec;
FM_LOG_EXIT(FM_LOG_CAT_PLATFORM, FM_OK);
return (diff.tv_sec * 1000 + diff.tv_usec / 1000);
}
} /* end RegRead32 */
uint32_t fm10k_uio_spi_SetCtrlReg(uintptr_t mem, uint32_t value){
uint32_t spiCtrl;
struct timeval startTime;
uint8_t isTimeout = 0;
WriteRegister32(mem, FM10K_REGISTER_SPI_CTRL, value);
gettimeofday(&startTime, NULL);
do{
if(isTimeout){
printf("Timeout waiting for SPI_CTRL Busy. 0x%02x\n", spiCtrl);
return 1;
}
if(get_interval_diff(&startTime, NULL) > 50){
isTimeout = 1;
}
ReadRegister32(mem, FM10K_REGISTER_SPI_CTRL, &spiCtrl);
} while ((spiCtrl >> 21) & 1); //While "Busy"
/* write back SPI_CTRL with command = 0 */
spiCtrl &= 0xffff87ff;
WriteRegister32(mem, FM10K_REGISTER_SPI_CTRL, spiCtrl);
return 0;
}
void fm10k_uio_spi_Enable(uintptr_t mem){
//ENABLE SPI
uint32_t spiCtrl = 0;
ReadRegister32(mem, FM10K_REGISTER_SPI_CTRL, &spiCtrl);
/* keep current freq setting and set SPI Enable */
spiCtrl &= 0x3ff;
spiCtrl |= 1<<10;
WriteRegister32(mem, FM10K_REGISTER_SPI_CTRL, spiCtrl);
}
void fm10k_uio_spi_Disable(uintptr_t mem){
//DISABLE SPI
uint32_t spiCtrl = 0;
ReadRegister32(mem, FM10K_REGISTER_SPI_CTRL, &spiCtrl);
/* keep current freq setting and set SPI Disable */
spiCtrl &= 0x3ff;
WriteRegister32(mem, FM10K_REGISTER_SPI_CTRL, spiCtrl);
}
uint32_t fm10k_uio_spi_ReadFlash(uintptr_t mem, uint32_t address, uint8_t* data, int32_t len){
uint32_t spiCtrl;
uint32_t rxData;
uint32_t header;
int32_t freq;
int32_t cnt;
int32_t numRead;
fm10k_uio_spi_Enable(mem);
ReadRegister32(mem, FM10K_REGISTER_SPI_CTRL, &spiCtrl);
if(FM10K_SPI_FREQ_KHZ > 0){
freq = ((100000 / (int)FM10K_SPI_FREQ_KHZ) / 2) - 1;
if (freq < 0){
freq = 0;
}
/*****************************************************************************/
/** RegWrite32
* \ingroup intPlatform
*
* \desc Write a value to register.
*
* \param[in] switchMem is pointer to mapped memory
*
* \param[in] addr is the address of the register
*
* \param[out] value is the register value
*
* \return FM_OK if successful.
* \return FM_ERR_INVALID_ARGUMENT if switchMem is NULL.
*
*****************************************************************************/
static fm_status RegWrite32(fm_uintptr switchMem,
fm_uint addr,
fm_uint32 value)
{
FM_LOG_ENTRY(FM_LOG_CAT_PLATFORM,
"switchMem %p addr 0x%x value 0x%x\n",
(void*)switchMem,
addr,
value);
if ((fm_uint32*)switchMem == NULL)
{
FM_LOG_EXIT(FM_LOG_CAT_PLATFORM, FM_ERR_INVALID_ARGUMENT);
spiCtrl ^= ((spiCtrl >> 0) ^ freq) & ((2 << 9) - 1); //Set Freq
}
*(((fm_uint32*)switchMem) + addr) = value;
spiCtrl &= 0x7ff;
FM_LOG_EXIT(FM_LOG_CAT_PLATFORM, FM_OK);
/* header: command (1 byte: READ_BYTES) + address (3 bytes) */
header = (0x3 << 24) | (address & 0xffffff);
WriteRegister32(mem, FM10K_REGISTER_SPI_HEADER, header);
} /* end RegWrite32 */
/* first loop only: set send header flag. Following loops: shift only data. */
spiCtrl |= (0x1 << 11);
cnt = 0;
while (cnt < len){
/* determine the number of data bytes to read [1..4] */
numRead = (len - cnt) > 3 ? 4 : (len - cnt);
/* set 'shift data' flag and number of data bytes */
spiCtrl |= ((0x4 << 11) | ((numRead & 0x03) << 17));
if(fm10k_uio_spi_SetCtrlReg(mem, spiCtrl)){
return 1;
}
/* get data */
ReadRegister32(mem, FM10K_REGISTER_SPI_RX_DATA, &rxData);
/* push the read data into the array */
while (numRead) {
numRead--;
data[cnt++] = (rxData >> (numRead * 8)) & 0xff;
}
spiCtrl &= 0x7ff;
}
/* release CS */
spiCtrl |= (0x8 << 11);
if(fm10k_uio_spi_SetCtrlReg(mem, spiCtrl)){
return 1;
}
fm_status fm10000CrmDummy( fm_smEventInfo *eventInfo, void *userInfo, fm_int *nextState ){
fm10k_uio_spi_Disable(mem);
return 0;
}
int main(int argc, char** argv){
fm_int fd;
fm_int size;
void *memmapAddr;
fm_uint32 *switchMem;
fm_status err = FM_OK;
int fdUIO;
FILE* fdOutput;
FILE* binFD;
if(argc < 2){
printf("Usage: %s <output.bin>\n", argv[0]);
if(argc < 3){
printf("Usage: %s </dev/uio0> <output.bin> [sizeInMB, default 1]\n", argv[0]);
return 1;
}
binFD = fopen(argv[1], "wb");
fdOutput = fopen(argv[2], "wb");
if(binFD == NULL){
printf("Could not create %s\n", argv[1]);
if(fdOutput == NULL){
printf("Could not create %s\n", argv[2]);
return 1;
}
err = fmPlatformMmapUioDevice(NULL, &fd, &memmapAddr, &size);
if (err)
{
printf("Unable to map uio device to read NVM\n");
fdUIO = open(argv[1], O_RDWR);
if(fdUIO <= 0){
printf("Unable to open uio device %s to read NVM\n", argv[1]);
return 1;
}
void* memmapAddr;
memmapAddr = mmap(NULL, FM10K_UIO_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fdUIO, 0);
if (memmapAddr == MAP_FAILED) {
printf("Unable to map uio device %s to read NVM\n", argv[1]);
close(fdUIO);
return 1;
}
switchMem = (fm_uint32*) memmapAddr;
unsigned int mbToRead = 1;
fm_uint32 bootImageSize = 1 * 1024 * 1024;
fm_byte value;
for(fm_uint32 addr = 0x0; addr < bootImageSize; ++addr){
err = fm10000UtilSpiReadFlash((fm_uintptr)switchMem, RegRead32, RegWrite32, addr, &value, sizeof(fm_byte), SPI_FREQ_KHZ);
if(err){
if(argc > 3){
sscanf(argv[3], "%u", &mbToRead);
}
if(mbToRead > 128){
printf("Too many MB: %u\n", mbToRead);
return 1;
}
uint32_t bootImageSize = mbToRead * 1024 * 1024;
uint8_t* value = malloc(bootImageSize);
uint32_t strideSize = 1024;
for(uint32_t addr = 0; addr < bootImageSize; addr += strideSize){
printf("\rLOC 0x%08x MAX 0x%08x", addr, bootImageSize);
if(fm10k_uio_spi_ReadFlash((uintptr_t)(uint32_t *)memmapAddr, addr, value + addr, strideSize)){
return 2;
}
fwrite(&value, sizeof(value), 1, binFD);
}
fclose(binFD);
return err;
fwrite(value, 1, bootImageSize, fdOutput);
free(value);
fclose(fdOutput);
printf("\nRead %u bytes\n", bootImageSize);
return 0;
}