www.pudn.com > uboot-DataFlash_1_01.zip > patch-u-boot-AT91RM9200-dataflash.dat


diff -purN u-boot-1.0.0.orig/CHANGELOG u-boot-1.0.0.test/CHANGELOG
--- u-boot-1.0.0.orig/CHANGELOG	Thu Oct 30 22:49:38 2003
+++ u-boot-1.0.0.test/CHANGELOG	Fri Nov  7 20:35:54 2003
@@ -2,6 +2,11 @@
 Changes for U-Boot 1.0.0:
 ======================================================================
 
+* Patch by Nicolas Lacressonniere, 12 Nov 2003:
+  Modifications for Atmel AT91RM9200DK ARM920T based development kit
+  - Add Atmel DataFlash AT45DB1282 support
+  - Add the possibility to set the environment variables in DataFlash
+
 * Fix parameter passing to standalone images with bootm command
 
 * Patch by Kyle Harris, 30 Oct 2003:
diff -purN u-boot-1.0.0.orig/README u-boot-1.0.0.test/README
--- u-boot-1.0.0.orig/README	Mon Oct 20 01:22:11 2003
+++ u-boot-1.0.0.test/README	Fri Nov  7 20:24:42 2003
@@ -1742,6 +1742,20 @@ to save the current settings.
 	  The size in bytes of the EEPROM device.
 
 
+- CFG_ENV_IS_IN_DATAFLASH:
+
+	Define this if you have a DataFlash memory device which you 
+	want to use for the environment.
+
+	- CFG_ENV_OFFSET:
+	- CFG_ENV_ADDR:
+	- CFG_ENV_SIZE:
+
+	  These three #defines specify the offset and size of the
+	  environment area within the total memory of your DataFlash placed
+	  at the specified address.
+
+
 - CFG_SPI_INIT_OFFSET
 
 	Defines offset to the initial SPI buffer area in DPRAM. The
diff -purN u-boot-1.0.0.orig/common/Makefile u-boot-1.0.0.test/common/Makefile
--- u-boot-1.0.0.orig/common/Makefile	Thu Oct  9 22:09:04 2003
+++ u-boot-1.0.0.test/common/Makefile	Fri Nov  7 15:46:59 2003
@@ -42,7 +42,7 @@ COBJS	= main.o ACEX1K.o altera.o bedbug.
 	  cmd_reginfo.o cmd_scsi.o cmd_spi.o cmd_usb.o cmd_vfd.o \
 	  command.o console.o devices.o dlmalloc.o docecc.o \
 	  environment.o env_common.o \
-	  env_flash.o env_eeprom.o env_nvram.o env_nowhere.o exports.o \
+	  env_flash.o env_dataflash.o env_eeprom.o env_nvram.o env_nowhere.o exports.o \
 	  flash.o fpga.o \
 	  hush.o kgdb.o lists.o lynxkdi.o miiphybb.o miiphyutil.o \
 	  s_record.o soft_i2c.o soft_spi.o spartan2.o \
