From: Ulf Samuelsson <ulf@atmel.com>
To: u-boot@lists.denx.de
Subject: [U-Boot-Users] Question about CFG_ENV_ADDR during RAMBOOT
Date: Wed, 30 May 2007 00:13:45 +0200 [thread overview]
Message-ID: <465CA599.7070704@atmel.com> (raw)
In-Reply-To: <20070529001021.531C2353428@atlas.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
next prev parent reply other threads:[~2007-05-29 22:13 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-05-26 10:53 [U-Boot-Users] Question about CFG_ENV_ADDR during RAMBOOT Ulf Samuelsson
2007-05-26 13:15 ` Wolfgang Denk
2007-05-28 11:37 ` Ladislav Michl
2007-05-28 14:08 ` Ulf Samuelsson
2007-05-28 15:39 ` Ladislav Michl
2007-05-28 16:16 ` Håvard Skinnemoen
2007-05-28 16:56 ` Ulf Samuelsson
2007-05-28 19:39 ` Ladislav Michl
2007-05-29 0:10 ` Wolfgang Denk
2007-05-29 22:13 ` Ulf Samuelsson [this message]
2007-05-29 22:46 ` Wolfgang Denk
2007-05-29 23:15 ` Ulf Samuelsson
2007-05-29 23:39 ` Wolfgang Denk
2007-05-30 0:46 ` Ulf Samuelsson
2007-05-30 6:57 ` Wolfgang Denk
2007-05-30 10:52 ` Ladislav Michl
2007-05-30 13:43 ` Wolfgang Denk
2007-05-30 18:11 ` Ulf Samuelsson
-- strict thread matches above, loose matches on Subject: below --
2007-05-30 11:34 Ulf Samuelsson
2007-05-30 12:16 ` Ladislav Michl
2007-05-30 13:47 ` Wolfgang Denk
2007-05-30 18:23 ` Ulf Samuelsson
2007-05-30 23:19 ` Wolfgang Denk
2007-05-16 19:58 Timur Tabi
2007-05-22 20:36 ` Timur Tabi
2007-05-22 20:53 ` Jerry Van Baren
2007-05-22 21:04 ` Wolfgang Denk
2007-05-22 21:07 ` Timur Tabi
2007-05-23 0:15 ` Wolfgang Denk
2007-05-23 15:58 ` Timur Tabi
2007-05-22 21:26 ` Jerry Van Baren
2007-05-22 21:20 ` Andy Fleming
2007-05-22 21:22 ` Timur Tabi
2007-05-23 0:17 ` Wolfgang Denk
2007-05-23 14:56 ` Timur Tabi
2007-05-22 21:00 ` Wolfgang Denk
2007-05-22 21:30 ` Andy Fleming
2007-05-23 10:04 ` Ladislav Michl
2007-05-23 10:48 ` Ulf Samuelsson
2007-05-23 11:39 ` Ladislav Michl
2007-05-23 12:52 ` Ulf Samuelsson
2007-05-23 13:57 ` Wolfgang Denk
2007-05-23 16:19 ` Ulf Samuelsson
2007-05-24 12:10 ` Ladislav Michl
2007-05-24 13:03 ` Wolfgang Denk
2007-05-24 13:34 ` Ladislav Michl
2007-05-24 19:08 ` Ulf Samuelsson
2007-05-24 21:11 ` Wolfgang Denk
2007-05-24 21:43 ` Ulf Samuelsson
2007-05-24 23:46 ` Wolfgang Denk
2007-05-25 5:37 ` Stefan Roese
2007-05-25 8:50 ` Ladislav Michl
2007-05-23 12:59 ` Ulf Samuelsson
2007-05-23 13:25 ` Ladislav Michl
2007-05-23 16:05 ` Ulf Samuelsson
2007-05-24 12:29 ` Ladislav Michl
2007-05-24 18:34 ` Ulf Samuelsson
2007-05-24 18:35 ` Ulf Samuelsson
2007-05-23 12:59 ` Wolfgang Denk
2007-05-23 15:44 ` Ulf Samuelsson
2007-05-23 18:08 ` Wolfgang Denk
2007-05-24 9:14 ` Ladislav Michl
2007-05-25 9:06 ` Ladislav Michl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=465CA599.7070704@atmel.com \
--to=ulf@atmel.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox