From: hadaq Date: Fri, 28 Aug 2009 17:40:58 +0000 (+0000) Subject: initial version X-Git-Tag: v6.0~396 X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=18e16b2d3b453334c229256b0f08160c1a19b9e9;p=trbnettools.git initial version . --- diff --git a/trbrich/trbflashrich.c b/trbrich/trbflashrich.c new file mode 100644 index 0000000..51166db --- /dev/null +++ b/trbrich/trbflashrich.c @@ -0,0 +1,775 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static const uint16_t CtrlReg = 0xd000; +static const uint16_t SetupReg = 0xd001; +static const uint16_t BlockRam = 0xd100; +static uint32_t* trbBuffer = NULL; +static uint8_t** pageBuffer = NULL; +static uint16_t* pageBufferAddress = NULL; + +static uint8_t* imageBuffer = NULL; + +/* Maximum number of endpoints */ +#define NUM_ENDPOINTS 1024 + +/* 32-Bit Words: */ +#define BLOCKRAM_SIZE 64 +#define TRB_BUFFER_SIZE (BLOCKRAM_SIZE * NUM_ENDPOINTS + NUM_ENDPOINTS) + +/* Bytes: */ +#define PAGE_SIZE 256 +#define NUM_PAGES 16384 +#define BLOCK_SIZE (64 * 1024) +#define NUM_BLOCKS 64 + +#define PAGE_BUFFER_SIZE (PAGE_SIZE * NUM_ENDPOINTS) + +static const uint32_t manId[1] = { + 0x0000471f +}; + +static const char bussy[4][5] = { + "|\b", + "/\b", + "-\b", + "\\\b" +}; + +#define NUM_MAN_IDS 1 + +/* ------ MAIN ---------------------------------------------------------- */ + +static FILE *imageFile = NULL; + +static void atexit0() +{ + if (imageFile != NULL) { + fclose(imageFile); + } +} + +static void sigHandler(int sig) +{ + if (sig == SIGTERM) fprintf(stderr, "caught SIGTERM\n"); + if (sig == SIGINT) fprintf(stderr, "caught SIGINT\n"); + + exit(128 + sig); +} + +static const unsigned int timeout = 10000; + +static int readSetupRegister(uint16_t trb_address, + uint8_t value[NUM_ENDPOINTS]) +{ + unsigned int ctr = 0; + int status = -1; + int c; + int i; + + /* Wait until NoMoreData is withdrawn */ + do { + if ((status = trb_register_read(trb_address, SetupReg, + trbBuffer, TRB_BUFFER_SIZE)) == -1) { + trb_error("Error readSetupRegister"); + return -1; + } + + /* Check timeout */ + if (ctr >= timeout) { + fprintf(stderr, "Error readSetupRegister, timeout\n"); + return -1; + } + ctr++; + } while (trb_term.status_channel == 0x04); + + if (trb_term.status_channel != 0) { + trb_error("Error readSetupRegister Status"); + return -1; + } + + if (status <= 0) { + fprintf(stderr, "Error readSetupRegister, length\n"); + return -1; + } + + c = 0; + for (i = 1; i < status; i += 2) { + if (value != NULL) value[c] = (uint8_t)((trbBuffer[i] >> 24) & 0xff); + c++; + } + + return c; +} + +static int writeSetupRegister(uint16_t trb_address, uint8_t value) +{ + unsigned int ctr = 0; + int status = -1; + + /* Wait until NoMoreData is withdrawn */ + do { + if ((status = trb_register_write(trb_address, SetupReg, + (uint32_t)(value << 24))) == -1) { + trb_error("Error writeSetupRegister"); + return -1; + } + + /* Check timeout */ + if (ctr >= timeout) { + fprintf(stderr, "Error writeSetupRegister, timeout\n"); + return -1; + } + ctr++; + } while (trb_term.status_channel != 0); + + if (trb_term.status_channel != 0) { + trb_error("Error writeSetupRegister Status"); + return -1; + } + + return 1; +} + +static int readCtrlRegister(uint16_t trb_address, + uint32_t value[NUM_ENDPOINTS]) +{ + unsigned int ctr = 0; + int status = -1; + int c; + int i; + + /* Wait until NoMoreData is withdrawn */ + do { + if ((status = trb_register_read(trb_address, SetupReg, + trbBuffer, TRB_BUFFER_SIZE)) == -1) { + trb_error("Error readCtrlRegister"); + return -1; + } + + /* Check timeout */ + if (ctr >= timeout) { + fprintf(stderr, "Error readCtrlRegister, timeout\n"); + return -1; + } + ctr++; + } while (trb_term.status_channel != 0); + + if (status <= 0) { + fprintf(stderr, "Error readCtrlRegister, length\n"); + return -1; + } + + c = 0; + for (i = 1; i < status; i += 2) { + if (value != NULL) value[c] = trbBuffer[i]; + c++; + } + + return c; +} + +static int writeCtrlRegister(uint16_t trb_address, uint32_t value) +{ + unsigned int ctr = 0; + int status = -1; + + /* Wait until NoMoreData is withdrawn */ + do { + if ((status = trb_register_write(trb_address, CtrlReg, + value)) == -1) { + trb_error("Error writeCtrlRegister"); + return -1; + } + + /* Check timeout */ + if (ctr >= timeout) { + fprintf(stderr, "Error writeCtrlRegister, timeout\n"); + return -1; + } + ctr++; + } while (trb_term.status_channel != 0); + + return 1; +} + +static int sendCommand(uint16_t trb_address, uint32_t cmd, uint8_t max) +{ + if (writeSetupRegister(trb_address, max) == -1) { + return -1; + } + if (writeCtrlRegister(trb_address, cmd) == -1) { + return -1; + } + if (readCtrlRegister(trb_address, NULL) == -1) { + return -1; + } + + return 0; +} + +static int checkStatus(uint16_t trb_address) +{ + uint32_t trbcmd; + int status; + int ret = 0; + int i; + + /* Read Status Register */ + trbcmd = 0x05 << 24; + if (sendCommand(trb_address, trbcmd, 0) == -1) { + return -1; + } + + if ((status = + trb_register_read(trb_address, BlockRam, trbBuffer, + TRB_BUFFER_SIZE)) == -1) { + trb_error("Error > checkStatus"); + exit(EXIT_FAILURE); + } + + if (status <= 0) { + return -1; + } + + for (i = 0; i < status; i += 2) { + fprintf(stderr, "Status: 0x%02x\n", trbBuffer[i + 1] & 0xff); + if (((trbBuffer[i + 1] >> 5) & 0x01) == 1) { + fprintf(stderr, "Erase or program error on EndPoint 0x%04x\n", + trbBuffer[i] & 0xffff); + return -1; /* Fatal Error */ + } + if ((trbBuffer[i + 1] & 0x01) == 1) { + ret = -2; /* One is busy */ + } + } + + return ret; +} + +static int readPage(uint16_t trb_address, uint32_t pageNumber, + uint32_t numBytes) +{ + uint32_t* temp = NULL; + uint32_t* end = NULL; + unsigned int endPoint; + uint16_t size = 0; + uint32_t trbcmd; + int status = -1; + + if (pageNumber >= NUM_PAGES) return -1; + if ((numBytes > PAGE_SIZE) || (numBytes == 0)) return -1; + + trbcmd = (0x03 << 24) | ((pageNumber * PAGE_SIZE) & 0xffffff); + if (sendCommand(trb_address, trbcmd, numBytes - 1) == -1) { + return -1; + } + + size = (numBytes / 4) + (numBytes % 4 != 0 ? 1 : 0); + if ((status = trb_register_read_mem(trb_address, BlockRam, 0, size, + trbBuffer, TRB_BUFFER_SIZE)) + == -1) { + trb_error("readPage"); + exit(EXIT_FAILURE); + } + + if (status <= 0) { + return -1; + } + + /* Copy trbBuffer to pageBuffer and check content */ + endPoint = 0; + temp = trbBuffer; + end = trbBuffer + status; + while (temp < trbBuffer + status) { + unsigned int len = (*temp >> 16) & 0xffff; + unsigned int address = *temp & 0xffff; + unsigned int c; + + if (len != size) { + fprintf(stderr, + "Error > readPage: Invalid len %d returned by endpoint 0x%04x\n", + len, address); + } + + /* read one page */ + pageBufferAddress[endPoint] = address; + for (c = 0; c < (len * 4); c++) { + if ((c % 4) == 0) { + temp++; + } + pageBuffer[endPoint][c] = (*temp >> ((c % 4) * 8)) & 0xff; + } + temp++; + endPoint++; + } + + return endPoint; +} + + +static int writePage(uint16_t trb_address, uint32_t pageNumber, + const uint8_t* pageBuffer, uint32_t numBytes) +{ + uint32_t* temp = NULL; + uint16_t size = 0; + uint32_t trbcmd; + unsigned int c; + int status = -1; + + if (pageNumber >= NUM_PAGES) return -1; + if ((numBytes > PAGE_SIZE) || (numBytes == 0)) return -1; + + /* Copy pageBuffer to trbBuffer */ + temp = trbBuffer - 1; + for (c = 0; c < numBytes; c++) { + if ((c % 4) == 0) { + temp++; + temp = 0; + } + *temp |= (pageBuffer[c] << ((c % 4) * 8)); + } + + /* Transfer trbBuffer */ + size = temp - trbBuffer + 1; + if ((status = trb_register_write_mem(trb_address, BlockRam, 0, + trbBuffer, size)) + == -1) { + trb_error("Error > writePage: tranfer trbBuffer"); + exit(EXIT_FAILURE); + } + + /* Enable writing */ + if (sendCommand(trb_address, 0x06 << 24, 0) == -1) { + fprintf(stderr, "Error > writePage: write enable\n"); + return -1; + } + + /* Write page */ + trbcmd = (0x02 << 24) | ((pageNumber * PAGE_SIZE) & 0xffffff); + if (sendCommand(trb_address, trbcmd, numBytes - 1) == -1) { + fprintf(stderr, "Error > writePage: write page\n"); + return -1; + } + + return 0; +} + +static int checkManId(uint16_t trb_address) +{ + uint32_t trbcmd; + int status; + int i; + + + /* Read MeanId */ + trbcmd = 0x9f << 24; + if (sendCommand(trb_address, trbcmd, 3) == -1) { + return -1; + } + + if ((status = + trb_register_read(trb_address, BlockRam, trbBuffer, + TRB_BUFFER_SIZE)) == -1) { + trb_error("Error > checkMeanId"); + exit(EXIT_FAILURE); + } + + if (status <= 0) { + return -1; + } + + for (i = 0; i < status; i += 2) { + unsigned int id; + int accepted = -1; + for (id = 0; id < NUM_MAN_IDS; id++) { + if (trbBuffer[i + 1] == manId[id]) { + accepted = 0; + break; + } + } + if (accepted == -1) { + fprintf(stderr, "Invalid ManId 0x%04x on EndPoint 0x%04x\n", + trbBuffer[i + 1], trbBuffer[i] & 0xffff); + return -1; + } + } + + return 0; +} + +void usage(const char *progName) +{ + printf("Usage: %s [-h] [-d level] \n", + progName); + printf("Options:\n"); + printf(" -h give this help\n"); + printf(" -d turn on Debugging Information\n"); + printf("\nCommands:\n"); + printf(" program -> \n"); + printf(" verify -> \n"); + printf(" backup -> \n"); + printf(" restore -> \n"); +} + +int main(int argc, char ** argv) +{ + /* + uint32_t page[PAGE_SIZE]; + sigset_t blockSet; + */ + unsigned int i; + + trb_debug = 0; + + /* Parse Arguments */ + while ((i = getopt(argc, argv, "+hd:")) != -1) { + switch (i) { + case '?': + usage(basename(argv[0])); + exit(EXIT_FAILURE); + case 'h': + usage(basename(argv[0])); + exit(EXIT_SUCCESS); + case 'd': + trb_debug = strtoul(optarg, NULL, 0); + break; + default: + break; + } + } + + if (argc - optind < 1) { + usage(basename(argv[0])); + exit(EXIT_FAILURE); + } + + if (init_ports() == -1) { + trb_error("Init_Ports"); + exit(EXIT_FAILURE); + } + + /* Allocate memory for buffers */ + + /* Buffer holding the TRBNet packages, e.g. use by trb_read_register */ + trbBuffer = (uint32_t*)malloc(sizeof(uint32_t) * TRB_BUFFER_SIZE); + if (trbBuffer == NULL) { + abort(); + } + + /* Buffer holding the pages of the endpoints */ + pageBuffer = (uint8_t**)malloc(sizeof(uint8_t*) * NUM_ENDPOINTS); + if (pageBuffer == NULL) { + abort(); + } + for (i = 0; i < NUM_ENDPOINTS; i++) { + pageBuffer[i] = (uint8_t*)malloc(sizeof(uint8_t) * PAGE_SIZE); + if (pageBuffer[i] == NULL) abort(); + } + + /* Buffer holding the corresponding TRBAddresses */ + pageBufferAddress = (uint16_t*)malloc(sizeof(uint16_t) * NUM_ENDPOINTS); + if (pageBufferAddress == NULL) { + abort(); + } + + /* Buffer holding the entire rom-image */ + imageBuffer = (uint8_t*)malloc(sizeof(uint8_t) * PAGE_SIZE * NUM_PAGES); + if (imageBuffer == NULL) { + abort(); + } + + if (strcmp(argv[optind], "program") == 0) { + if (argc - optind != 3) { + usage(basename(argv[0])); + exit(EXIT_FAILURE); + } + uint16_t trb_address = strtoul(argv[optind + 1], NULL, 0); + char* imageFileName = argv[optind + 2]; + + fprintf(stderr, + "Start flashing ImageFile '%s' to TRB_Address 0x%04x\n", + imageFileName, trb_address); + + } else if (strcmp(argv[optind], "backup") == 0) { + + /*********************************************************/ + /* Backup Image */ + /*********************************************************/ + + uint16_t trb_address; + char* imageFileName; + FILE* imageFile = NULL; + unsigned int page; + + if (argc - optind != 3) { + usage(basename(argv[0])); + exit(EXIT_FAILURE); + } + trb_address = strtoul(argv[optind + 1], NULL, 0); + imageFileName = argv[optind + 2]; + + if (trb_address >= 0xff00) { + fprintf(stderr, + "Broadcast addresses are not supported by this command\n"); + exit(EXIT_FAILURE); + } + + imageFile = fopen(imageFileName, "w+"); + if (imageFile == NULL) { + fprintf(stderr, "Could not open Imagefile %s: %s\n", + imageFileName, strerror(errno)); + } + + if (checkManId(trb_address) == -1) { + exit(EXIT_FAILURE); + } + + if (checkStatus(trb_address) < 0) { + exit(EXIT_FAILURE); + } + + /* Write Pages to file */ + fprintf(stderr, "Writing entire flashrom of EndPoint 0x%04x to file '%s' ", + trb_address, imageFileName); + for (page = 0; page < NUM_PAGES; page++) { + if (readPage(trb_address, page, 256) == -1) { + fprintf(stderr, "Error reading Page# %d, aborting..\n", page); + fclose(imageFile); + exit(EXIT_FAILURE); + } + if (fwrite((void*)pageBuffer[0], PAGE_SIZE, 1, imageFile) != 1) { + fprintf(stderr, "Error writing Page# %d to file, aborting..\n", page); + fclose(imageFile); + exit(EXIT_FAILURE); + } + + fprintf(stderr, "%s", bussy[page % 4]); + } + fprintf(stderr, " \nDone\n"); + + fclose(imageFile); + + } else if (strcmp(argv[optind], "restore") == 0) { + + /*********************************************************/ + /* Restore Image */ + /*********************************************************/ + + uint16_t trb_address; + char* imageFileName; + FILE* imageFile = NULL; + size_t size; + unsigned int block; + unsigned int page; + int status; + unsigned int i; + + if (argc - optind != 3) { + usage(basename(argv[0])); + exit(EXIT_FAILURE); + } + trb_address = strtoul(argv[optind + 1], NULL, 0); + imageFileName = argv[optind + 2]; + + /* Check for correct ManId */ + if (checkManId(trb_address) == -1) { + fprintf(stderr, "Invalid ManId(s), aborting\n"); + exit(EXIT_FAILURE); + } + + /* Read in image */ + imageFile = fopen(imageFileName, "r"); + if (imageFile == NULL) { + fprintf(stderr, "Could not open ImageFile %s: %s\n", + imageFileName, strerror(errno)); + } + + size = fread((void*)imageBuffer, PAGE_SIZE, NUM_PAGES, imageFile); + + if (size != NUM_PAGES) { + fprintf(stderr, "Invalid ImageFile %s, aborting\n", imageFileName); + exit(EXIT_FAILURE); + } + fclose(imageFile); + + /* Check ImageBuffer ??? */ + + page = 0; + for (block = 0; block < NUM_BLOCKS; block++) { + /* Enable writing */ + if (sendCommand(trb_address, 0x06 << 24, 0) == -1) { + fprintf(stderr, "Error > restore: write enable, aborting\n"); + exit(EXIT_FAILURE); + } + + /* Unprotect sector */ + if (sendCommand(trb_address, 0x39 << 24 | (BLOCK_SIZE * block), 3) + == -1) { + fprintf(stderr, "Error > restore: unprotect sector #%d, aborting\n", + block); + exit(EXIT_FAILURE); + } + + /* Enable writing */ + if (sendCommand(trb_address, 0x06 << 24, 0) == -1) { + fprintf(stderr, "Error > restore: write enable, aborting\n"); + exit(EXIT_FAILURE); + } + + /* Erase block */ + if (sendCommand(trb_address, 0xd8 << 24 | (BLOCK_SIZE * block), 3) + == -1) { + fprintf(stderr, "Error > restore: erase block #%d, aborting\n", + block); + exit(EXIT_FAILURE); + } + + /* Wait for not busy and check status */ + while ((status = checkStatus(trb_address) == -2)) { + fprintf(stderr, "Wait..\n"); + } + + if (status != 0) { + fprintf(stderr, "Error > restore: invalid status, aborting\n"); + exit(EXIT_FAILURE); + } + + /* Now write pages */ + for (i = 0; i < (BLOCK_SIZE / PAGE_SIZE); i++) { + status = writePage(trb_address, page, + imageBuffer + page * PAGE_SIZE, PAGE_SIZE); + if (status == -1) { + fprintf(stderr, "Error > restore: writePage, aborting\n"); + exit(EXIT_FAILURE); + } + page++; + } + } + + } else if (strcmp(argv[optind], "test") == 0) { + uint16_t trb_address; + uint32_t pageNumber; + char* imageFileName; + unsigned int i; + int status; + + if (argc - optind != 3) { + usage(basename(argv[0])); + exit(EXIT_FAILURE); + } + trb_address = strtoul(argv[optind + 1], NULL, 0); + pageNumber = strtoul(argv[optind + 2], NULL, 0); + imageFileName = argv[optind + 2]; + + + fprintf(stderr, + "Start flashing ImageFile '%s' to TRB_Address 0x%04x\n", + imageFileName, trb_address); + +#if 0 + + if (sendCommand(trb_address, 0x05 << 24, 0) == -1) { + exit(EXIT_FAILURE); + } + if (trb_register_read(trb_address, BlockRam, buffer, 2) == -1) { + trb_error("readStatus"); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Satus: 0x%08x\n", buffer[1]); +#endif + + if ((status = readPage(trb_address, pageNumber, 256)) == -1) { + fprintf(stderr, "Error reading Page\n"); + exit(EXIT_FAILURE); + } + + for (i = 0; i < status; i++) { + fprintf(stderr, "EndPoint: 0x%04x\n", pageBufferAddress[i]); + int c; + for (c = 0; c < 256; c++) { + fprintf(stderr, "%d: 0x%02x\n", c, pageBuffer[i][c]); + } + } +#if 0 + checkManId(trb_address); + checkStatus(trb_address); + sendCommand(trb_address, 0x06 << 24, 0); + checkStatus(trb_address); + sendCommand(trb_address, 0x04 << 24, 0); + printf("S: %d\n", checkStatus(trb_address)); +#endif + } else { + /* Invalid command */ + usage(basename(argv[0])); + exit(EXIT_FAILURE); + } + +#if 0 + fprintf(stderr, + "Start flashing ImageFile '%s' to TRB_Address 0x%04x\n", + imageFileName, trb_address); + + /* open port */ + init_ports(); + + /* Open ImageFile */ + imageFile = fopen(imageFileName, "r"); + if (imageFile == NULL) { + perror("Error opening ImageFile"); + exit(EXIT_FAILURE); + } + + + while (feof(imageFile) == 0) { + size_t size; + /* clear buffer */ + for (i = 0 ; i < PAGE_SIZE; i++) { + page[i] = 0xffffffff; + } + + if ((size = fread((void*)page, 4, PAGE_SIZE, imageFile)) != PAGE_SIZE) { + fprintf(stderr, "Error reading ImageFile, size = %d\n", size); + exit(EXIT_FAILURE); + } + + fprintf(stderr, "\n\n"); + for (i = 0 ; i < PAGE_SIZE; i++) { + fprintf(stderr, "0x%08x\n", page[i]); + } + } +#endif + +#if 0 + /* Set Signalhandler */ + atexit(atexit0); + signal(SIGINT, sigHandler); + signal(SIGTERM, sigHandler); + + /* Set signal mask for blocking */ + sigemptyset(&blockSet); + sigaddset(&blockSet, SIGINT); + sigaddset(&blockSet, SIGTERM); +#endif + + /* Free memory */ + free(pageBufferAddress); + for (i = 0; i < NUM_ENDPOINTS; i++) { + free(pageBuffer[i]); + } + free(pageBuffer); + free(trbBuffer); + free(imageBuffer); + + exit(EXIT_SUCCESS); +}