diff -purN u-boot-1.0.0.orig/common/cmd_flash.c u-boot-1.0.0.test/common/cmd_flash.c
--- u-boot-1.0.0.orig/common/cmd_flash.c	Tue Oct 14 21:43:56 2003
+++ u-boot-1.0.0.test/common/cmd_flash.c	Fri Nov  7 16:31:36 2003
@@ -307,7 +307,9 @@ int do_protect (cmd_tbl_t *cmdtp, int fl
 	ulong bank, addr_first, addr_last;
 	int i, p, n, sect_first, sect_last;
 	int rcode = 0;
-
+#ifdef CONFIG_HAS_DATAFLASH
+	int status;
+#endif
 	if (argc < 3) {
 		printf ("Usage:\n%s\n", cmdtp->usage);
 		return 1;
@@ -322,7 +324,28 @@ int do_protect (cmd_tbl_t *cmdtp, int fl
 		return 1;
 	}
 
+#ifdef CONFIG_HAS_DATAFLASH
+	if ( (strcmp(argv[2], "all") != 0) && (strcmp(argv[2], "bank") != 0) ){
+
+		addr_first = simple_strtoul(argv[2], NULL, 16);
+		addr_last  = simple_strtoul(argv[3], NULL, 16);
+
+		if (addr_dataflash(addr_first) && addr_dataflash(addr_last) ){
+
+			status = dataflash_real_protect(p,addr_first,addr_last);
+			if (status < 0){
+				printf("Bad DataFlash sector specification\n");
+                		return 1;
+        		}
+        		printf("%sProtect %d DataFlash Sectors\n",
+                		p ? "" : "Un-", status);
+			return 0;
+		}
+	}
+#endif
+	
 	if (strcmp(argv[2], "all") == 0) {
+
 		for (bank=1; bank<=CFG_MAX_FLASH_BANKS; ++bank) {
 			info = &flash_info[bank-1];
 			if (info->flash_id == FLASH_UNKNOWN) {
diff -purN u-boot-1.0.0.orig/common/cmd_mem.c u-boot-1.0.0.test/common/cmd_mem.c
--- u-boot-1.0.0.orig/common/cmd_mem.c	Thu Sep 18 11:21:35 2003
+++ u-boot-1.0.0.test/common/cmd_mem.c	Fri Nov  7 19:18:14 2003
@@ -136,13 +136,19 @@ int do_mem_md ( cmd_tbl_t *cmdtp, int fl
 		uint	*uip = (uint   *)linebuf;
 		ushort	*usp = (ushort *)linebuf;
 		u_char	*ucp = (u_char *)linebuf;
-
+#ifdef CONFIG_HAS_DATAFLASH
+		int rc;
+#endif
 		printf("%08lx:", addr);
 		linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
 
 #ifdef CONFIG_HAS_DATAFLASH
-		if (read_dataflash(addr, (linebytes/size)*size, linebuf) != -1){
-
+		if ((rc = read_dataflash(addr, (linebytes/size)*size, linebuf)) == DATAFLASH_OK){
+			/* if outside dataflash */
+			/*if (rc != 1) {
+        	                dataflash_perror (rc);
+                	        return (1);
+	                }*/
 			for (i=0; i
 #endif
 
-#if !defined(CFG_ENV_IS_IN_NVRAM) && !defined(CFG_ENV_IS_IN_EEPROM) && !defined(CFG_ENV_IS_IN_FLASH) && !defined(CFG_ENV_IS_NOWHERE)
-# error Define one of CFG_ENV_IS_IN_NVRAM, CFG_ENV_IS_IN_EEPROM, CFG_ENV_IS_IN_FLASH, CFG_ENV_IS_NOWHERE
+#if !defined(CFG_ENV_IS_IN_NVRAM) && !defined(CFG_ENV_IS_IN_EEPROM) && !defined(CFG_ENV_IS_IN_FLASH) && !defined(CFG_ENV_IS_IN_DATAFLASH) && !defined(CFG_ENV_IS_NOWHERE)
+# error Define one of CFG_ENV_IS_IN_NVRAM, CFG_ENV_IS_IN_EEPROM, CFG_ENV_IS_IN_FLASH,  CFG_ENV_IS_IN_DATAFLASH, CFG_ENV_IS_NOWHERE
 #endif
 
 #define XMK_STR(x)	#x
diff -purN u-boot-1.0.0.orig/common/env_dataflash.c u-boot-1.0.0.test/common/env_dataflash.c
--- u-boot-1.0.0.orig/common/env_dataflash.c	Thu Jan  1 01:00:00 1970
+++ u-boot-1.0.0.test/common/env_dataflash.c	Fri Nov  7 15:53:35 2003
@@ -0,0 +1,104 @@
+/* LowLevel function for DataFlash environment support
+ * Author : Gilles Gastaldi (Atmel)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+#include 
+
+#if defined(CFG_ENV_IS_IN_DATAFLASH) /* Environment is in DataFlash */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+env_t *env_ptr = NULL;
+
+char * env_name_spec = "dataflash";
+
+extern int read_dataflash (unsigned long addr, unsigned long size, char
+*result);
+extern int write_dataflash (unsigned long addr_dest, unsigned long addr_src,
+		     unsigned long size);
+extern int AT91F_DataflashInit (void);
+extern uchar default_environment[];
+/* extern int default_environment_size; */
+
+
+uchar env_get_char_spec (int index)
+{
+	uchar c;
+	read_dataflash (CFG_ENV_ADDR+index+offsetof(env_t,data),1,&c);
+	return (c);
+}
+
+void env_relocate_spec (void)
+{
+	read_dataflash (CFG_ENV_ADDR,CFG_ENV_SIZE,(uchar *)env_ptr);
+}
+
+int saveenv(void)
+{
+/* env must be copied to do not alter env structure in memory*/
+unsigned char temp[CFG_ENV_SIZE];
+int i;
+	memcpy(temp, env_ptr, CFG_ENV_SIZE);
+	return write_dataflash (CFG_ENV_ADDR, (unsigned long)temp, CFG_ENV_SIZE);
+}
+
+/************************************************************************
+ * Initialize Environment use
+ *
+ * We are still running from ROM, so data use is limited
+ * Use a (moderately small) buffer on the stack
+ */
+int env_init(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	
+	ulong crc, len, new;
+	unsigned off;
+	uchar buf[64];
+	if (gd->env_valid == 0){
+		AT91F_DataflashInit();	/* prepare for DATAFLASH read/write */
+
+		/* read old CRC */
+		read_dataflash (CFG_ENV_ADDR+offsetof(env_t,crc),sizeof(ulong),&crc);
+		new = 0;
+		len = ENV_SIZE;
+		off = offsetof(env_t,data);
+		while (len > 0) {
+			int n = (len > sizeof(buf)) ? sizeof(buf) : len;
+			read_dataflash (CFG_ENV_ADDR+off,n , buf);
+			new = crc32 (new, buf, n);
+			len -= n;
+			off += n;
+		}
+		if (crc == new) {
+			gd->env_addr  = offsetof(env_t,data);
+			gd->env_valid = 1;
+		} else {
+			gd->env_addr  = (ulong)&default_environment[0];
+			gd->env_valid = 0;
+		}
+	}
+	
+ 	return (0);
+}
+
+#endif /* CFG_ENV_IS_IN_DATAFLASH */
diff -purN u-boot-1.0.0.orig/cpu/at91rm9200/at45.c u-boot-1.0.0.test/cpu/at91rm9200/at45.c
--- u-boot-1.0.0.orig/cpu/at91rm9200/at45.c	Fri Jun 27 23:32:32 2003
+++ u-boot-1.0.0.test/cpu/at91rm9200/at45.c	Fri Nov  7 15:47:52 2003
@@ -26,6 +26,7 @@
 #include 
 
 #define SPI_CLK 5000000
+#define AT91C_TIMEOUT_WRDY			200000
 #define AT91C_SPI_PCS0_SERIAL_DATAFLASH		0xE     /* Chip Select 0 : NPCS0 %1110 */
 #define AT91C_SPI_PCS3_DATAFLASH_CARD		0x7     /* Chip Select 3 : NPCS3 %0111 */
 
@@ -145,10 +146,20 @@ AT91S_DataFlashStatus AT91F_DataFlashSen
 
 	/* fill the  command  buffer */
 	pDataFlash->pDataFlashDesc->command[0] = OpCode;
-	pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x00FF0000) >> 16);
-	pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x0000FF00) >> 8);
-	pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(adr & 0x000000FF) ;
-	pDataFlash->pDataFlashDesc->command[4] = 0;
+	if (pDataFlash->pDevice->pages_number >= 16384)
+	{
+		pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x0F000000) >> 24);
+		pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x00FF0000) >> 16);
+		pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((adr & 0x0000FF00) >> 8);
+		pDataFlash->pDataFlashDesc->command[4] = (unsigned char)(adr & 0x000000FF);
+	}
+	else
+	{	
+		pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x00FF0000) >> 16);
+		pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x0000FF00) >> 8);
+		pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(adr & 0x000000FF) ;
+		pDataFlash->pDataFlashDesc->command[4] = 0;
+	}
 	pDataFlash->pDataFlashDesc->command[5] = 0;
 	pDataFlash->pDataFlashDesc->command[6] = 0;
 	pDataFlash->pDataFlashDesc->command[7] = 0;
