From: Hao Zhang Date: Fri, 9 Dec 2011 22:02:23 +0000 (-0500) Subject: Added uboot tools X-Git-Tag: DEV.SC-MCSDK-02.00.00.02^0 X-Git-Url: https://git.ti.com/gitweb?p=keystone-rtos%2Fmcsdk-tools.git;a=commitdiff_plain;h=9bc0cc7db1163dbf8804d7914f253ee41d74cb68;hp=0e8fcaaeb20e72b74c695fb670ea7c698f0351c2 Added uboot tools --- diff --git a/boot_loader/uboot/build_writer.bat b/boot_loader/uboot/build_writer.bat new file mode 100644 index 0000000..4868093 --- /dev/null +++ b/boot_loader/uboot/build_writer.bat @@ -0,0 +1,23 @@ +set path=t:\gen\mingw\20110516\msys\1.0\bin;t:\gen\mingw\20110516\bin +set C6000_CG_DIR="C:\ti\ccsv5\tools\compiler\c6000" + +cd utils +bash make_util +cd .. + +cd nandwriter +bash make_writer + +..\utils\bin2ccs u-boot.bin u-boot.tmp +..\utils\ccsAddGphdr 0xc001000 -infile u-boot.tmp -outfile u-boot.hdr +..\utils\ccsAddGptlr -infile u-boot.hdr -outfile u-boot.tlr +..\utils\byteswapccs u-boot.tlr u-boot.dat +rm -rf u-boot.tmp +rm -rf u-boot.hdr +rm -rf u-boot.tlr + +cd .. + + + + diff --git a/boot_loader/uboot/nandwriter/Makefile b/boot_loader/uboot/nandwriter/Makefile new file mode 100644 index 0000000..ba92b4f --- /dev/null +++ b/boot_loader/uboot/nandwriter/Makefile @@ -0,0 +1,9 @@ + + +nandwrite.out: nandwrite.cmd nandwrite.obj + $(C6000_CG_DIR)/bin/cl6x -z nandwrite.cmd $(C6000_CG_DIR)/lib/rts64plus.lib -o nandwrite.out -m nandwrite.map + +nandwrite.obj: nandwrite.c + $(C6000_CG_DIR)/bin/cl6x -c -g -mv64+ nandwrite.c -I$(C6000_CG_DIR)/include + + diff --git a/boot_loader/uboot/nandwriter/make_writer b/boot_loader/uboot/nandwriter/make_writer new file mode 100644 index 0000000..293faed --- /dev/null +++ b/boot_loader/uboot/nandwriter/make_writer @@ -0,0 +1 @@ +make -f Makefile diff --git a/boot_loader/uboot/nandwriter/nandwrite.c b/boot_loader/uboot/nandwriter/nandwrite.c new file mode 100644 index 0000000..4dc8e6c --- /dev/null +++ b/boot_loader/uboot/nandwriter/nandwrite.c @@ -0,0 +1,1204 @@ +/* A very simple NAND writer */ +#include + +// This code will work ONLY for Micron MT29F2G08ABDHC devices! + +/* These values are setup at run time */ +unsigned int busWidth = 8; +unsigned int pageSizeBytes = 2048; +unsigned int pagesPerBlock = 64; +unsigned int spareBytesPerSegment = 16; +unsigned int spareBytesPerPage = 0; + +unsigned int readIdCmd = 0x90; +unsigned int readPageCmd = 0x00; +unsigned int readPageDoneCmd = 0x30; /* Not used for small page devices */ +unsigned int readPageRandomCmd = 0x05; /* Not used for small page devices */ +unsigned int readPageRndDoneCmd = 0xE0; /* Not used for small page devices */ + +unsigned int smallPageReadEccCmd = 0x50; /* Used only on small page devices */ + +unsigned int blockEraseACmd = 0x60; +unsigned int blockEraseBCmd = 0xD0; + +unsigned int resetCmd = 0xFF; + +unsigned int programACmd = 0x80; +unsigned int programBCmd = 0x10; + +unsigned int readStatusRegCmd = 0x70; + +/* Which pages have manufacturer bad block mark? */ +unsigned int manufactureBadBlockPages[] = { 0 }; /* indexed from 0 */ + +/* Which spare bytes of of page have manufacturer bad block mark? */ +unsigned int manufactureBadBlockBytes[] = { 0 }; /* array of bad word mark locations indexed from 0 */ + +volatile unsigned int statusReg; + +unsigned int csRegion = 0; +unsigned int memBase = 0; + +/* data, address, command latch addresses assuming the EMIF16 is configured with emif11a as + * the address latch, and emif12a as the command latch */ +unsigned int dataOffset = 0x0000; +unsigned int addrOffset = 0x2000; +unsigned int cmdOffset = 0x4000; + +int smallPage = 0; //1; + +/* The following values are defined in the linker command file */ +//extern unsigned int writeBlock; +//extern unsigned int readBlock; +//extern unsigned int spareBlock; +//extern unsigned int scratchBlock; +extern unsigned char writeBlock; +extern unsigned char readBlock; +extern unsigned char spareBlock; +extern unsigned char scratchBlock; + +unsigned char *writeData = &writeBlock; /* Defined in the linker command file */ +unsigned char *readData = &readBlock; +unsigned char *spareData = &spareBlock; /* the spare data area is placed here after writes */ +unsigned char *scratch = &scratchBlock; /* used for temporary storage */ + +volatile unsigned int dataSizeUint32 = 0x20000; // THIS MUST BE SET TO THE NUMBER OF WORDS TO PROGRAM! + +unsigned int firstBlock = 0; /* The first block to program */ + +int doWrite = 1; /* Set to 1 to program the nand */ +//int doCompare = 0; /* Set to 1 to compare writeData and readData */ + + +void eraseBlock (int n); +void programSegment(unsigned int firstBlock, int blockIdx, unsigned int page, int segment, unsigned int memOffset, unsigned int eccOffset); +void readAndCorrectSegment(unsigned int firstBlock, int blockCount, unsigned int pageCount, int segmentCount, unsigned int memOffset); +void readDeviceId(); + +volatile unsigned int dummy; + + +#define EMIF_CTL_BASE 0x20c00000 + +#define EMIF_CTL_RCSR 0x0000 + +#define EMIF_CTL_A1CR 0x0010 + +#define EMIF_CTL_NANDFCR 0x0060 +#define EMIF_CTL_NANDFSR 0x0064 + +#define EMIF_CTL_NANDF4BECCLR 0x00bc + +#define EMIF_CTL_NANDF4BECC1R 0x00c0 +#define EMIF_CTL_NANDF4BECC2R 0x00c4 +#define EMIF_CTL_NANDF4BECC3R 0x00c8 +#define EMIF_CTL_NANDF4BECC4R 0x00cc + +#define EMIF_CTL_NANDFEA1R 0x00d0 +#define EMIF_CTL_NANDFEA2R 0x00d4 + +#define EMIF_CTL_NANDFEV1R 0x00d8 +#define EMIF_CTL_NANDFEV2R 0x00dc + +#define BITMASK(x,y) ( ( ( ((unsigned int)1 << (((unsigned int)x)-((unsigned int)y)+(unsigned int)1) ) - (unsigned int)1 ) ) << ((unsigned int)y) ) +#define READ_BITFIELD(z,x,y) (((unsigned int)z) & BITMASK(x,y)) >> (y) +#define SET_BITFIELD(z,f,x,y) (((unsigned int)z) & ~BITMASK(x,y)) | ( (((UINT32)f) << (y)) & BITMASK(x,y) ) + + +/***************/ +/* Stop the ECC hardware block */ +/***************/ +void stopEcc(void) +{ + dummy = *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_RCSR)); + dummy = *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDF4BECC1R)); +} + + +/***************/ +/* Enable EMIF access for NAND at this chip select */ +/***************/ +void nandEnableRegion(int region) +{ + unsigned int a1cr; + + a1cr = *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_A1CR)); + a1cr = a1cr & ~0x03; + + *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDFCR)) = (1 << region); + + if (busWidth == 16) + { + a1cr = a1cr | 0x01; + } + + *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_A1CR)) = a1cr; +} + + +/***************/ +/* Enable (start) the ECC calculation by the EMIF hardware block */ +/***************/ +void eccEnable(int region) +{ + *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDFCR)) = (1 << region) | (region << 4) | (1 << 12); +} + + +/***************/ +/* */ +/***************/ +void correctDisable (void) +{ + dummy = *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDFEA1R)); +} + + +/***************/ +/* */ +/***************/ +void eccCorrectLoad (unsigned int v) +{ + *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDF4BECCLR)) = v; +} + + +/***************/ +/* */ +/***************/ +void eccWaitCalc (void) +{ + dummy = *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_RCSR)); +} + + +/***************/ +/* Read the ECC data from the hardware */ +/***************/ +void readEccReg (unsigned int *ev) +{ + ev[0] = (*((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDF4BECC1R))) & 0x03ff03ff; + ev[1] = (*((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDF4BECC2R))) & 0x03ff03ff; + ev[2] = (*((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDF4BECC3R))) & 0x03ff03ff; + ev[3] = (*((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDF4BECC4R))) & 0x03ff03ff; +} + + +/***************/ +/* */ +/***************/ +/* returns: + -1 : errors cannot be corrected + 0 : error are not in the data fields + 1 : there are errors to be corrected +*/ +int errAddressRun(void) +{ + unsigned int v; + + *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDFCR)) = (1 << 13); + + do + { + v = *((volatile unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDFSR)); + v = (v >> 8) & 0xff; + } while ( (v != 1) && (v != 2) && (v != 3) ); + + return (v); +} + + +/***************/ +/* */ +/***************/ +int errNumErrors (void) +{ + unsigned int v; + + v = *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDFSR)); + + v = ((v >> 16) & 0x3) + 1; + + return (v); + + +} + + +/***************/ +/* */ +/***************/ +void correct8BitData (unsigned char *p, int n) +{ + unsigned int idx; + unsigned char xor; + + if ((n == 3) || (n == 4)) { + + idx = 519 - *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDFEA1R)); + xor = *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDFEV1R)); + + } else { + + idx = 519 - *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDFEA2R)); + xor = *((unsigned int *)(EMIF_CTL_BASE + EMIF_CTL_NANDFEV2R)); + } + + /* Shift if necessary, mask */ + if ((n == 2) || (n == 4)) { + idx = (idx >> 16); + xor = (xor >> 16); + } + + idx = idx & 0x3ff; + xor = xor & 0x0ff; + + if (idx < 512) + p[idx] ^= xor; + +} + + +volatile unsigned int deld; // Delay variable + + +/***************/ +/* Big delay */ +/***************/ +void bigDelay (void) +{ + for (deld = 0; deld < 10000; deld++); +} + + +/***************/ +/* Small delay */ +/***************/ +void smallDelay(void) +{ + for (deld = 0; deld < 1000; deld++); +} + + +/***************/ +/* Write byte to command latch, CLE, of NAND */ +/***************/ +void command(unsigned int cmd) +{ + *((unsigned char *)(memBase + cmdOffset)) = cmd; +} + + +/***************/ +/* Write byte to address latch, ALE, of NAND */ +/***************/ +void address(unsigned char addr) +{ + *((unsigned char *)(memBase + addrOffset)) = addr; +} + + +/***************/ +/* Read a byte from the data latch of the NAND */ +/***************/ +unsigned char readData8Bit (void) +{ + unsigned char c; + + c = *((unsigned char *)(memBase + dataOffset)); + + return (c); +} + + +/***************/ +/* Write a byte of data to the data latch of the NAND */ +/***************/ +void writeData8Bit (unsigned char c) +{ + *((unsigned char *)(memBase + dataOffset)) = c; +} + + +/***************/ +/* Read the status register */ +/***************/ +void readStatusReg(void) +{ + // Write command to read the status register, delay + command (readStatusRegCmd); + smallDelay (); + + // Read the status data, delay + statusReg = readData8Bit(); + smallDelay (); + + if (statusReg & 0x01) + { + for (;;) + { + } + } + + // Reset the device + command (resetCmd); + bigDelay (); +} + + +/***************/ +/* Read the spare bytes for the specified block/page/segment */ +/***************/ +void readSpareBytes(unsigned int block, unsigned int page, unsigned char *iscratch, int segment) +{ + unsigned int columnAddr; + unsigned int rowAddr; + unsigned char addr[5]; + int i; + + unsigned char *scratch = (unsigned char *)iscratch; + + + // Reset NAND device and delay + command (resetCmd); + bigDelay(); + + // Calculate the column and row addresses for the desired spared bytes + columnAddr = pageSizeBytes + (segment * spareBytesPerSegment); + rowAddr = (block << 6) + page; + if (busWidth == 16) + { + for (;;) + { + } + } + + addr[0] = columnAddr & 0xFF; + addr[1] = (columnAddr >> 8) & 0xFF; + addr[2] = rowAddr & 0xFF; + addr[3] = (rowAddr >> 8) & 0xFF; + addr[4] = (rowAddr >> 16) & 0xFF; + + // Send the read command to the device + command(readPageCmd); + smallDelay(); + + // Send the address bytes to the device + address(addr[0]); + smallDelay(); + + address(addr[1]); + smallDelay(); + + address(addr[2]); + smallDelay(); + + address(addr[3]); + smallDelay(); + + address(addr[4]); + smallDelay(); + + // Send the end of the read command to the device + command(readPageDoneCmd); + bigDelay(); + + if (busWidth == 8) + { + for (i = 0; i < spareBytesPerSegment; i++) + { + scratch[i] = readData8Bit(); + smallDelay (); + } + } + else + { + for (;;) + { + } + } +} + + +/***************/ +/* Check erased block to see if it is good or bad. */ +/***************/ +int blockIsBad(unsigned int n) +{ + int i; + unsigned char *cscratch = (unsigned char *)scratch; + + /* read spare bytes: block n, page 0, segment 0 */ + readSpareBytes(n, 0, scratch, 0); + + if (busWidth == 8) + { + for (i = 0; i < 6; i++) + { + if (cscratch[i] != 0xff) + { + printf ("Block %d should have been erase, but it has bad block mark, page %d! (%02X02X02X02X02X02X)\n", + n, 0, cscratch[0], cscratch[1], cscratch[2], cscratch[3], cscratch[4], cscratch[5]); + return (1); + } + } + } + else + { + for (;;) + { + } + } + + /* read spare bytes: block n, page 0, segment 0 */ + readSpareBytes(n, 1, scratch, 0); + + if (busWidth == 8) + { + for (i = 0; i < 6; i++) + { + if (cscratch[i] != 0xff) + { + printf ("Block %d should have been erase, but it has bad block mark, page %d! (%02X02X02X02X02X02X)\n", + n, 1, cscratch[0], cscratch[1], cscratch[2], cscratch[3], cscratch[4], cscratch[5]); + return (1); + } + } + } + else + { + for (;;) + { + } + } + + /* read spare bytes: block n, page 0, segment 0 */ + readSpareBytes(n, pagesPerBlock - 1, scratch, 0); + + if (busWidth == 8) + { + for (i = 0; i < 6; i++) + { + if (cscratch[i] != 0xff) + { + printf ("Block %d should have been erase, but it has bad block mark, page %d! (%02X02X02X02X02X02X)\n", + n, (pagesPerBlock - 1), cscratch[0], cscratch[1], cscratch[2], cscratch[3], cscratch[4], cscratch[5]); + return (1); + } + } + } + else + { + for (;;) + { + } + } + + // No bad block marks found, return false. + return (0); +} + + +/***************/ +/* Check a block for the manufacturer bad block mark. */ +/* Must use this before erasing a block! */ +/***************/ +int blockIsBadManufacture(unsigned int n) +{ + int i; + int j; + unsigned char *cscratch = (unsigned char *)scratch; + + // "manufactureBadBlockPages" tells us which pages of the block to check + for (j = 0; j < sizeof(manufactureBadBlockPages) / sizeof(unsigned int); j++) + { + /* read spare bytes: block n, page defined above, segment 0 */ + readSpareBytes(n, manufactureBadBlockPages[j], scratch, 0); + + if (busWidth == 8) + { + for (i = 0; i < sizeof(manufactureBadBlockBytes) / sizeof (unsigned int); i++) + { + if (cscratch[manufactureBadBlockBytes[i]] != 0xff) + { + printf ("Block %d should have been erase, but it has bad block mark, page %d! (%02X02X02X02X02X02X)\n", + n, manufactureBadBlockPages[j], cscratch[0], cscratch[1], cscratch[2], cscratch[3], cscratch[4], cscratch[5]); + return (1); + } + } + } + else + { + for (;;) + { + } + } + } + + return (0); +} + + +/***************/ +/* Erase block n */ +/***************/ +void eraseBlock(int n) +{ + unsigned int rowAddr; + unsigned char addr[3]; + + + // Calculate the row address + rowAddr = n << 6; + + addr[0] = rowAddr & 0xFF; + addr[1] = (rowAddr >> 8) & 0xFF; + addr[2] = (rowAddr >> 16) & 0xFF; + + // Send the command and address bytes (with delay) to the device + command (resetCmd); + bigDelay(); + + command (blockEraseACmd); + smallDelay (); + + address (addr[0]); + smallDelay(); + + address (addr[1]); + smallDelay(); + + address (addr[2]); + smallDelay(); + + command (blockEraseBCmd); + bigDelay (); + bigDelay (); + + readStatusReg(); + printf ("Erased block %d, status = 0x%02X\n", n, statusReg); +} + + +/***************/ +/* Read and correct (ECC) a 512-byte segment. */ +/***************/ +void readDeviceId(void) +{ + unsigned char deviceId[5]; + unsigned char onfiId[4]; + unsigned char *p8; + unsigned char idAddr; + int tempIndex; + + + // p8 points to storage for device ID bytes + p8 = (unsigned char *)deviceId; + + /* Reset the device, delay. */ + command (resetCmd); + bigDelay(); + + /* Send 'read ID' command to device, delay */ + command (readIdCmd); + smallDelay(); + + // Send the address bytes to the device (0x00 is regular ID) + idAddr = 0x00; + address(idAddr); + smallDelay(); + + bigDelay(); + + // Read the 5 bytes of the regular ID + for (tempIndex = 0; tempIndex < 5; tempIndex++) + { + p8[tempIndex] = readData8Bit(); + smallDelay(); + } + + printf ("\nDevice ID for MT29F2G08ABDHC is: 0x2CAA901506\n\n"); + + printf ("ID read from device:\n"); + printf ("Device ID[0]: 0x%02X\n", deviceId[0]); + printf ("Device ID[1]: 0x%02X\n", deviceId[1]); + printf ("Device ID[2]: 0x%02X\n", deviceId[2]); + printf ("Device ID[3]: 0x%02X\n", deviceId[3]); + printf ("Device ID[4]: 0x%02X\n\n", deviceId[4]); + + // p8 points to storage for onfi ID bytes + p8 = (unsigned char *)onfiId; + + /* Reset the device, delay. */ + command (resetCmd); + bigDelay(); + + /* Send 'read ID' command to device, delay */ + command (readIdCmd); + smallDelay(); + + // Send the address bytes to the device (0x20 is onfi ID) + idAddr = 0x20; + address(idAddr); + smallDelay(); + + bigDelay(); + + // Read the 4 bytes of the regular ID + for (tempIndex = 0; tempIndex < 4; tempIndex++) + { + p8[tempIndex] = readData8Bit(); + smallDelay(); + } + + printf ("onfi ID[0]: %c (should be \"O\")\n", onfiId[0]); + printf ("onfi ID[1]: %c (should be \"N\")\n", onfiId[1]); + printf ("onfi ID[2]: %c (should be \"F\")\n", onfiId[2]); + printf ("onfi ID[3]: %c (should be \"I\")\n\n", onfiId[3]); +} + + +/***************/ +/* Read and correct (ECC) a 512-byte segment. */ +/***************/ +void readAndCorrectSegment(unsigned int firstBlock, int blockCount, unsigned int pageCount, int segmentCount, unsigned int memOffset) +{ + unsigned int columnAddr; + unsigned int rowAddr; + unsigned char addr[5]; + unsigned char *p8; + unsigned char *pecc; + unsigned int ecc10[8]; + unsigned int eccReg[4]; + unsigned char a; + unsigned char b; + int tempIndex; + int tempReturn; + int numErrors; + + + /* Read the spare area for this page */ + readSpareBytes(firstBlock + blockCount, pageCount, scratch, segmentCount); + + // p8 points to storage are for bytes to be read from NAND + p8 = (unsigned char *) (((unsigned int)readData) + memOffset); + + // Calculate the column and row addresses for of what data should be read from the NAND + columnAddr = segmentCount * 512; + rowAddr = ((firstBlock + blockCount) << 6) + pageCount; + if (busWidth == 16) + { + for (;;) + { + } + } + + addr[0] = columnAddr & 0xFF; + addr[1] = (columnAddr >> 8) & 0xFF; + addr[2] = rowAddr & 0xFF; + addr[3] = (rowAddr >> 8) & 0xFF; + addr[4] = (rowAddr >> 16) & 0xFF; + + /* Reset the device, delay. */ + command (resetCmd); + bigDelay(); + + /* Send 'read' command to device, delay */ + command (readPageCmd); + smallDelay(); + + // Send the address bytes to the device + address(addr[0]); + smallDelay(); + + address(addr[1]); + smallDelay(); + + address(addr[2]); + smallDelay(); + + address(addr[3]); + smallDelay(); + + address(addr[4]); + smallDelay(); + + // Send the end of the read command to the device + command(readPageDoneCmd); + + bigDelay(); + + /* Clear the ECC to start fresh */ + stopEcc(); + + smallDelay(); + + /* Enable the 4 bit ECC through the nand flash control register */ + eccEnable(csRegion); + + if (busWidth == 8) + { + /* Read the 512-byte data segment from the device */ + for (tempIndex = 0; tempIndex < 512; tempIndex++) + { + p8[tempIndex] = readData8Bit(); + } + } + else + { + for (;;); + } + + /* Halt ECC hardware so we can read it. */ + stopEcc (); + + //Read Status Register + readStatusReg(); + + /* Convert the ECC bytes from 10-bit format to 8-bit values. The 1st 6 bytes are not used for ECC. */ + pecc = (unsigned char *) (((unsigned int)scratch) + 6); + + /* Convert the 80 bits of ecc into eight 10 bit values. The byte order here is little endian */ + a = pecc[0] ; + b = READ_BITFIELD(pecc[1], 1, 0); + ecc10[0] = a | (b << 8); + + a = READ_BITFIELD(pecc[1], 7, 2); + a |= (READ_BITFIELD(pecc[2], 1, 0)) << 6; + b = READ_BITFIELD(pecc[2], 3, 2); + ecc10[1] = a | (b << 8); + + a = READ_BITFIELD(pecc[2], 7, 4); + a |= (READ_BITFIELD(pecc[3], 3, 0)) << 4; + b = READ_BITFIELD(pecc[3], 5, 4); + ecc10[2] = a | (b << 8); + + a = READ_BITFIELD(pecc[3], 7, 6); + a |= (READ_BITFIELD(pecc[4], 5, 0)) << 2; + b = READ_BITFIELD(pecc[4], 7, 6); + ecc10[3] = a | (b << 8); + + a = pecc[5]; + b = READ_BITFIELD(pecc[6], 1, 0); + ecc10[4] = a | (b << 8); + + a = READ_BITFIELD(pecc[6], 7, 2); + a |= (READ_BITFIELD(pecc[7], 1, 0)) << 6; + b = READ_BITFIELD(pecc[7], 3, 2); + ecc10[5] = a | (b << 8); + + a = READ_BITFIELD(pecc[7], 7, 4); + a |= (READ_BITFIELD(pecc[8], 3, 0)) << 4; + b = READ_BITFIELD(pecc[8], 5, 4); + ecc10[6] = a | (b << 8); + + a = READ_BITFIELD(pecc[8], 7, 6); + a |= (READ_BITFIELD(pecc[9], 5, 0)) << 2; + b = READ_BITFIELD(pecc[9], 7, 6); + ecc10[7] = a | (b << 8); + + /* Disable any left over error correction */ + correctDisable (); + + for (tempIndex = 7; tempIndex >= 0; tempIndex--) + { + eccCorrectLoad(ecc10[tempIndex]); + } + + eccWaitCalc(); + + readEccReg(eccReg); + + /* 0 values indicates there are no bit errors */ + if ((eccReg[0] == 0) && (eccReg[1] == 0) && (eccReg[2] == 0) && (eccReg[3] == 0)) + { + return; + } + + /* If there are bit errors perform the data correction */ + tempReturn = errAddressRun(); + + if (tempReturn == -1) + { + printf ("There are errors in block %d page %d segment %d that cannot be corrected\n", + firstBlock + blockCount, pageCount, segmentCount); + return; + } + + if (tempReturn == 0) + { + return; /* Errors are not present in the data bits */ + } + + /* Correct the errors */ + numErrors = errNumErrors(); + + for (tempIndex = numErrors; tempIndex >= 1; tempIndex--) + { + if (busWidth == 8) + { + correct8BitData (p8, tempIndex); + } + } +} + + +/***************/ +/* Program a 512-byte segment. */ +/***************/ +void programSegment(unsigned int firstBlock, int blockIdx, unsigned int page, int segmentCount, unsigned int memOffset, unsigned int eccOffset) +{ + unsigned int columnAddr; + unsigned int rowAddr; + unsigned char addr[5]; + unsigned char *p8; + unsigned int eccReg[4]; + unsigned int ecc8[10]; + unsigned char a; + unsigned char b; + int tempIndex; + + + // p8 points to group of bytes to be written to NAND + p8 = (unsigned char *) (((unsigned int)writeData) + memOffset); + + // Calculate the column and row addresses for where the data should be written on the NAND + columnAddr = segmentCount * 512; + rowAddr = ((firstBlock + blockIdx) << 6) + page; + if (busWidth == 16) + { + for (;;) + { + } + } + + addr[0] = columnAddr & 0xFF; + addr[1] = (columnAddr >> 8) & 0xFF; + addr[2] = rowAddr & 0xFF; + addr[3] = (rowAddr >> 8) & 0xFF; + addr[4] = (rowAddr >> 16) & 0xFF; + + /* Reset the device and delay */ + command(resetCmd); + bigDelay(); + + /* Send 'write' command to device, delay. */ + command(programACmd); + smallDelay(); + + // Send the address bytes to the device + address(addr[0]); + smallDelay(); + + address(addr[1]); + smallDelay(); + + address(addr[2]); + smallDelay(); + + address(addr[3]); + smallDelay(); + + address(addr[4]); + smallDelay(); + + bigDelay(); + + /* Clear the ECC to start fresh */ + stopEcc(); + + smallDelay(); + + /* Enable the 4 bit ECC through the nand flash control register */ + eccEnable(csRegion); + + if (busWidth == 8) + { + /* Write the 512-byte data segment to the device */ + for (tempIndex = 0; tempIndex < 512; tempIndex++) + { + writeData8Bit (p8[tempIndex]); + } + } + else + { + for (;;); + } + + /* Halt ECC hardware so we can read it. */ + // stopEcc (); + + /* Read the compuated ECC values and convert them to 10 bytes */ + readEccReg(eccReg); + + /* Send the end of write command to the device */ + command(programBCmd); + bigDelay(); + readStatusReg(); + //printf ("Wrote block %d, segment %d, status = 0x%02X\n", blockIdx, segmentCount, statusReg); + + ecc8[0] = READ_BITFIELD(eccReg[0], 7, 0); + + a = READ_BITFIELD(eccReg[0], 9, 8); + b = READ_BITFIELD(eccReg[0], 21, 16); + ecc8[1] = a | (b << 2); + + a = READ_BITFIELD(eccReg[0], 25, 22); + b = READ_BITFIELD(eccReg[1], 3, 0); + ecc8[2] = a | (b << 4); + + a = READ_BITFIELD(eccReg[1], 9, 4); + b = READ_BITFIELD(eccReg[1], 17, 16); + ecc8[3] = a | (b << 6); + + ecc8[4] = READ_BITFIELD(eccReg[1], 25, 18); + + ecc8[5] = READ_BITFIELD(eccReg[2], 7, 0); + + a = READ_BITFIELD(eccReg[2], 9, 8); + b = READ_BITFIELD(eccReg[2], 21, 16); + ecc8[6] = a | (b << 2); + + a = READ_BITFIELD(eccReg[2], 25, 22); + b = READ_BITFIELD(eccReg[3], 3, 0); + ecc8[7] = a | (b << 4); + + a = READ_BITFIELD(eccReg[3], 9, 4); + b = READ_BITFIELD(eccReg[3], 17, 16); + ecc8[8] = a | (b << 6); + + ecc8[9] = READ_BITFIELD(eccReg[3], 25, 18); + + // Generate the spare bytes for this segment + // 6 bytes of 0xff (no bad block marks) followed by ECC data + for (tempIndex = 0; tempIndex < 6; tempIndex++) + { + spareData[eccOffset + tempIndex] = 0xFF; + } + for (tempIndex = 6; tempIndex < 16; tempIndex++) + { + spareData[eccOffset + tempIndex] = ecc8[tempIndex - 6]; + } + + // Re-calculate the column addresses for writing these spare bytes + // (row address is the same since the block and page are the same)s + columnAddr = pageSizeBytes + (segmentCount * spareBytesPerSegment); + if (busWidth == 16) + { + for (;;) + { + } + } + + addr[0] = columnAddr & 0xFF; + addr[1] = (columnAddr >> 8) & 0xFF; + + /* Reset the device and delay */ + command (resetCmd); + bigDelay(); + + /* Send 'write' command to device, delay. */ + command (programACmd); + smallDelay(); + + // Send the address bytes to the device + address(addr[0]); + smallDelay(); + + address(addr[1]); + smallDelay(); + + address(addr[2]); + smallDelay(); + + address(addr[3]); + smallDelay(); + + address(addr[4]); + smallDelay(); + + bigDelay(); + + if (busWidth == 8) + { + /* Write the spare bytes for this 512-byte data segment to the device */ + for (tempIndex = 0; tempIndex < 16; tempIndex++) + { + writeData8Bit(spareData[eccOffset + tempIndex]); + } + } + else + { + for (;;); + } + + /* Send the end of write command to the device */ + command (programBCmd); + bigDelay (); + readStatusReg (); + //printf ("Wrote spare bytes for block %d, segment %d, status = 0x%02X\n", blockIdx, segmentCount, statusReg); +} + +/***************/ +/* main */ +/***************/ +int main () +{ + + unsigned int nblocks; /* Number of blocks that will be programmed */ + unsigned int bytesPerBlock; + unsigned int memOffset = 0; + unsigned int eccOffset = 0; + unsigned int dataSizeUint8; + + int wordCount; + int blockCount; + int errorCount; + int pageCount; + int tempIndex; + int memOffset_Offset; + int segmentCount; + + printf ("Appleton EVM NAND writer for Micron MT29F2G08xxx devices.\n\n"); + + + if (dataSizeUint32 == 0x00) + { + printf ("Variable \'dataSizeUint32\' is zero.\n"); + printf ("It must be set the the number of words in image!\n"); + printf ("Execution will stall until the variable is updated.\n"); + + while (dataSizeUint32 == 0x00) + { + // Wait until user tells us how much data to program + } + } + + dataSizeUint8 = dataSizeUint32 * 4; + + // Calculate the number of spare bytes per page based on number of spare per segment and number of segments + spareBytesPerPage = spareBytesPerSegment * (pageSizeBytes / 512); + + // Calculate the number of bytes per block based on NAND geometry + bytesPerBlock = pageSizeBytes * pagesPerBlock; + + // Calculate the number of blocks to program based on size of image to write to NAND + nblocks = (dataSizeUint8 + bytesPerBlock - 1) / bytesPerBlock; + + // Calculate the base address of the device in EMIF + memBase = 0x70000000 + (csRegion * 0x04000000); + + /* Configure the nand flash control register */ + nandEnableRegion(csRegion); + + // Read and display the device ID information + readDeviceId(); + + if (doWrite != 0) + { + printf ("Erasing %d blocks starting at block %d\n", nblocks, firstBlock); + + /* Strange for loop here, i is the check, j is incremented */ + for (blockCount = 0; blockCount < nblocks; blockCount++) + { + if (blockIsBadManufacture (firstBlock + blockCount) != 0) + { + printf ("Block %d has been marked bad. Skipping the block (not erased)\n", firstBlock+blockCount); + continue; + } + + eraseBlock (firstBlock + blockCount); + printf ("Block %d erased.\n", firstBlock + blockCount); + } + + printf ("Programming %d blocks starting at block %d\n", nblocks, firstBlock); + + for (blockCount = 0; blockCount < nblocks; blockCount++) + { + printf ("Attempting to program block %d\n", firstBlock + blockCount); + + if (blockIsBad(firstBlock + blockCount) != 0) + { + printf ("Block %d has been marked bad. Skipping the block\n"); + continue; + } + + for (pageCount = 0; pageCount < pagesPerBlock; pageCount++) + { + // File the spare area for this page with 0x55 pattern + for (tempIndex = 0; tempIndex < spareBytesPerPage; tempIndex++) + { + spareData[eccOffset + tempIndex] = 0x55; + } + + //programPage(firstBlock, j, k, memOffset, eccOffset); + + // Program the page, one 512-byte segment at a time + for (memOffset_Offset = segmentCount = 0; memOffset_Offset < pageSizeBytes; memOffset_Offset += 512, segmentCount++) + { + programSegment(firstBlock, blockCount, pageCount, segmentCount, (memOffset + memOffset_Offset), eccOffset); + eccOffset += spareBytesPerSegment; + } + + memOffset += pageSizeBytes; + if (memOffset >= dataSizeUint8) + { + break; + } + } + } + } + + /* Read back the data just written. */ + memOffset = 0; + + for (blockCount = 0; blockCount < nblocks; blockCount++) + { + printf ("Attempting to read block %d\n", firstBlock + blockCount); + + if (blockIsBad(firstBlock + blockCount) != 0) + { + printf ("Block %d has been marked bad. Skipping the block\n"); + continue; + } + + for (pageCount = 0; pageCount < pagesPerBlock; pageCount++) + { + //readPage(firstBlock, blockCount, pageCount, memOffset); + + // Read the page, one 512-byte segment at a time + for (memOffset_Offset = segmentCount = 0; memOffset_Offset < pageSizeBytes; memOffset_Offset += 512, segmentCount++) + { + readAndCorrectSegment(firstBlock, blockCount, pageCount, segmentCount, (memOffset + memOffset_Offset)); + } + + memOffset += pageSizeBytes; + if (memOffset >= dataSizeUint8) + { + break; + } + } + } + + /* Compare the read and write data. */ + for (wordCount = errorCount = 0; wordCount < dataSizeUint32; wordCount++) + { + if (writeData[wordCount] != readData[wordCount]) + { + printf ("Data comparison failure at offset %d (0x%08x). Wrote 0x%08x, read 0x%08x\n", wordCount, wordCount, writeData[wordCount], readData[wordCount]); + + if (++errorCount >= 10) + { + printf ("Too many comparison errors, quiting\n"); + break; + } + } + + } + + if (errorCount == 0) + { + printf ("Data compare complete, no errors\n"); + } +} + diff --git a/boot_loader/uboot/nandwriter/nandwrite.cmd b/boot_loader/uboot/nandwriter/nandwrite.cmd new file mode 100644 index 0000000..483085e --- /dev/null +++ b/boot_loader/uboot/nandwriter/nandwrite.cmd @@ -0,0 +1,57 @@ + +/* source files */ +nandwrite.obj + +/* opts */ +-c +-a +-stack 0x400 + + +MEMORY +{ + TCODE: origin = 0x800000 length = 0x10000 + DATA: origin = 0x810000 length = 0x10000 + STACK: origin = 0x820000 length = 0x400 + + WRITE_BUF : origin = 0x0c000000 length = 0x40000 + READ_BUF : origin = 0x0c040000 length = 0x40000 + SPARE_BUF : origin = 0x0c080000 length = 0x20000 + SCRATCH_BUF : origin = 0x0c0a0000 length = 0x20000 +} + +SECTIONS +{ + .text > TCODE + + .data > DATA + .far > DATA + .const > DATA + .switch > DATA + .bss > DATA + .cinit > DATA + + .stack > STACK + + .d1 > WRITE_BUF + { + _writeBlock = .; + } + + .d2 > READ_BUF + { + _readBlock = .; + } + + .d3 > SPARE_BUF + { + _spareBlock = .; + } + + .d4 > SCRATCH_BUF + { + _scratchBlock = .; + } +} + + diff --git a/boot_loader/uboot/readme.txt b/boot_loader/uboot/readme.txt new file mode 100644 index 0000000..25e774e --- /dev/null +++ b/boot_loader/uboot/readme.txt @@ -0,0 +1,52 @@ +Notes: + +There are two folders in the uboot tools directory: + +1. utils +Contains the utilities to convert U-Boot image to an RBL readable image format. mingw and msys +tools are required to build the utilities. Please refer to the release notes for tools detail. + +2. nanwriter +Contains the writer utility (running on the DSP) to burn the U-Boot image. C6000 Code Gen +tools are required to build the utilities. Please refer to the release notes for tools detail. + +The NAND writer is only a TEMPORARY solution (only supported in Alpha-2 release). In alpha-3 release, +U-Boot itself will support burning the U-Boot image to the NAND. + + +Steps to build the utilities and the nandwriter: + +1. Copy the binary raw image u-boot.bin to uboot\nandwriter folder +2. Modify build_writer.bat if necessary to set the mingw and msys path and the C6000 Code Gen tool path +3. Run the build_writer.bat + +A new CCS data image u-boot.dat will be generated under uboot\nandwriter. + + +Steps to use the nandwriter to burn the U-Boot image: + +1. Be sure the boot dip switch is set to ARM master no boot mode on the TCI6614 EVM: + SW3 (p4,p3,p2,p1) = on,on,on,off + SW4 (p4,p3,p2,p1) = on,on,on,on + SW5 (p4,p3,p2,p1) = on,on,on,on + SW6 (p4,p3,p2,p1) = on,on,on,on + SW2 (p4,p3,p2,p1) = on,on,off,on + +2. Launch TCI6614 target in CCS and connect to C66xx-1 DSP core + +3. Load the u-boot.dat using CCS Memory browser with Start Address 0x0c00_0000 and length 0x20000 words + +4. Run the DSP and the writer will write the U-Boot image to the first 4 NAND blocks + +5. Set the boot dip switch to ARM master NAND boot mode on the TCI6614 EVM + SW3 (p4,p3,p2,p1) = on,on,on,off + SW4 (p4,p3,p2,p1) = off,on,on,on + SW5 (p4,p3,p2,p1) = off,off,off,off + SW6 (p4,p3,p2,p1) = off,on,on,on + SW2 (p4,p3,p2,p1) = on,on,off,off + +6. Connect the UART cable to PC with Tera/Hyper Term running at 115200 baud rate, 8-bit data, parity none, + 1-bit stop, flow control none + +7. Do system reset using CCS, U-Boot should be able to boot and print the booting info to the UART. +There is a known issue that the reset/power cycle the board will not boot the U-Boot image from the NAND. diff --git a/boot_loader/uboot/utils/Makefile b/boot_loader/uboot/utils/Makefile new file mode 100644 index 0000000..237f272 --- /dev/null +++ b/boot_loader/uboot/utils/Makefile @@ -0,0 +1,54 @@ +#/* +# * +# * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ +# * +# * +# * Redistribution and use in source and binary forms, with or without +# * modification, are permitted provided that the following conditions +# * are met: +# * +# * Redistributions of source code must retain the above copyright +# * notice, this list of conditions and the following disclaimer. +# * +# * Redistributions in binary form must reproduce the above copyright +# * notice, this list of conditions and the following disclaimer in the +# * documentation and/or other materials provided with the +# * distribution. +# * +# * Neither the name of Texas Instruments Incorporated nor the names of +# * its contributors may be used to endorse or promote products derived +# * from this software without specific prior written permission. +# * +# * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# * +#*/ + +TARGETS= ccsutil.o ccsAddGphdr.exe ccsAddGptlr.exe bin2ccs.exe byteswapccs.exe + +all: $(TARGETS) + + +ccsutil.o: ccsutil.c ccsutil.h + gcc -g -c ccsutil.c + +ccsAddGphdr.exe: ccsAddGphdr.c ccsutil.o + gcc -g -o $@ ccsAddGphdr.c ccsutil.o + +ccsAddGptlr.exe: ccsAddGptlr.c ccsutil.o + gcc -g -o $@ ccsAddGptlr.c ccsutil.o + +bin2ccs.exe: bin2ccs.c + gcc -g -o $@ bin2ccs.c + +byteswapccs.exe: byteswapccs.c + gcc -g -o $@ byteswapccs.c \ No newline at end of file diff --git a/boot_loader/uboot/utils/bin2ccs.c b/boot_loader/uboot/utils/bin2ccs.c new file mode 100644 index 0000000..8b266c6 --- /dev/null +++ b/boot_loader/uboot/utils/bin2ccs.c @@ -0,0 +1,143 @@ +/* + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ +/********************************************************************************************** + * FILE PURPOSE: Convert a binary file to CCS format + ********************************************************************************************** + * FILE NAME: bin2ccs.c + * + * DESCRIPTION: The binary file is converted to an ascii file in CCS data format + * + **********************************************************************************************/ + +#include +#include + +/********************************************************************************************** + * FUNCTION PURPOSE: Form a 32 bit value from an unsigned byte array + ********************************************************************************************** + * DESCRIPTION: The value is formed and padded if required + **********************************************************************************************/ +unsigned int formInt (unsigned char *c, unsigned int i, unsigned int len) +{ + unsigned int x = 0; + + if (i < len) + x = x | (c[i] << 24); + + if ((i+1) < len) + x = x | (c[i+1] << 16); + + if ((i+2) < len) + x = x | (c[i+2] << 8); + + if ((i+3) < len) + x = x | c[i+3]; + + return (x); + +} + +int main (int argc, char *argv[]) +{ + FILE *fil; + unsigned char *cdat; + unsigned int len; + unsigned int i; + + + if (argc != 3) { + fprintf (stderr, "usage: %s infile outfile\n", argv[0]); + return (-1); + } + + fil = fopen (argv[1], "rb"); + if (fil == NULL) { + fprintf (stderr, "%s: Failed to open input file %s\n", argv[0], argv[1]); + return (-1); + } + + fseek (fil, 0, SEEK_END); + len = ftell (fil); + fclose (fil); + + cdat = malloc (len * sizeof (unsigned char)); + if (cdat == NULL) { + fprintf (stderr, "%s: Failed to malloc %d bytes\n", argv[0], len); + return (-1); + } + + fil = fopen (argv[1], "rb"); + if (fil == NULL) { + fprintf (stderr, "%s: Failed to open input file %s\n", argv[0], argv[1]); + return (-1); + } + + fread (cdat, sizeof(unsigned char), len, fil); + + fclose (fil); + + + fil = fopen (argv[2], "w"); + if (fil == NULL) { + fprintf (stderr, "%s: Error opening output file %s\n", argv[0], argv[1]); + free (cdat); + return (-1); + } + + /* The ccs header */ + fprintf (fil, "1651 1 10000 1 %x\n", (len + 3) / 4); + + + /* The data */ + for (i = 0; i < len; i += 4) + fprintf (fil, "0x%08x\n", formInt(cdat, i, len)); + + + fclose (fil); + free (cdat); + + return (0); + +} + + + + + + + + + + diff --git a/boot_loader/uboot/utils/byteswapccs.c b/boot_loader/uboot/utils/byteswapccs.c new file mode 100644 index 0000000..4b718fb --- /dev/null +++ b/boot_loader/uboot/utils/byteswapccs.c @@ -0,0 +1,116 @@ +/* + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ +/******************************************************************************************** + * FILE PURPOSE: Byte swap a CCS data file + ******************************************************************************************** + * FILE NAME: byteswapccs.c + * + * DESCRIPTION: A CCS file is read in, the data is byte swapped, and a CCS file is written out + * + * usage: byteswapccs infile outfile + * + ********************************************************************************************/ +#include +#include + + +int main (int argc, char *argv[]) +{ + FILE *fin, *fout; + unsigned int v, b0, b1, b2, b3; + int a, b, c, d, n; + int i; + char iline[132]; + + + if (argc != 3) { + fprintf (stderr, "usage: %s infile outfile\n", argv[0]); + return (-1); + } + + + fin = fopen (argv[1], "r"); + if (fin == NULL) { + fprintf (stderr, "%s: Could not open input file %s\n", argv[1]); + return (-1); + } + + fout = fopen (argv[2], "w"); + if (fout == NULL) { + fprintf (stderr, "%s: Could not open output file %s\n", argv[2]); + fclose (fin); + return (-1); + } + + + /* Read the CCS data file header, write it out unchanged */ + fgets (iline, 132, fin); + sscanf (iline, "%x %x %x %x %x", &a, &b, &c, &d, &n); + fputs (iline, fout); + + for (i = 0; i < n; i++) { + fgets (iline, 132, fin); + sscanf (&iline[2], "%x", &v); + + b0 = (v >> 24) & 0xff; + b1 = (v >> 16) & 0xff; + b2 = (v >> 8) & 0xff; + b3 = (v >> 0) & 0xff; + + v = (b3 << 24) | (b2 << 16) | (b1 <<8) | b0; + fprintf (fout, "0x%08x\n", v); + } + + fclose (fout); + fclose (fin); + + return (0); + +} + + + + + + + + + + + + + + + diff --git a/boot_loader/uboot/utils/ccsAddGphdr.c b/boot_loader/uboot/utils/ccsAddGphdr.c new file mode 100644 index 0000000..c680354 --- /dev/null +++ b/boot_loader/uboot/utils/ccsAddGphdr.c @@ -0,0 +1,176 @@ +/* + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ +/***************************************************************************** + * FILE PURPOSE: Add a GP header to a CCS data file + ****************************************************************************** + * FILE NAME: ccsAddGphdr.c + * + * Description: Adds the two word GP header to a ccs data file + * + * usage: ccsAddGphdr baseAddress [-infile infile] [-outfile outfile] + * + ******************************************************************************/ +#include +#include +#include "ccsutil.h" + +char *infile = NULL; +char *outfile = NULL; +unsigned int baseAddress = 0xffffffff; + + +unsigned int readInt (char *c) +{ + unsigned int v; + + if ((c[0] == '0') && (c[1] == 'x')) + sscanf (&c[2], "%x", &v); + + else + sscanf (c, "%d", &v); + + return (v); + +} + +int parseit (int ac, char *av[]) +{ + int i; + + if (ac == 1) { + fprintf (stderr, "usage: %s baseAddress [-infile infile] [-outfile outfile]\n", av[0]); + return (-1); + } + + for (i = 1; i < ac; ) { + + if (!strcmp(av[i], "-infile")) { + infile = av[i+1]; + i = i + 2; + + } else if (!strcmp(av[i], "-outfile")) { + outfile = av[i+1]; + i = i + 2; + + } else { + + baseAddress = readInt (av[i]); + i = i + 1; + } + + } + + if (baseAddress == 0xffffffff) { + fprintf (stderr, "%s error: baseAddress not specified\n", av[0]); + return (-1); + } + + return (0); + +} + + +int main (int argc, char *argv[]) +{ + FILE *str; + unsigned int *data1, *data2; + int nwords; + int i; + + if (parseit (argc, argv) != 0) + return (-1); + + if (infile != NULL) { + str = fopen (infile, "r"); + if (str == NULL) { + fprintf (stderr, "%s error: failed to open file %s\n", argv[0], infile); + return (-1); + } + } else { + str = stdin; + } + + data1 = readCcsFile (str, &nwords); + + if (infile != NULL) + fclose (str); + + if (data1 == NULL) { + fprintf (stderr, "%s error: read ccs file returned error\n", argv[0]); + return (-1); + } + + data2 = malloc ((nwords + 2) * sizeof(unsigned int)); + if (data2 == NULL) { + fprintf (stderr, "%s error: malloc failed on %d unsigned ints\n", argv[0], nwords + 2); + free (data1); + return (-1); + } + + data2[0] = nwords * 4; + data2[1] = baseAddress; + + for (i = 0; i < nwords; i++) + data2[i+2] = data1[i]; + + free (data1); + + if (outfile != NULL) { + str = fopen (outfile, "w"); + if (str == NULL) { + fprintf (stderr, "%s error: failed to open file %s\n", argv[0], outfile); + return (-1); + } + } else { + str = stdout; + } + + writeCcsFile (str, data2, nwords+2); + + free (data2); + + if (outfile != NULL) + fclose (str); + + return (0); + +} + + + + + + + diff --git a/boot_loader/uboot/utils/ccsAddGptlr.c b/boot_loader/uboot/utils/ccsAddGptlr.c new file mode 100644 index 0000000..a63f6aa --- /dev/null +++ b/boot_loader/uboot/utils/ccsAddGptlr.c @@ -0,0 +1,160 @@ +/* + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ +/****************************************************************************** + * FILE PURPOSE: Add a GP Trailer to a CCS file + ****************************************************************************** + * FILE NAME: ccsAddGptlr.c + * + * DESCRIPTION: Adds the 8 byte General Purpose Trailer + * + * Usage: ccsAddGptlr [-h] [-infile infile] [-outfile outfile] + * + ******************************************************************************/ +#include +#include +#include +#include "ccsutil.h" + +char *infile = NULL; +char *outfile = NULL; + +int parseit (int ac, char *av[]) +{ + + int i; + + for (i = 1; i < ac; ) { + + if (!strcmp (av[i], "-infile")) { + infile = av[i+1]; + i = i + 2; + continue; + } + + if (!strcmp (av[i], "-outfile")) { + outfile = av[i+1]; + i = i + 2; + continue; + } + + if (!strcmp (av[i], "-h")) { + fprintf (stderr, "usage: %s [-h] [-infile infile] [-outfile outfile]\n", av[0]); + return (-1); + } + + fprintf (stderr, "%s: Unknown option %s\n", av[0], av[i]); + return (-1); + + } + + return (0); + +} + + +int main (int argc, char *argv[]) +{ + FILE *str; + unsigned int *dat; + int n; + + if (parseit (argc, argv)) + return (-1); + + + if (infile != NULL) { + + str = fopen (infile, "r"); + if (str == NULL) { + fprintf (stderr, "%s: Failed to open input file %s\n", argv[0], infile); + return (-1); + } + + } else { + + str = stdin; + + } + + dat = readCcsFile (str, &n); + + if (dat == NULL) { + + fprintf (stderr, "%s: Error reading CCS data file\n", argv[0]); + return (-1); + + } + + if (infile != NULL) + fclose (str); + + + dat = realloc (dat, (n+2) * sizeof(unsigned int)); + if (dat == NULL) { + fprintf (stderr, "%s: Realloc failed\n", argv[0]); + return (-1); + } + + dat[n+0] = 0; + dat[n+1] = 0; + n = n + 2; + + if (outfile != NULL) { + + str = fopen (outfile, "w"); + if (str == NULL) { + fprintf (stderr, "%s: Failed to open output file %s\n", argv[0], outfile); + free (dat); + return (-1); + } + + } else { + + str = stdout; + + } + + writeCcsFile (str, dat, n); + + if (outfile != NULL) + fclose (str); + + free (dat); + + return (0); + +} + + diff --git a/boot_loader/uboot/utils/ccsutil.c b/boot_loader/uboot/utils/ccsutil.c new file mode 100644 index 0000000..2c631a4 --- /dev/null +++ b/boot_loader/uboot/utils/ccsutil.c @@ -0,0 +1,195 @@ +/* + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ +/********************************************************************************** + * FILE PURPOSE: General purpose CCS utility functions + ********************************************************************************** + * FILE NAME: ccsutil.c + * + * DESCRIPTION: Common functions which make use of ccs files + * + **********************************************************************************/ +#include +#include +#include "ccsutil.h" + + +/********************************************************************************** + * FUNCTION PURPOSE: Read a CCS data file + ********************************************************************************** + * DESCRIPTION: An array is allocated and the CCS data file is read + **********************************************************************************/ +unsigned int *readCcsFile (FILE *str, int *nwords) +{ + int a, b, c, d, e, i; + unsigned int *cf; + char iline[132]; + + fgets (iline, 132, str); + sscanf (iline, "%x %x %x %x %x", &a, &b, &c, &d, &e); + + cf = malloc (e * sizeof (unsigned int)); + if (cf == NULL) { + *nwords = -1; + return (NULL); + } + + for (i = 0; i < e; i++) { + fgets (iline, 132, str); + sscanf (&iline[2], "%x", &cf[i]); + } + + *nwords = e; + return (cf); + +} + + +/**************************************************************************************** + * FUNCTION PURPOSE: Write a CCS data file + **************************************************************************************** + * DESCRIPTION: Data in the the array is written out + ****************************************************************************************/ +int writeCcsFile (FILE *str, unsigned int *data, int nwords) +{ + int i; + + fprintf (str, "1651 1 10000 1 %x\n", nwords); + + for (i = 0; i < nwords; i++) + fprintf (str, "0x%08x\n", data[i]); + + return (0); + +} + + +/**************************************************************************************** + * FUNCTION PURPOSE: Write a CCS data file in upper case + **************************************************************************************** + * DESCRIPTION: Data in the the array is written out in upper case + ****************************************************************************************/ +int writeCcsFileUp (FILE *str, unsigned int *data, int nwords) +{ + int i; + + fprintf (str, "1651 1 10000 1 %X\n", nwords); + + for (i = 0; i < nwords; i++) + fprintf (str, "0x%08X\n", data[i]); + + return (0); + +} + + +/****************************************************************************************** + * FUNCTION PURPOSE: Endian swap a data array + ****************************************************************************************** + * DESCRIPTION: All the values in the array are endian swapped + ******************************************************************************************/ +void ccsEndianSwap (unsigned int *data, int nwords) +{ + int i; + unsigned int v; + + for (i = 0; i < nwords; i++) { + + v = (((data[i] >> 24) & 0xff) << 0) | + (((data[i] >> 16) & 0xff) << 8) | + (((data[i] >> 8) & 0xff) << 16) | + (((data[i] >> 0) & 0xff) << 24) ; + + data[i] = v; + } + +} + + +/****************************************************************************************** + * FUNCTION PURPOSE: Open a file, read the CCS data, close the file + ****************************************************************************************** + * DESCRIPTION: Reads a CCS data file + ******************************************************************************************/ +unsigned int *openReadCloseCcsFile (char *fname, int *size) +{ + unsigned int *dat; + + FILE *str; + + str = fopen (fname, "r"); + + if (str == NULL) { + *size = -1; + return (NULL); + } + + + dat = readCcsFile (str, size); + + fclose (str); + + return (dat); + +} + + +/****************************************************************************************** + * FUNCTION PURPOSE: Open a file, write CCS data, close the file + ****************************************************************************************** + * DESCRIPTION: Writes a CCS data file + ******************************************************************************************/ +int openWriteCloseCcsFile (char *fname, unsigned int *data, int nwords) +{ + FILE *str; + + str = fopen (fname, "w"); + + if (str == NULL) + return (-1); + + + writeCcsFile (str, data, nwords); + + fclose (str); + + return (0); + +} + + + + + + diff --git a/boot_loader/uboot/utils/ccsutil.h b/boot_loader/uboot/utils/ccsutil.h new file mode 100644 index 0000000..50174a9 --- /dev/null +++ b/boot_loader/uboot/utils/ccsutil.h @@ -0,0 +1,59 @@ +/* + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ +#ifndef _CCSUTIL_H +#define _CCSUTIL_H +/******************************************************************************* + * FILE PURPOSE: Define the API for the ccs utility functions + ******************************************************************************* + * FILE NAME: ccsutil.h + * + * DESCRIPTION: Defines the API to the CCS utility functions + *******************************************************************************/ +unsigned int *readCcsFile (FILE *str, int *nwords); +int writeCcsFile (FILE *str, unsigned int *data, int nwords); +int writeCcsFileUp (FILE *str, unsigned int *data, int nwords); +void ccsEndianSwap (unsigned int *data, int nwords); +int openWriteCloseCcsFile (char *fname, unsigned int *data, int nwords); +unsigned int *openReadCloseCcsFile (char *fname, int *size); + + + + + + + + +#endif /* _CCSUTIL_H */ + diff --git a/boot_loader/uboot/utils/make_util b/boot_loader/uboot/utils/make_util new file mode 100644 index 0000000..293faed --- /dev/null +++ b/boot_loader/uboot/utils/make_util @@ -0,0 +1 @@ +make -f Makefile