|
1706
|
1 //========================================================================== |
|
|
2 // |
|
|
3 // legacy_dev.c |
|
|
4 // |
|
|
5 // Interface to the legacy device drivers |
|
|
6 // |
|
|
7 //========================================================================== |
|
|
8 //####ECOSGPLCOPYRIGHTBEGIN#### |
|
|
9 // ------------------------------------------- |
|
|
10 // This file is part of eCos, the Embedded Configurable Operating System. |
|
|
11 // Copyright (C) 2004 Andrew Lunn |
|
|
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): Andrew Lunn |
|
|
44 // Contributors: Andrew Lunn |
|
|
45 // Date: 2004-07-02 |
|
|
46 // Purpose: |
|
|
47 // Description: Implement an interface to the legacy device drivers |
|
|
48 // |
|
|
49 //####DESCRIPTIONEND#### |
|
|
50 // |
|
|
51 //========================================================================== |
|
|
52 |
|
|
53 #include <pkgconf/system.h> |
|
|
54 #include <pkgconf/io_flash.h> |
|
|
55 |
|
|
56 #include <cyg/hal/hal_arch.h> |
|
|
57 #include <cyg/hal/hal_intr.h> |
|
|
58 #include <cyg/hal/hal_cache.h> |
|
|
59 #include <string.h> |
|
|
60 |
|
|
61 #define _FLASH_PRIVATE_ |
|
|
62 #include <cyg/io/flash.h> |
|
|
63 |
|
|
64 // When this flag is set, do not actually jump to the relocated code. |
|
|
65 // This can be used for running the function in place (RAM startup only), |
|
|
66 // allowing calls to diag_printf() and similar. |
|
|
67 #undef RAM_FLASH_DEV_DEBUG |
|
|
68 #if !defined(CYG_HAL_STARTUP_RAM) && defined(RAM_FLASH_DEV_DEBUG) |
|
|
69 # warning "Can only enable the flash debugging when configured for RAM startup" |
|
|
70 #endif |
|
|
71 |
|
|
72 struct flash_info flash_info; |
|
|
73 |
|
|
74 // These are the functions in the HW specific driver we need to call. |
|
|
75 typedef void code_fun(void*); |
|
|
76 |
|
|
77 externC code_fun flash_query; |
|
|
78 externC code_fun flash_erase_block; |
|
|
79 externC code_fun flash_program_buf; |
|
|
80 externC code_fun flash_read_buf; |
|
|
81 externC code_fun flash_lock_block; |
|
|
82 externC code_fun flash_unlock_block; |
|
|
83 |
|
|
84 // Initialize the device |
|
|
85 static int |
|
|
86 legacy_flash_init (struct cyg_flash_dev *dev) |
|
|
87 { |
|
|
88 int err; |
|
|
89 static cyg_block_info_t block_info[1]; |
|
|
90 |
|
|
91 err=flash_hwr_init(); |
|
|
92 |
|
|
93 if (!err) { |
|
|
94 dev->start = (cyg_flashaddr_t)flash_info.start; |
|
|
95 dev->end = (cyg_flashaddr_t)flash_info.end; |
|
|
96 dev->num_block_infos = 1; |
|
|
97 dev->block_info = block_info; |
|
|
98 block_info[0].block_size = flash_info.block_size; |
|
|
99 block_info[0].blocks = flash_info.blocks; |
|
|
100 } |
|
|
101 return err; |
|
|
102 } |
|
|
103 |
|
|
104 // Use this function to make function pointers anonymous - forcing the |
|
|
105 // compiler to use jumps instead of branches when calling driver |
|
|
106 // services. |
|
|
107 static void* __anonymizer(void* p) |
|
|
108 { |
|
|
109 return p; |
|
|
110 } |
|
|
111 |
|
|
112 static size_t |
|
|
113 legacy_flash_query (struct cyg_flash_dev *dev, |
|
|
114 void * data, |
|
|
115 const size_t len) |
|
|
116 __attribute__ ((section (".2ram.flash_program_buf"))); |
|
|
117 |
|
|
118 static size_t |
|
|
119 legacy_flash_query (struct cyg_flash_dev *dev, |
|
|
120 void * data, |
|
|
121 const size_t len) |
|
|
122 { |
|
|
123 typedef void code_fun(void*); |
|
|
124 code_fun *_flash_query; |
|
|
125 |
|
|
126 _flash_query = (code_fun*) __anonymizer(&flash_query); |
|
|
127 |
|
|
128 (*_flash_query)(data); |
|
|
129 |
|
|
130 return len; |
|
|
131 } |
|
|
132 |
|
|
133 static int |
|
|
134 legacy_flash_erase_block (struct cyg_flash_dev *dev, |
|
|
135 const cyg_flashaddr_t block_base) |
|
|
136 __attribute__ ((section (".2ram.flash_program_buf"))); |
|
|
137 |
|
|
138 static int |
|
|
139 legacy_flash_erase_block (struct cyg_flash_dev *dev, |
|
|
140 const cyg_flashaddr_t block_base) |
|
|
141 { |
|
|
142 typedef int code_fun(cyg_flashaddr_t, unsigned int); |
|
|
143 code_fun *_flash_erase_block; |
|
|
144 size_t block_size = dev->block_info[0].block_size; |
|
|
145 |
|
|
146 _flash_erase_block = (code_fun*) __anonymizer(&flash_erase_block); |
|
|
147 |
|
|
148 return (*_flash_erase_block)(block_base, block_size); |
|
|
149 } |
|
|
150 |
|
|
151 static int |
|
|
152 legacy_flash_program(struct cyg_flash_dev *dev, |
|
|
153 cyg_flashaddr_t base, |
|
|
154 const void* data, const size_t len) |
|
|
155 __attribute__ ((section (".2ram.flash_program_buf"))); |
|
|
156 |
|
|
157 static int |
|
|
158 legacy_flash_program(struct cyg_flash_dev *dev, |
|
|
159 cyg_flashaddr_t base, |
|
|
160 const void* data, const size_t len) |
|
|
161 { |
|
|
162 typedef int code_fun(cyg_flashaddr_t, const void *, int, unsigned long, int); |
|
|
163 code_fun *_flash_program_buf; |
|
|
164 size_t block_size = dev->block_info[0].block_size; |
|
|
165 size_t block_mask = ~(block_mask -1); |
|
|
166 |
|
|
167 _flash_program_buf = (code_fun*) __anonymizer(&flash_program_buf); |
|
|
168 |
|
|
169 return (*_flash_program_buf)(base, data, len, block_mask ,block_size); |
|
|
170 } |
|
|
171 |
|
|
172 static int |
|
|
173 legacy_flash_read (struct cyg_flash_dev *dev, |
|
|
174 const cyg_flashaddr_t base, |
|
|
175 void* data, const size_t len) |
|
|
176 __attribute__ ((section (".2ram.flash_program_buf"))); |
|
|
177 |
|
|
178 static int |
|
|
179 legacy_flash_read (struct cyg_flash_dev *dev, |
|
|
180 const cyg_flashaddr_t base, |
|
|
181 void* data, const size_t len) |
|
|
182 { |
|
|
183 #ifdef CYGSEM_IO_FLASH_READ_INDIRECT |
|
|
184 typedef int code_fun(void *, void *, int, unsigned long, int); |
|
|
185 code_fun *_flash_read_buf; |
|
|
186 size_t block_size = dev->block_info[0].block_size; |
|
|
187 size_t block_mask = ~(block_mask -1); |
|
|
188 |
|
|
189 _flash_read_buf = (code_fun*) __anonymizer(&flash_read_buf); |
|
|
190 |
|
|
191 return = (*_flash_read_buf)(base, data, len, block_mask, buffer_size); |
|
|
192 #else |
|
|
193 memcpy(data,(void *)base, len); |
|
|
194 return CYG_FLASH_ERR_OK; |
|
|
195 #endif |
|
|
196 } |
|
|
197 |
|
|
198 |
|
|
199 static int |
|
|
200 legacy_flash_block_lock (struct cyg_flash_dev *dev, |
|
|
201 const cyg_flashaddr_t block_base) |
|
|
202 __attribute__ ((section (".2ram.flash_program_buf"))); |
|
|
203 |
|
|
204 static int |
|
|
205 legacy_flash_block_lock (struct cyg_flash_dev *dev, |
|
|
206 const cyg_flashaddr_t block_base) |
|
|
207 { |
|
|
208 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING |
|
|
209 typedef int code_fun(cyg_flashaddr_t); |
|
|
210 code_fun *_flash_lock_block; |
|
|
211 |
|
|
212 _flash_lock_block = (code_fun*) __anonymizer(&flash_lock_block); |
|
|
213 |
|
|
214 return (*_flash_lock_block)(block_base); |
|
|
215 #else |
|
|
216 return CYG_FLASH_ERR_INVALID; |
|
|
217 #endif |
|
|
218 } |
|
|
219 |
|
|
220 static int |
|
|
221 legacy_flash_block_unlock (struct cyg_flash_dev *dev, |
|
|
222 const cyg_flashaddr_t block_base) |
|
|
223 __attribute__ ((section (".2ram.flash_program_buf"))); |
|
|
224 |
|
|
225 static int |
|
|
226 legacy_flash_block_unlock (struct cyg_flash_dev *dev, |
|
|
227 const cyg_flashaddr_t block_base) |
|
|
228 { |
|
|
229 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING |
|
|
230 typedef int code_fun(cyg_flashaddr_t, int, int); |
|
|
231 code_fun *_flash_unlock_block; |
|
|
232 size_t block_size = dev->block_info[0].block_size; |
|
|
233 cyg_uint32 blocks = dev->block_info[0].blocks; |
|
|
234 |
|
|
235 _flash_unlock_block = (code_fun*) __anonymizer(&flash_unlock_block); |
|
|
236 |
|
|
237 return (*_flash_unlock_block)(block_base, block_size, blocks); |
|
|
238 #else |
|
|
239 return CYG_FLASH_ERR_INVALID; |
|
|
240 #endif |
|
|
241 } |
|
|
242 |
|
|
243 // Map a hardware status to a package error |
|
|
244 static int |
|
|
245 legacy_flash_hwr_map_error (struct cyg_flash_dev *dev, int err) |
|
|
246 __attribute__ ((section (".2ram.flash_program_buf"))); |
|
|
247 |
|
|
248 static int |
|
|
249 legacy_flash_hwr_map_error (struct cyg_flash_dev *dev, int err) |
|
|
250 { |
|
|
251 return flash_hwr_map_error(err); |
|
|
252 } |
|
|
253 |
|
|
254 void |
|
|
255 flash_dev_query(void* data) |
|
|
256 { |
|
|
257 typedef void code_fun(void*); |
|
|
258 code_fun *_flash_query; |
|
|
259 int d_cache, i_cache; |
|
|
260 |
|
|
261 _flash_query = (code_fun*) __anonymizer(&flash_query); |
|
|
262 |
|
|
263 HAL_FLASH_CACHES_OFF(d_cache, i_cache); |
|
|
264 (*_flash_query)(data); |
|
|
265 HAL_FLASH_CACHES_ON(d_cache, i_cache); |
|
|
266 } |
|
|
267 |
|
|
268 CYG_FLASH_FUNS(cyg_legacy_funs, |
|
|
269 legacy_flash_init, |
|
|
270 legacy_flash_query, |
|
|
271 legacy_flash_erase_block, |
|
|
272 legacy_flash_program, |
|
|
273 legacy_flash_read, |
|
|
274 legacy_flash_hwr_map_error, |
|
|
275 legacy_flash_block_lock, |
|
|
276 legacy_flash_block_unlock |
|
|
277 ); |
|
|
278 |
|
|
279 CYG_FLASH_DRIVER(cyg_zzlegacy_flashdev, // zz so that it probably comes last. |
|
|
280 &cyg_legacy_funs, |
|
|
281 NULL, // Pointer to config structure |
|
|
282 0, // Start address of flash |
|
|
283 0); // Size of private structure |
|
|
284 |