@@ -230,6 +241,7 @@ AT91S_DataFlashStatus AT91F_DataFlashCon
 	unsigned char *dataBuffer,
 	int sizeToRead )
 {
+	AT91S_DataFlashStatus status;
 	/* Test the size to read in the device */
 	if ( (src + sizeToRead) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
 		return DATAFLASH_MEMORY_OVERFLOW;
@@ -239,8 +251,9 @@ AT91S_DataFlashStatus AT91F_DataFlashCon
 	pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
 	pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;
 
+	status = AT91F_DataFlashSendCommand (pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src);
 	/* Send the command to the dataflash */
-	return(AT91F_DataFlashSendCommand (pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src));
+	return(status);
 }
 
 
@@ -259,13 +272,17 @@ AT91S_DataFlashStatus AT91F_DataFlashPag
 	unsigned int dest,
 	unsigned int SizeToWrite)
 {
+	int cmdsize;
 	pDataFlash->pDataFlashDesc->tx_data_pt = src ;
 	pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ;
 	pDataFlash->pDataFlashDesc->rx_data_pt = src;
 	pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
 
+	cmdsize = 4;
 	/* Send the command to the dataflash */
-	return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_PGM_BUF1, 4, dest));
+	if (pDataFlash->pDevice->pages_number >= 16384)
+		cmdsize = 5;
+	return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_PGM_BUF1, cmdsize, dest));
 }
 
 
