From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ulf Samuelsson Date: Wed, 30 May 2007 00:13:45 +0200 Subject: [U-Boot-Users] Question about CFG_ENV_ADDR during RAMBOOT In-Reply-To: <20070529001021.531C2353428@atlas.denx.de> References: <20070529001021.531C2353428@atlas.denx.de> Message-ID: <465CA599.7070704@atmel.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de This patch is obviously not going to be accepted in the main tree... Here is my patch to allow * cp.b from SDRAM to dataflash with CRC calculation and storage * cp.b from dataflash to SDRAM with CRC calculation and check * compare dataflash to SDRAM. Looks like it disappeared from the 1.1.2-atmel version by mistake. The reason for adding the CRC is that the CRC check used when booting the kernel does not really trigger the user to think along the right lines. If you write the kernel after the root fs, you overwrite the beginning of the root fs if the kernel does not fit. If you write the kernel before you write the root fs, you will overwrite the last part of the kernel if the kernel does not fit. By doing the crc check when copying from the dataflash to SDRAM you immediately pinpoint the problem. If U-Boot contained a command to write the kernel to dataflash, then this command could check that the image fits into the partition allocated for the kernel, and would report a "kernel too large" warning message. diff -urN u-boot-1.1.4-0rig/common/cmd_mem.c u-boot-1.1.4/common/cmd_mem.c --- u-boot-1.1.4-0rig/common/cmd_mem.c 2006-08-18 18:35:32.000000000 +0200 +++ u-boot-1.1.4/common/cmd_mem.c 2006-08-18 19:32:33.000000000 +0200 @@ -64,6 +64,7 @@ } #endif + #if (CONFIG_COMMANDS & CFG_CMD_MEMORY) #ifdef CMD_MEM_DEBUG @@ -71,6 +72,63 @@ #else #define PRINTF(fmt,args...) #endif +#ifdef CONFIG_HAS_DATAFLASH +#define DF_PAGE_VALID 0x01 +typedef unsigned char dfpagebuf[CFG_DATAFLASH_PAGE_SIZE]; +dfpagebuf dfcache[3]; // Cache buffers for dataflash +unsigned char dfvalid[3]; // if DF_PAGE_VALID is set, then the, cache buffer contents are valid +unsigned char dflru[3]; // Least recently used algorithm to determine which buffer to reuse +unsigned int dfpage[3]; // TLB for cache, tells which page is loaded into dfcache + +void flush_dfcache(void) +{ + dfvalid[0] = dfvalid[1] = dfvalid[2] = 0; + dflru[0] = 0; + dflru[1] = 1; + dflru[2] = 2; +} + +ulong translate(unsigned int addr) +{ + unsigned int page = (addr) / CFG_DATAFLASH_PAGE_SIZE; + unsigned int index = (addr) - (page * CFG_DATAFLASH_PAGE_SIZE); + unsigned int i,rc; + for(i = 0; i < 2; i++) { + if((page == dfpage[i]) && (dfvalid[i] & DF_PAGE_VALID)) { + if(dflru[0] == i) { + // nothing + } else if(dflru[1] == i) { + // swap with 0 + dflru[1] = dflru[0]; + dflru[0] = i; + } else { + // shift down + dflru[2] = dflru[1]; + dflru[1] = dflru[0]; + dflru[0] = i; + } + return (unsigned int) &dfcache[i][index]; + } + } + // not found + // use buffer found in dflru[2] + i = dflru[2]; + if ((rc = read_dataflash(addr, CFG_DATAFLASH_PAGE_SIZE, dfcache[i])) == DATAFLASH_OK){ + dflru[2] = dflru[1]; + dflru[1] = dflru[0]; + dflru[0] = i; + dfvalid[i] |= DF_PAGE_VALID; + return (unsigned int) &dfcache[i][index]; + } + return 0; +} +void df_writed(unsigned char *ldest, ulong laddr) +{ + +} +void df_writew(unsigned char *ldest,ushort laddr) {} +void df_writeb(unsigned char *ldest, u_char laddr) {} +#endif static int mod_mem(cmd_tbl_t *, int, int, int, char *[]); @@ -316,6 +374,7 @@ int do_mem_cmp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong addr1, addr2, count, ngood; + ulong laddr1, laddr2; int size; int rcode = 0; @@ -338,12 +397,57 @@ count = simple_strtoul(argv[3], NULL, 16); #ifdef CONFIG_HAS_DATAFLASH +/* if (addr_dataflash(addr1) | addr_dataflash(addr2)){ puts ("Comparison with DataFlash space not supported.\n\r"); return 0; } +*/ + if (addr_dataflash(addr1) | addr_dataflash(addr2)){ + flush_dfcache(); + ngood = 0; + while (count-- > 0) { + laddr1 = translate((unsigned int) addr1); + laddr2 = translate((unsigned int) addr2); + if (size == 4) { + ulong word1 = *(ulong *)laddr1; + ulong word2 = *(ulong *)laddr2; + if (word1 != word2) { + printf("word at 0x%08lx (0x%08lx) " + "!= word at 0x%08lx (0x%08lx)\n", + laddr1, word1, laddr2, word2); + rcode = 1; + break; + } + } + else if (size == 2) { + ushort hword1 = *(ushort *)laddr1; + ushort hword2 = *(ushort *)laddr2; + if (hword1 != hword2) { + printf("halfword at 0x%08lx (0x%04x) " + "!= halfword at 0x%08lx (0x%04x)\n", + laddr1, hword1, laddr2, hword2); + rcode = 1; + break; + } + } + else { + u_char byte1 = *(u_char *)laddr1; + u_char byte2 = *(u_char *)laddr2; + if (byte1 != byte2) { + printf("byte at 0x%08lx (0x%02x) " + "!= byte at 0x%08lx (0x%02x)\n", + laddr1, byte1, laddr2, byte2); + rcode = 1; + break; + } + } + ngood++; + addr1 += size; + addr2 += size; + } + } else { #endif - ngood = 0; while (count-- > 0) { @@ -384,6 +488,10 @@ addr1 += size; addr2 += size; } +#ifdef CONFIG_HAS_DATAFLASH + } +#endif + printf("Total of %ld %s%s were the same\n", ngood, size == 4 ? "word" : size == 2 ? "halfword" : "byte", @@ -484,11 +592,30 @@ /* Check if we are copying from RAM or Flash to DataFlash */ if (addr_dataflash(dest) && !addr_dataflash(addr)){ int rc; +#ifdef CONFIG_DATAFLASH_CRC + unsigned int crc; + unsigned char *p; + puts ("Copy to DataFlash with CRC... "); + crc = crc32 (0, (const uchar *) addr, count*size); + // Save CRC in small endian format + printf("0x%08x written to [%08x] ... ",crc,(unsigned int) (dest + count * size)); + p = (unsigned char *) addr+(count*size); + *p++ = (unsigned char) crc & 0xff; + crc >>= 8; + + *p++ = (unsigned char) crc & 0xff; + crc >>= 8; - puts ("Copy to DataFlash... "); + *p++ = (unsigned char) crc & 0xff; + crc >>= 8; - rc = write_dataflash (dest, addr, count*size); + *p = (unsigned char) crc & 0xff; + rc = write_dataflash (dest, addr, count*size+4); +#else + puts ("Copy to DataFlash... "); + rc = write_dataflash (dest, addr, count*size); +#endif if (rc != 1) { dataflash_perror (rc); return (1); @@ -504,17 +631,70 @@ #endif ){ int rc; +#ifdef CONFIG_DATAFLASH_CRC + unsigned char *p; + unsigned int crc,oldcrc; + puts ("Copy from DataFlash with CRC..."); + rc = read_dataflash(addr, (count * size)+4, (char *) dest); + if (rc != 1) { + dataflash_perror (rc); + return (1); + } + // Read CRC in small endian format, MSB first + + p = (unsigned char *) dest + (count * size) + 3; + oldcrc = *p--; + oldcrc = (oldcrc << 8) | *p--; + oldcrc = (oldcrc << 8) | *p--; + oldcrc = (oldcrc << 8) | *p; + crc = crc32 (0, (const uchar *) dest, count*size); + if(crc != oldcrc) { + printf("\n\rBad CRC, %x expected, found %x... \n\r",oldcrc,crc); + return 1; + } else { + printf("[0x%x]",crc); + } +#else + puts ("Copy from DataFlash..."); rc = read_dataflash(addr, count * size, (char *) dest); if (rc != 1) { dataflash_perror (rc); return (1); } +#endif + if (rc != 1) { + dataflash_perror (rc); + return (1); + } + puts ("done\n\r"); return 0; } if (addr_dataflash(addr) && addr_dataflash(dest)){ - puts ("Unsupported combination of source/destination.\n\r"); + puts ("Cannot copy between two dataflash areas\n\r"); return 1; +#if 0 + unsigned int addr_page = (unsigned int) addr / CFG_DATAFLASH_PAGE_SIZE ; + unsigned int dest_page = (unsigned int) dest / CFG_DATAFLASH_PAGE_SIZE; + unsigned char *ldest,*laddr; if(addr_page == dest_page) + puts ("Cannot copy within same page\n\r"); + return 1; + } + flush_dfcache(); + // Read into buffer 0 + while (count-- > 0) { + laddr = translate(addr); // Read source page if not inside + ldest = translate(dest); // Read dest page if not inside + if (size == 4) + df_writed(ldest, *((ulong *)laddr); + else if (size == 2) + df_writew(ldest,*((ushort *)laddr); + else + df_writeb(ldest, *((u_char *)laddr); + addr += size; + dest += size; + } +#endif } #endif -- Best Regards, Ulf Samuelsson ulf at atmel.com Atmel Nordic AB Mail: Box 2033, 174 02 Sundbyberg, Sweden Visit: Kavalleriv?gen 24, 174 58 Sundbyberg, Sweden Phone +46 (8) 441 54 22 Fax +46 (8) 441 54 29 GSM +46 (706) 22 44 57 Technical support when I am not available: AT90 AVR Applications Group: mailto:avr at atmel.com AT91 ARM Applications Group: mailto:at91support at atmel.com links: www.avrfreaks.net; www.at91.com; avr32linux.org -------------- next part -------------- A non-text attachment was scrubbed... Name: ulf.vcf Type: text/x-vcard Size: 301 bytes Desc: not available Url : http://lists.denx.de/pipermail/u-boot/attachments/20070530/7eaf41d0/attachment.vcf