Made it not depend on IES
This commit is contained in:
parent
b8db6e9dc4
commit
5c26080348
296
fm10k-dump.c
296
fm10k-dump.c
|
@ -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;
|
||||
}
|
Loading…
Reference in a new issue