@@ -282,14 +299,17 @@ AT91S_DataFlashStatus AT91F_MainMemoryTo
 	unsigned char BufferCommand,
 	unsigned int page)
 {
+	int cmdsize;
 	/* Test if the buffer command is legal */
 	if ((BufferCommand != DB_PAGE_2_BUF1_TRF) && (BufferCommand != DB_PAGE_2_BUF2_TRF))
 		return DATAFLASH_BAD_COMMAND;
 
 	/* no data to transmit or receive */
 	pDataFlash->pDataFlashDesc->tx_data_size = 0;
-
-	return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, 4, page*pDataFlash->pDevice->pages_size));
+	cmdsize = 4;
+	if (pDataFlash->pDevice->pages_number >= 16384)
+		cmdsize = 5;
+	return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, page*pDataFlash->pDevice->pages_size));
 }
 
 
@@ -310,6 +330,7 @@ AT91S_DataFlashStatus AT91F_DataFlashWri
 	unsigned int bufferAddress,
 	int SizeToWrite )
 {
+	int cmdsize;
 	/* Test if the buffer command is legal */
 	if ((BufferCommand != DB_BUF1_WRITE) && (BufferCommand != DB_BUF2_WRITE))
 		return DATAFLASH_BAD_COMMAND;
@@ -324,14 +345,25 @@ AT91S_DataFlashStatus AT91F_DataFlashWri
 	/* Send first Write Command */
 	pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
 	pDataFlash->pDataFlashDesc->command[1] = 0;
-	pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress &  pDataFlash->pDevice->byte_mask)) >> 8) ;
-	pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress  & 0x00FF) ;
-
+	if (pDataFlash->pDevice->pages_number >= 16384)
+	{
+	    	pDataFlash->pDataFlashDesc->command[2] = 0;
+	    	pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(((unsigned int)(bufferAddress &  pDataFlash->pDevice->byte_mask)) >> 8) ;
+	    	pDataFlash->pDataFlashDesc->command[4] = (unsigned char)((unsigned int)bufferAddress  & 0x00FF) ;
+		cmdsize = 5;
+	}
+	else
+	{
+	    	pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress &  pDataFlash->pDevice->byte_mask)) >> 8) ;
+	    	pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress  & 0x00FF) ;
+	    	pDataFlash->pDataFlashDesc->command[4] = 0;
+		cmdsize = 4;
+	}
 
 	pDataFlash->pDataFlashDesc->tx_cmd_pt 	 = pDataFlash->pDataFlashDesc->command ;
-	pDataFlash->pDataFlashDesc->tx_cmd_size = 4 ;
+	pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize ;
 	pDataFlash->pDataFlashDesc->rx_cmd_pt 	 = pDataFlash->pDataFlashDesc->command ;
-	pDataFlash->pDataFlashDesc->rx_cmd_size = 4 ;
+	pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize ;
 
 	pDataFlash->pDataFlashDesc->rx_data_pt 	= dataBuffer ;
 	pDataFlash->pDataFlashDesc->tx_data_pt 	= dataBuffer ;
@@ -341,6 +373,51 @@ AT91S_DataFlashStatus AT91F_DataFlashWri
 	return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
 }
 
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_PageErase                                        */             
+/* Object              : Erase a page 						*/
+/* Input Parameters    : DataFlash Service					*/
+/*                     : Page concerned						*/
+/*                     : 							*/
+/* Return value		: State of the dataflash				*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_PageErase(
+	AT91PS_DataFlash pDataFlash,
+	unsigned int page)
+{
+	int cmdsize;
+	/* Test if the buffer command is legal */	
+	/* no data to transmit or receive */
+    	pDataFlash->pDataFlashDesc->tx_data_size = 0;
+	
+	cmdsize = 4;
+	if (pDataFlash->pDevice->pages_number >= 16384)
+		cmdsize = 5;
+	return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_ERASE, cmdsize, page*pDataFlash->pDevice->pages_size));
+}
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_BlockErase                                       */             
+/* Object              : Erase a Block 						*/
+/* Input Parameters    : DataFlash Service					*/
+/*                     : Page concerned						*/
+/*                     : 							*/
+/* Return value		: State of the dataflash				*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_BlockErase(
+	AT91PS_DataFlash pDataFlash,
+	unsigned int block)
+{
+	int cmdsize;
+	/* Test if the buffer command is legal */	
+	/* no data to transmit or receive */
+    	pDataFlash->pDataFlashDesc->tx_data_size = 0;
+	cmdsize = 4;
+	if (pDataFlash->pDevice->pages_number >= 16384)
+		cmdsize = 5;
+	return(AT91F_DataFlashSendCommand (pDataFlash, DB_BLOCK_ERASE,cmdsize, block*8*pDataFlash->pDevice->pages_size));
+}
 
 /*------------------------------------------------------------------------------*/
 /* Function Name       : AT91F_WriteBufferToMain				*/
