]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/flash/intel/strata/v2_0/src/flash_program_buf2.c
RedBoot TX53 Release 2012-02-15
[karo-tx-redboot.git] / packages / devs / flash / intel / strata / v2_0 / src / flash_program_buf2.c
1 //==========================================================================
2 //
3 //      flash_program_buf.c
4 //
5 //      Flash programming
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):    gthomas, hmt
44 // Contributors: gthomas
45 // Date:         2001-02-14
46 // Purpose:      
47 // Description:  
48 //              
49 //####DESCRIPTIONEND####
50 //
51 //==========================================================================
52
53
54 // original code changed by KARO electronics GmbH 09.04.2003
55 // the original code assumes, that the BA is constant over the whole region to program.
56 // As we remap the first 4k of flash to DRAM, and the corresponding DRAM to flash,
57 // this is not true if we want to update the RedBoot image itself.
58 #include "strata.h"
59
60 #include <pkgconf/hal.h>
61 #include <cyg/hal/hal_arch.h>
62 #include <cyg/hal/hal_cache.h>
63
64 //
65 // CAUTION!  This code must be copied to RAM before execution.  Therefore,
66 // it must not contain any code which might be position dependent!
67 //
68
69 int
70 flash_program_buf(volatile flash_t *addr, flash_t *data, int len,
71                   unsigned long block_mask, int buffer_size)
72 {
73     volatile flash_t *ROM;
74     volatile flash_t *BA;
75     volatile flash_t *phy_address;
76     flash_t stat = 0;
77     int timeout = 50000;
78     int cache_on;
79 #ifdef FLASH_Write_Buffer
80     int i, wc;
81 #endif
82
83         phy_address = addr;
84
85     HAL_DCACHE_IS_ENABLED(cache_on);
86     if (cache_on) {
87         HAL_DCACHE_SYNC();
88         HAL_DCACHE_DISABLE();
89     }
90
91     // Get base address and map addresses to virtual addresses
92     ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)addr);
93     BA = FLASH_P2V( block_mask & (unsigned int)addr );
94     addr = FLASH_P2V(addr);
95
96
97
98     // Clear any error conditions
99     ROM[0] = FLASH_Clear_Status;
100
101 #ifdef FLASH_Write_Buffer
102     // Write any big chunks first
103     while (len >= buffer_size) {
104         ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)phy_address );
105         BA = FLASH_P2V( block_mask & (unsigned int)phy_address );
106         addr = FLASH_P2V(phy_address);
107         
108         wc = buffer_size;
109         if (wc > len) wc = len;
110         len -= wc;
111
112         // convert 'wc' in bytes to 'wc' in 'flash_t' 
113
114         wc = wc / sizeof(flash_t);  // Word count
115         
116         
117         
118         *BA = FLASH_Write_Buffer;
119         
120         timeout = 5000000;
121         while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
122             if (--timeout == 0) {
123                 
124                 
125                 goto bad;
126             }
127             *BA = FLASH_Write_Buffer;
128         }
129
130         *BA = FLASHWORD(wc-1);  // Count is 0..N-1
131         for (i = 0;  i < wc;  i++) {
132 #ifdef CYGHWR_FLASH_WRITE_ELEM
133             CYGHWR_FLASH_WRITE_ELEM(addr+i, data+i);
134 #else
135             *(addr+i) = *(data+i);
136 #endif
137         }
138
139     
140     
141         *BA = FLASH_Confirm;
142     
143         ROM[0] = FLASH_Read_Status;
144         timeout = 5000000;
145         while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
146             if (--timeout == 0) {
147                 
148                 
149                 
150                 goto bad;
151             }
152         }
153
154         // Jump out if there was an error
155         if (stat & FLASH_ErrorMask) {
156
157             
158
159             goto bad;
160         }
161         
162         // And verify the data - also increments the pointers.
163         *BA = FLASH_Reset;            
164         for (i = 0;  i < wc;  i++) {
165                 phy_address++;
166             if ( *addr++ != *data++ ) {
167                 stat = FLASH_ErrorNotVerified;
168                goto bad;
169             }
170         }
171         
172         
173         
174         
175     }
176 #endif
177
178     while (len > 0) {
179         diag_printf("hier komm ich auch rein !!!!\n");
180         ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)phy_address );
181         BA = FLASH_P2V( block_mask & (unsigned int)phy_address );
182         addr = FLASH_P2V(phy_address);
183         
184         ROM[0] = FLASH_Program;
185 #ifdef CYGHWR_FLASH_WRITE_ELEM
186         CYGHWR_FLASH_WRITE_ELEM(addr, data);
187 #else
188         *addr = *data;
189 #endif
190         timeout = 5000000;
191         while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
192             if (--timeout == 0) {
193                 goto bad;
194             }
195         }
196         if (stat & FLASH_ErrorMask) {
197             break;
198         }
199         ROM[0] = FLASH_Reset;  
200         phy_address++;          
201         if (*addr++ != *data++) {
202             stat = FLASH_ErrorNotVerified;
203             break;
204         }
205         len -= sizeof( flash_t );
206     }
207
208     // Restore ROM to "normal" mode
209  bad:
210     ROM[0] = FLASH_Reset;            
211
212     if (cache_on) {
213         HAL_DCACHE_ENABLE();
214     }
215
216     return stat;
217 }