1 //==========================================================================
5 // Flash programming for the at91 devices which have the
6 // Embedded Flash Controller.
8 //==========================================================================
9 //####ECOSGPLCOPYRIGHTBEGIN####
10 // -------------------------------------------
11 // This file is part of eCos, the Embedded Configurable Operating System.
12 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // Copyright (C) 2006 eCosCentric Ltd
14 // Copyright (C) 2006 Andrew Lunn (andrew.lunn@ascom.ch)
16 // eCos is free software; you can redistribute it and/or modify it under
17 // the terms of the GNU General Public License as published by the Free
18 // Software Foundation; either version 2 or (at your option) any later version.
20 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
21 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 // You should have received a copy of the GNU General Public License along
26 // with eCos; if not, write to the Free Software Foundation, Inc.,
27 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
29 // As a special exception, if other files instantiate templates or use macros
30 // or inline functions from this file, or you compile this file and link it
31 // with other works to produce a work based on this file, this file does not
32 // by itself cause the resulting work to be covered by the GNU General Public
33 // License. However the source code for this file must still be made available
34 // in accordance with section (3) of the GNU General Public License.
36 // This exception does not invalidate any other reasons why a work based on
37 // this file might be covered by the GNU General Public License.
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
44 // Contributors: gthomas, dmoseley, Andrew Lunn, Oliver Munz
49 //####DESCRIPTIONEND####
51 //==========================================================================
53 #include <pkgconf/hal.h>
54 #include <pkgconf/devs_flash_at91.h>
56 #include <cyg/hal/hal_io.h>
57 #include <cyg/hal/hal_intr.h>
58 #include <cyg/infra/cyg_ass.h>
60 #define _FLASH_PRIVATE_
61 #include <cyg/io/flash.h>
65 #define FLASH_TIMEOUT 100000
67 #ifdef CYGBLD_DEV_FLASH_AT91_LOCKING
68 static cyg_uint32 sector_size;
71 // Disable the flash controller from erasing the page before
74 flash_erase_before_write_disable (void)
78 HAL_READ_UINT32(AT91_MC+AT91_MC_FMR, fmr);
79 fmr = fmr | AT91_MC_FMR_NEBP;
80 HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR, fmr);
83 // Enable the flash controller to erase the page before programming
86 flash_erase_before_write_enable (void)
91 HAL_READ_UINT32(AT91_MC+AT91_MC_FMR, fmr);
92 fmr = fmr & ~((cyg_uint32) AT91_MC_FMR_NEBP);
93 HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR, fmr);
96 // Is the flash controller ready to accept the next command?
97 static __inline__ cyg_bool
98 flash_controller_is_ready(void)
99 CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command");
101 static __inline__ cyg_bool
102 flash_controller_is_ready(void)
106 HAL_READ_UINT32(AT91_MC+AT91_MC_FSR, fsr);
107 return (fsr & AT91_MC_FSR_FRDY ? true : false);
110 // Busy loop waiting for the controller to finish the command.
111 // Wait a maximum of timeout loops and then return an error.
112 static __inline__ int
113 flash_wait_for_controller (cyg_uint32 timeout)
114 CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command");
116 static __inline__ int
117 flash_wait_for_controller (cyg_uint32 timeout)
119 while (!flash_controller_is_ready()){
122 return FLASH_ERR_DRV_TIMEOUT;
128 // Execute one command on the flash controller. This code should
129 // probably not be in flash
132 flash_run_command(cyg_uint32 address,
135 CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command");
138 flash_run_command(cyg_uint32 address,
147 page = ((cyg_uint32) address - (cyg_uint32) flash_info.start) /
148 flash_info.block_size;
150 // Wait for the last command to finish
151 retcode = flash_wait_for_controller(timeout);
152 if (retcode != FLASH_ERR_OK){
156 HAL_DISABLE_INTERRUPTS(mask);
158 HAL_WRITE_UINT32(AT91_MC+AT91_MC_FCR,
160 ((page & AT91_MC_FCR_PAGE_MASK) << AT91_MC_FCR_PAGE_SHIFT) |
163 retcode = flash_wait_for_controller(timeout);
165 HAL_RESTORE_INTERRUPTS(mask);
167 if (retcode != FLASH_ERR_OK){
171 // Check for an error
172 HAL_READ_UINT32(AT91_MC+AT91_MC_FSR, fsr);
174 if ((fsr & AT91_MC_FSR_LOCKE) == AT91_MC_FSR_LOCKE)
175 return FLASH_ERR_PROTECT;
176 if ((fsr & AT91_MC_FSR_PROGE) == AT91_MC_FSR_PROGE)
177 return FLASH_ERR_PROGRAM;
182 // The flash is embedded in the CPU package. So return the chip
183 // ID. This allows us to determine if the chip is one we support and
184 // the size of the flash
185 int flash_query(void *data)
189 HAL_READ_UINT32(AT91_DBG+AT91_DBG_C1R, chipID1r);
191 memcpy(data, &chipID1r, sizeof(chipID1r));
195 // Initialize the hardware. Make sure we have a flash device we know
196 // how to program and determine its size, the size of the blocks, and
197 // the number of blocks. The query function returns the chip ID 1
198 // register which tells us about the CPU we are running on, the flash
199 // size etc. Use this information to determine we have a valid setup.
201 flash_hwr_init(void){
204 cyg_uint32 flash_mode;
206 cyg_uint32 lock_bits;
208 flash_query (&chipID1r);
210 if ((chipID1r & AT91_DBG_C1R_CPU_MASK) != AT91_DBG_C1R_ARM7TDMI)
213 if (((chipID1r & AT91_DBG_C1R_ARCH_MASK) != AT91_DBG_C1R_ARCH_AT91SAM7Sxx) &&
214 ((chipID1r & AT91_DBG_C1R_ARCH_MASK) != AT91_DBG_C1R_ARCH_AT91SAM7Xxx))
217 if ((chipID1r & AT91_DBG_C1R_FLASH_MASK) == AT91_DBG_C1R_FLASH_0K)
220 switch (chipID1r & AT91_DBG_C1R_FLASH_MASK) {
221 case AT91_DBG_C1R_FLASH_32K:
222 flash_info.block_size = 128;
223 flash_info.blocks = 256;
226 case AT91_DBG_C1R_FLASH_64K:
227 flash_info.block_size = 128;
228 flash_info.blocks = 512;
231 case AT91_DBG_C1R_FLASH_128K:
232 flash_info.block_size = 256;
233 flash_info.blocks = 512;
236 case AT91_DBG_C1R_FLASH_256K:
237 flash_info.block_size = 256;
238 flash_info.blocks = 1024;
244 flash_info.buffer_size = 0;
245 flash_info.start = (void *) 0x00100000;
246 flash_info.end = (void *)(((cyg_uint32) flash_info.start) +
247 flash_info.block_size * flash_info.blocks);
248 #ifdef CYGBLD_DEV_FLASH_AT91_LOCKING
249 sector_size = flash_info.block_size * flash_info.blocks / lock_bits;
251 // Set the FLASH clock to 1.5 microseconds based on the MCLK. This
252 // assumes the CPU is still running from the PLL clock as defined in
253 // the HAL CDL and the HAL startup code.
254 fmcn = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / 1000000 * 1.5;
255 HAL_READ_UINT32(AT91_MC+AT91_MC_FMR, flash_mode);
256 flash_mode = flash_mode & ~AT91_MC_FMR_FMCN_MASK;
257 flash_mode = flash_mode | (fmcn << AT91_MC_FMR_FMCN_SHIFT);
258 HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR, flash_mode);
263 (*flash_info.pf)("Can't identify FLASH, sorry, ChipID1 %x\n",
265 return FLASH_ERR_HWR;
268 // Erase a block. The flash controller does not have a command to
269 // erase a block. So instead we setup the controller to do a program
270 // writing all 0xff with an erase operation first.
272 flash_erase_block (volatile unsigned long block)
278 buffer = (cyg_uint32 *) block;
279 end = (cyg_uint32 *) (block + flash_info.block_size);
281 while (buffer < end){
282 *buffer = (cyg_uint32) 0xffffffff;
286 flash_erase_before_write_enable();
287 retcode = flash_run_command(block,
288 AT91_MC_FCR_START_PROG,
294 // Write into the flash. The datasheet says that performing 8 or 16bit
295 // accesses results in unpredictable corruption. So the current code
296 // checks that these conditions are upheld. It would be possible to
297 // perform extra reads and masking operation to support writing to
298 // none word assigned addresses or not multiple or a word length.
300 flash_program_buf (volatile unsigned long addr, unsigned long *data, int len)
303 volatile unsigned long *target;
305 CYG_ASSERT(len % 4 == 0, "Only word writes allowed by current code");
306 CYG_ASSERT(addr % 4 == 0, "Address must be word aligned for current code");
308 target = (volatile unsigned long *)addr;
314 len = len - sizeof(unsigned long);
317 flash_erase_before_write_disable();
318 retcode = flash_run_command(addr,
319 AT91_MC_FCR_START_PROG,
325 #ifdef CYGBLD_DEV_FLASH_AT91_LOCKING
326 // Unlock a block. This is not strictly possible, we can only lock and
327 // unlock sectors. This will unlock the sector which contains the
330 flash_unlock_block(volatile unsigned long block, int block_size, int blocks)
336 sector = (((cyg_uint32) block) - (cyg_uint32) flash_info.start) /
339 HAL_READ_UINT32(AT91_MC + AT91_MC_FSR, status);
341 if (status & (1 << (sector + 16))){
342 retcode = flash_run_command(block,
351 // Lock a block. This is not strictly possible, we can only lock and
352 // unlock sectors. This will lock the sector which contains the
355 flash_lock_block(volatile unsigned long block, int block_size, int blocks)
361 sector = (((cyg_uint32) block) - (cyg_uint32) flash_info.start) /
364 HAL_READ_UINT32(AT91_MC + AT91_MC_FSR, status);
366 if (!(status & (1 << (sector + 16)))){
367 retcode = flash_run_command(block,
378 // Map a hardware status to a package error. NOP since the errors are
380 int flash_hwr_map_error(int err){
385 // See if a range of FLASH addresses overlaps currently running code
386 bool flash_code_overlaps(void *start, void *end){
388 extern char _stext[], _etext[];
390 return ((((unsigned long)&_stext >= (unsigned long)start) &&
391 ((unsigned long)&_stext < (unsigned long)end)) ||
392 (((unsigned long)&_etext >= (unsigned long)start) &&
393 ((unsigned long)&_etext < (unsigned long)end)));