@@ -355,6 +432,7 @@ AT91S_DataFlashStatus AT91F_WriteBufferT
 	unsigned char BufferCommand,
 	unsigned int dest )
 {
+	int cmdsize;
 	/* Test if the buffer command is correct */
 	if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
 	    (BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
@@ -365,8 +443,11 @@ AT91S_DataFlashStatus AT91F_WriteBufferT
 	/* no data to transmit or receive */
 	pDataFlash->pDataFlashDesc->tx_data_size = 0;
 
+	cmdsize = 4;
+	if (pDataFlash->pDevice->pages_number >= 16384)
+		cmdsize = 5;
 	/* Send the command to the dataflash */
-	return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, 4, dest));
+	return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, dest));
 }
 
 
@@ -391,10 +472,19 @@ AT91S_DataFlashStatus AT91F_PartialPageW
 
 	/* Read the contents of the page in the Sram Buffer */
 	AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
-	AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+	AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
 	/*Update the SRAM buffer */
 	AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, AdrInPage, size);
-	AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+
+	AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
+	
+	/* Erase page if a 128 Mbits device */
+	if (pDataFlash->pDevice->pages_number >= 16384)
+	{
+		AT91F_PageErase(pDataFlash, page);
+		/* Rewrite the modified Sram Buffer in the main memory */
+		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
+	}
 
 	/* Rewrite the modified Sram Buffer in the main memory */
 	return(AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM, (page*pDataFlash->pDevice->pages_size)));
@@ -402,7 +492,7 @@ AT91S_DataFlashStatus AT91F_PartialPageW
 
 
 /*------------------------------------------------------------------------------*/
-/* Function Name       : AT91F_DataFlashWrite_Overloaded			*/
+/* Function Name       : AT91F_DataFlashWrite					*/
 /* Object              :							*/
 /* Input Parameters    : <*src> = Source buffer					*/
 /*                     :  = dataflash adress				*/
@@ -415,6 +505,8 @@ AT91S_DataFlashStatus AT91F_DataFlashWri
 	int size )
 {
 	unsigned int length;
+	unsigned int page;
+	unsigned int status;
 
 	AT91F_SpiEnable(pDataFlash->pDevice->cs);
 
@@ -431,7 +523,7 @@ AT91S_DataFlashStatus AT91F_DataFlashWri
 		if(!AT91F_PartialPageWrite(pDataFlash,src, dest, length))
 			return DATAFLASH_ERROR;
 
-		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
 
 		/* Update size, source and destination pointers */
 		size -= length;
@@ -441,10 +533,21 @@ AT91S_DataFlashStatus AT91F_DataFlashWri
 
 	while (( size - pDataFlash->pDevice->pages_size ) >= 0 ) {
 		/* program dataflash page */
-		if(!AT91F_DataFlashPagePgmBuf(pDataFlash, src, dest, pDataFlash->pDevice->pages_size ))
+		page = (unsigned int)dest / (pDataFlash->pDevice->pages_size);
+
+		status = AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, 0, pDataFlash->pDevice->pages_size);
+		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
+
+		status = AT91F_PageErase(pDataFlash, page);
+		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
+		if (!status)
+			return DATAFLASH_ERROR;
+	
+		status = AT91F_WriteBufferToMain (pDataFlash, DB_BUF1_PAGE_PGM, dest);
+		if(!status)
 			return DATAFLASH_ERROR;
 
-		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
 
 		/* Update size, source and destination pointers */
 		size -= pDataFlash->pDevice->pages_size ;
@@ -458,7 +561,7 @@ AT91S_DataFlashStatus AT91F_DataFlashWri
 		if(!AT91F_PartialPageWrite(pDataFlash, src, dest, size) )
 			return DATAFLASH_ERROR;
 
-		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
 	}
 	return DATAFLASH_OK;
 }
@@ -480,13 +583,13 @@ int AT91F_DataFlashRead(
 
 	AT91F_SpiEnable(pDataFlash->pDevice->cs);
 
-	if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000) != DATAFLASH_OK)
+	if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
 		return -1;
 
 	while (size) {
 		SizeToRead = (size < 0x8000)? size:0x8000;
 
-		if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000) != DATAFLASH_OK)
+		if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
 			return -1;
 
 		if (AT91F_DataFlashContinuousRead (pDataFlash, addr, buffer, SizeToRead) != DATAFLASH_OK)
diff -purN u-boot-1.0.0.orig/drivers/dataflash.c u-boot-1.0.0.test/drivers/dataflash.c
--- u-boot-1.0.0.orig/drivers/dataflash.c	Fri Jun 27 23:32:37 2003
+++ u-boot-1.0.0.test/drivers/dataflash.c	Fri Nov  7 15:46:59 2003
@@ -31,22 +31,33 @@ int cs[][CFG_MAX_DATAFLASH_BANKS] = {
 	{CFG_DATAFLASH_LOGIC_ADDR_CS3, 3}
 };
 
+/*define the area offsets*/	
+dataflash_protect_t area_list[NB_DATAFLASH_AREA]={
+{0, 0x7fff, FLAG_PROTECT_SET},		/* ROM code */
+{0x8000, 0x1ffff, FLAG_PROTECT_SET},	/* u-boot code*/
+{0x20000, 0x27fff, FLAG_PROTECT_CLEAR},	/* u-boot environment */
+{0x28000, 0x1fffff, FLAG_PROTECT_CLEAR},/* data area size to tune */
+};
+
 extern void AT91F_SpiInit (void);
 extern int AT91F_DataflashProbe (int i, AT91PS_DataflashDesc pDesc);
 extern int AT91F_DataFlashRead (AT91PS_DataFlash pDataFlash,
 				unsigned long addr,
 				unsigned long size, char *buffer);
-
+extern int AT91F_DataFlashWrite( AT91PS_DataFlash pDataFlash,
+				    unsigned char *src,
+			            int dest,
+				    int size );
 
 int AT91F_DataflashInit (void)
 {
-	int i, j;
+	int i,j;
 	int dfcode;
-
+		
 	AT91F_SpiInit ();
 
 	for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
-
+		dataflash_info[i].Desc.state = IDLE;
 		dataflash_info[i].id = 0;
 		dataflash_info[i].Device.pages_number = 0;
 		dfcode = AT91F_DataflashProbe (cs[i][1], &dataflash_info[i].Desc);
@@ -84,22 +95,39 @@ int AT91F_DataflashInit (void)
 			dataflash_info[i].logical_address = cs[i][0];
 			dataflash_info[i].id = dfcode;
 			break;
+		case AT45DB128:
+			dataflash_info[i].Device.pages_number = 16384;
+			dataflash_info[i].Device.pages_size = 1056;
+			dataflash_info[i].Device.page_offset = 11;
+			dataflash_info[i].Device.byte_mask = 0x700;
+			dataflash_info[i].Device.cs = cs[i][1];
+			dataflash_info[i].Desc.DataFlash_state = IDLE;
+			dataflash_info[i].logical_address = cs[i][0];
+			dataflash_info[i].id = dfcode;
+			break;
 
 		default:
 			break;
 		}
-
-		for (j = 0; j < dataflash_info[i].Device.pages_number; j++)
-			dataflash_info[i].protect[j] = FLAG_PROTECT_SET;
-
-	}
+		/* set the last area end to the dataflash size*/
+		area_list[NB_DATAFLASH_AREA -1].end =
+				(dataflash_info[i].Device.pages_number *
+				dataflash_info[i].Device.pages_size)-1;
+				
+		/* set the area addresses */
+		for(j = 0; j (pdataFlash->pDevice->pages_size * 
+		pdataFlash->pDevice->pages_number)) return 0;
+	/* is too large for the dataflash */
+	if (size > ((pdataFlash->pDevice->pages_size * 
+		pdataFlash->pDevice->pages_number) - ((int)addr & 0x0FFFFFFF))) return 0;
+		
+	return 1;
+}
+/*-----------------------------------------------------------------------------*/
+/* Function Name       : prot_dataflash 					*/
+/* Object              : Test if destination area is protected			*/
+/*-----------------------------------------------------------------------------*/
+int prot_dataflash (AT91PS_DataFlash pdataFlash, unsigned long addr)
+{
+int area;
+	/* find area */
+	for (area=0; area < NB_DATAFLASH_AREA; area++){
+		if ((addr >= pdataFlash->pDevice->area_list[area].start) && 
+			(addr < pdataFlash->pDevice->area_list[area].end)) 
+			break;
+	}	
+	if (area == NB_DATAFLASH_AREA) return -1;
+	/*test protection value*/
+	if (pdataFlash->pDevice->area_list[area].protected == FLAG_PROTECT_SET) return 0;
+	
+	return 1;
+}
+/*-----------------------------------------------------------------------------*/
+/* Function Name       : dataflash_real_protect				*/
+/* Object              : protect/unprotect area				*/
+/*-----------------------------------------------------------------------------*/
+int dataflash_real_protect (int flag, unsigned long start_addr, unsigned long end_addr)
+{
+int i,j, area1, area2, addr_valid = 0;
+	/* find dataflash */ 
+	for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
+		if ((((int) start_addr) & 0xF0000000) ==
+			dataflash_info[i].logical_address){
+				addr_valid = 1;
+				break;
+		}
+	}
+	if (!addr_valid) {
+		return -1;
+	}
+	/* find start area */
+	for (area1=0; area1 < NB_DATAFLASH_AREA; area1++){
+		if (start_addr == dataflash_info[i].Device.area_list[area1].start) break;
+	}	
+	if (area1 == NB_DATAFLASH_AREA) return -1;
+	/* find end area */
+	for (area2=0; area2 < NB_DATAFLASH_AREA; area2++){
+		if (end_addr == dataflash_info[i].Device.area_list[area2].end) break;
+	}	
+	if (area2 == NB_DATAFLASH_AREA) return -1;
+
+	/*set protection value*/
+	for(j = area1; j < area2+1 ; j++)
+		if (flag == 0) dataflash_info[i].Device.area_list[j].protected = FLAG_PROTECT_CLEAR;
+		else dataflash_info[i].Device.area_list[j].protected = FLAG_PROTECT_SET;
+	
+	return (area2-area1+1);
+}
 
 /*------------------------------------------------------------------------------*/
 /* Function Name       : read_dataflash 					*/
@@ -187,10 +295,15 @@ int read_dataflash (unsigned long addr, 
 	AT91PS_DataFlash pFlash = &DataFlashInst;
 
 	pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead);
+
 	if (pFlash == 0)
-		return -1;
+		return ERR_UNKNOWN_FLASH_TYPE;
+
+	if (size_dataflash(pFlash,addr,size) == 0)
+		return ERR_INVAL;
 
 	return (AT91F_DataFlashRead (pFlash, AddrToRead, size, result));
+	
 }
 
 
@@ -201,17 +314,25 @@ int read_dataflash (unsigned long addr, 
 int write_dataflash (unsigned long addr_dest, unsigned long addr_src,
 		     unsigned long size)
 {
-	extern AT91S_DataFlashStatus AT91F_DataFlashWrite(
-			AT91PS_DataFlash, uchar *, int, int);
 	int AddrToWrite = addr_dest;
 	AT91PS_DataFlash pFlash = &DataFlashInst;
 
 	pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite);
+
+	if (pFlash == 0)
+		return ERR_UNKNOWN_FLASH_TYPE;
+
+	if (size_dataflash(pFlash,addr_dest,size) == 0)
+		return ERR_INVAL;
+
+	if (prot_dataflash(pFlash,addr_dest) == 0)
+		return ERR_PROTECTED;
+		
 	if (AddrToWrite == -1)
 		return -1;
 
-	return AT91F_DataFlashWrite (pFlash, (char *) addr_src, AddrToWrite,
-								 size);
+	return AT91F_DataFlashWrite (pFlash, (char *) addr_src, AddrToWrite, size);
+
 }
 
 
@@ -242,3 +363,4 @@ void dataflash_perror (int err)
 }
 
 #endif
+	
diff -purN u-boot-1.0.0.orig/include/configs/at91rm9200dk.h u-boot-1.0.0.test/include/configs/at91rm9200dk.h
--- u-boot-1.0.0.orig/include/configs/at91rm9200dk.h	Fri Jun 27 23:32:45 2003
+++ u-boot-1.0.0.test/include/configs/at91rm9200dk.h	Fri Nov  7 20:09:16 2003
@@ -105,7 +105,7 @@
 #define CONFIG_NET_RETRY_COUNT 20
 
 #define CONFIG_HAS_DATAFLASH	1
-#define CFG_SPI_WRITE_TOUT	CFG_HZ
+#define CFG_SPI_WRITE_TOUT	(5*CFG_HZ)
 #define CFG_MAX_DATAFLASH_BANKS 2
 #define CFG_MAX_DATAFLASH_PAGES 16384
 #define CFG_DATAFLASH_LOGIC_ADDR_CS0	0xC0000000	/* Logical adress for CS0 */
@@ -118,9 +118,20 @@
 #define CFG_MAX_FLASH_SECT 40
 #define CFG_FLASH_ERASE_TOUT	(2*CFG_HZ) /* Timeout for Flash Erase */
 #define CFG_FLASH_WRITE_TOUT	(2*CFG_HZ) /* Timeout for Flash Write */
+
+#undef	CFG_ENV_IS_IN_DATAFLASH
+
+#ifdef CFG_ENV_IS_IN_DATAFLASH
+#define CFG_ENV_OFFSET 0x20000  
+#define CFG_ENV_ADDR (CFG_DATAFLASH_LOGIC_ADDR_CS0 + CFG_ENV_OFFSET)
+#define CFG_ENV_SIZE 0x2000  /* 0x8000 */
+#else
 #define	CFG_ENV_IS_IN_FLASH	1
 #define CFG_ENV_ADDR (PHYS_FLASH_1 + 0xe000)  /* 0x10000 */
 #define CFG_ENV_SIZE 0x2000  /* 0x8000 */
+#endif
+
+
 #define CFG_LOAD_ADDR 0x21000000  /* default load address */
 
 #define CFG_BOOT_SIZE		0x6000 /* 24 KBytes */
diff -purN u-boot-1.0.0.orig/include/dataflash.h u-boot-1.0.0.test/include/dataflash.h
--- u-boot-1.0.0.orig/include/dataflash.h	Fri Jun 27 23:32:40 2003
+++ u-boot-1.0.0.test/include/dataflash.h	Fri Nov  7 15:46:59 2003
@@ -37,16 +37,15 @@
 #include 
 #include "config.h"
 
+/*number of protected area*/
+#define NB_DATAFLASH_AREA	4
 
+/*define the area structure*/
 typedef struct {
-	unsigned long base;		/* logical base address for a bank */
-	unsigned long size;		/* total bank size */
-	unsigned long page_count;
-	unsigned long page_size;
-	unsigned long id;		/* device id */
-	unsigned char protect[CFG_MAX_DATAFLASH_PAGES]; /* page protection status */
-} dataflash_info_t;
-
+	unsigned long start;
+	unsigned long end;
+	unsigned char protected;
+} dataflash_protect_t;
 
 typedef unsigned int AT91S_DataFlashStatus;
 
@@ -80,6 +79,7 @@ typedef struct _AT91S_Dataflash {
 	int page_offset;			/* page offset in command */
 	int byte_mask;				/* byte mask in command */
 	int cs;
+	dataflash_protect_t area_list[NB_DATAFLASH_AREA]; /* area protection status */
 } AT91S_DataflashFeatures, *AT91PS_DataflashFeatures;
 
 /*---------------------------------------------*/
@@ -91,13 +91,13 @@ typedef struct _AT91S_DataFlash {
 } AT91S_DataFlash, *AT91PS_DataFlash;
 
 
+
 typedef struct _AT91S_DATAFLASH_INFO {
 
 	AT91S_DataflashDesc Desc;
 	AT91S_DataflashFeatures Device; /* Pointer on a dataflash features array */
 	unsigned long logical_address;
 	unsigned int id;			/* device id */
-	unsigned char protect[CFG_MAX_DATAFLASH_PAGES]; /* page protection status */
 } AT91S_DATAFLASH_INFO, *AT91PS_DATAFLASH_INFO;
 
 
@@ -106,6 +106,7 @@ typedef struct _AT91S_DATAFLASH_INFO {
 #define AT45DB161	0x2c
 #define AT45DB321	0x34
 #define AT45DB642	0x3c
+#define AT45DB128	0x10
 
 #define AT91C_DATAFLASH_TIMEOUT		10000	/* For AT91F_DataFlashWaitReady */
 
@@ -166,6 +167,9 @@ typedef struct _AT91S_DATAFLASH_INFO {
 
 /*-------------------------------------------------------------------------------------------------*/
 
+extern int size_dataflash (AT91PS_DataFlash pdataFlash, unsigned long addr, unsigned long size);
+extern int prot_dataflash (AT91PS_DataFlash pdataFlash, unsigned long addr);
+extern int dataflash_real_protect (int flag, unsigned long start_addr, unsigned long end_addr);
 extern int addr_dataflash (unsigned long addr);
 extern int read_dataflash (unsigned long addr, unsigned long size, char *result);
 extern int write_dataflash (unsigned long addr, unsigned long dest, unsigned long size);