Mercurial > flash_v2
comparison packages/io/flash/current/src/flash.c @ 154:e2d866e32dac
Merge from eCos master repository on 2001-02-26-23:18:05-GMT
| author | jlarmour |
|---|---|
| date | Tue, 27 Feb 2001 01:21:45 +0000 |
| parents | 25e238959bae |
| children | b939e9cada46 |
comparison
equal
deleted
inserted
replaced
| 153:5e8f3b328bb3 | 154:e2d866e32dac |
|---|---|
| 56 // This can be used for running the function in place (RAM startup only), | 56 // This can be used for running the function in place (RAM startup only), |
| 57 // allowing calls to diag_printf() and similar. | 57 // allowing calls to diag_printf() and similar. |
| 58 #undef RAM_FLASH_DEV_DEBUG | 58 #undef RAM_FLASH_DEV_DEBUG |
| 59 #if !defined(CYG_HAL_STARTUP_RAM) && defined(RAM_FLASH_DEV_DEBUG) | 59 #if !defined(CYG_HAL_STARTUP_RAM) && defined(RAM_FLASH_DEV_DEBUG) |
| 60 # warning "Can only enable the flash debugging when configured for RAM startup" | 60 # warning "Can only enable the flash debugging when configured for RAM startup" |
| 61 # undef RAM_FLASH_DEV_DEBUG | 61 # undef CYGHWR_IO_FLASH_DEVICE_IN_RAM |
| 62 # define CYGHWR_IO_FLASH_DEVICE_IN_RAM 1 | |
| 62 #endif | 63 #endif |
| 63 | 64 |
| 64 struct flash_info flash_info; | 65 struct flash_info flash_info; |
| 65 | 66 |
| 66 int | 67 int |
| 77 flash_info.block_mask = ~(flash_info.block_size-1); | 78 flash_info.block_mask = ~(flash_info.block_size-1); |
| 78 flash_info.init = 1; | 79 flash_info.init = 1; |
| 79 return FLASH_ERR_OK; | 80 return FLASH_ERR_OK; |
| 80 } | 81 } |
| 81 | 82 |
| 83 #ifdef CYGHWR_IO_FLASH_DEVICE_IN_RAM | |
| 84 // Use this function to make function pointers anonymous - forcing the | |
| 85 // compiler to use jumps instead of branches when calling driver | |
| 86 // services. | |
| 87 static void* __anonymizer(void* p) | |
| 88 { | |
| 89 return p; | |
| 90 } | |
| 91 #endif | |
| 92 | |
| 82 // FIXME: Want to change all drivers to use this function. But it may | 93 // FIXME: Want to change all drivers to use this function. But it may |
| 83 // make sense to wait till device structure pointer arguments get | 94 // make sense to wait till device structure pointer arguments get |
| 84 // added as well. | 95 // added as well. |
| 85 void | 96 void |
| 86 flash_dev_query(void* data) | 97 flash_dev_query(void* data) |
| 87 { | 98 { |
| 88 extern char flash_query[], flash_query_end[]; | |
| 89 typedef void code_fun(void*); | 99 typedef void code_fun(void*); |
| 90 int code_len; | |
| 91 code_fun *_flash_query; | 100 code_fun *_flash_query; |
| 92 int d_cache, i_cache; | 101 int d_cache, i_cache; |
| 93 | 102 |
| 94 // Query the device driver - copy 'query' code to RAM for execution | 103 #ifdef CYGHWR_IO_FLASH_DEVICE_IN_RAM |
| 95 code_len = (unsigned long)&flash_query_end - (unsigned long)&flash_query; | 104 { |
| 96 _flash_query = (code_fun *)flash_info.work_space; | 105 externC code_fun flash_query; |
| 97 memcpy(_flash_query, &flash_query, code_len); | 106 _flash_query = (code_fun*) __anonymizer(&flash_query); |
| 107 } | |
| 108 #else | |
| 109 { | |
| 110 extern char flash_query[], flash_query_end[]; | |
| 111 int code_len; | |
| 112 | |
| 113 // Query the device driver - copy 'query' code to RAM for execution | |
| 114 code_len = (unsigned long)&flash_query_end - (unsigned long)&flash_query; | |
| 115 _flash_query = (code_fun *)flash_info.work_space; | |
| 116 memcpy(_flash_query, &flash_query, code_len); | |
| 117 } | |
| 118 #endif | |
| 98 | 119 |
| 99 HAL_FLASH_CACHES_OFF(d_cache, i_cache); | 120 HAL_FLASH_CACHES_OFF(d_cache, i_cache); |
| 100 #ifdef RAM_FLASH_DEV_DEBUG | |
| 101 _flash_query = &flash_query; | |
| 102 #endif | |
| 103 (*_flash_query)(data); | 121 (*_flash_query)(data); |
| 104 HAL_FLASH_CACHES_ON(d_cache, i_cache); | 122 HAL_FLASH_CACHES_ON(d_cache, i_cache); |
| 105 } | 123 } |
| 106 | 124 |
| 107 int | 125 int |
| 142 int | 160 int |
| 143 flash_erase(void *addr, int len, void **err_addr) | 161 flash_erase(void *addr, int len, void **err_addr) |
| 144 { | 162 { |
| 145 unsigned short *block, *end_addr; | 163 unsigned short *block, *end_addr; |
| 146 int stat = 0; | 164 int stat = 0; |
| 147 extern char flash_erase_block[], flash_erase_block_end[]; | |
| 148 int code_len; | |
| 149 typedef int code_fun(unsigned short *, unsigned int); | 165 typedef int code_fun(unsigned short *, unsigned int); |
| 150 code_fun *_flash_erase_block; | 166 code_fun *_flash_erase_block; |
| 151 int d_cache, i_cache; | 167 int d_cache, i_cache; |
| 152 | 168 |
| 153 if (!flash_info.init) { | 169 if (!flash_info.init) { |
| 154 return FLASH_ERR_NOT_INIT; | 170 return FLASH_ERR_NOT_INIT; |
| 155 } | 171 } |
| 156 | 172 |
| 157 // Copy 'erase' code to RAM for execution | 173 #ifdef CYGHWR_IO_FLASH_DEVICE_IN_RAM |
| 158 code_len = (unsigned long)&flash_erase_block_end - (unsigned long)&flash_erase_block; | 174 { |
| 159 _flash_erase_block = (code_fun *)flash_info.work_space; | 175 externC code_fun flash_erase_block; |
| 160 memcpy(_flash_erase_block, &flash_erase_block, code_len); | 176 _flash_erase_block = (code_fun*) __anonymizer(&flash_erase_block); |
| 161 | 177 } |
| 162 HAL_FLASH_CACHES_OFF(d_cache, i_cache); | 178 #else |
| 179 { | |
| 180 extern char flash_erase_block[], flash_erase_block_end[]; | |
| 181 int code_len; | |
| 182 | |
| 183 // Copy 'erase' code to RAM for execution | |
| 184 code_len = (unsigned long)&flash_erase_block_end - (unsigned long)&flash_erase_block; | |
| 185 _flash_erase_block = (code_fun *)flash_info.work_space; | |
| 186 memcpy(_flash_erase_block, &flash_erase_block, code_len); | |
| 187 } | |
| 188 #endif | |
| 189 | |
| 163 block = (unsigned short *)((unsigned long)addr & flash_info.block_mask); | 190 block = (unsigned short *)((unsigned long)addr & flash_info.block_mask); |
| 164 end_addr = (unsigned short *)((unsigned long)addr+len); | 191 end_addr = (unsigned short *)((unsigned long)addr+len); |
| 165 | 192 |
| 166 printf("... Erase from %p-%p: ", (void*)block, (void*)end_addr); | 193 printf("... Erase from %p-%p: ", (void*)block, (void*)end_addr); |
| 167 | 194 |
| 195 HAL_FLASH_CACHES_OFF(d_cache, i_cache); | |
| 168 while (block < end_addr) { | 196 while (block < end_addr) { |
| 169 #ifdef RAM_FLASH_DEV_DEBUG | |
| 170 _flash_erase_block = &flash_erase_block; | |
| 171 #endif | |
| 172 // Supply the blocksize for a gross check for erase success | 197 // Supply the blocksize for a gross check for erase success |
| 173 stat = (*_flash_erase_block)(block, flash_info.block_size); | 198 stat = (*_flash_erase_block)(block, flash_info.block_size); |
| 174 stat = flash_hwr_map_error(stat); | 199 stat = flash_hwr_map_error(stat); |
| 175 if (stat) { | 200 if (stat) { |
| 176 *err_addr = (void *)block; | 201 *err_addr = (void *)block; |
| 186 | 211 |
| 187 int | 212 int |
| 188 flash_program(void *_addr, void *_data, int len, void **err_addr) | 213 flash_program(void *_addr, void *_data, int len, void **err_addr) |
| 189 { | 214 { |
| 190 int stat = 0; | 215 int stat = 0; |
| 191 int code_len, size; | 216 int size; |
| 192 extern char flash_program_buf[], flash_program_buf_end[]; | |
| 193 typedef int code_fun(unsigned short *, unsigned short *, int); | 217 typedef int code_fun(unsigned short *, unsigned short *, int); |
| 194 code_fun *_flash_program_buf; | 218 code_fun *_flash_program_buf; |
| 195 unsigned short *addr = (unsigned short *)_addr; | 219 unsigned short *addr = (unsigned short *)_addr; |
| 196 unsigned short *data = (unsigned short *)_data; | 220 unsigned short *data = (unsigned short *)_data; |
| 197 int d_cache, i_cache; | 221 int d_cache, i_cache; |
| 198 | 222 |
| 199 if (!flash_info.init) { | 223 if (!flash_info.init) { |
| 200 return FLASH_ERR_NOT_INIT; | 224 return FLASH_ERR_NOT_INIT; |
| 201 } | 225 } |
| 202 | 226 |
| 203 // Copy 'program' code to RAM for execution | 227 #ifdef CYGHWR_IO_FLASH_DEVICE_IN_RAM |
| 204 code_len = (unsigned long)&flash_program_buf_end - (unsigned long)&flash_program_buf; | 228 { |
| 205 _flash_program_buf = (code_fun *)flash_info.work_space; | 229 externC code_fun flash_program_buf; |
| 206 memcpy(_flash_program_buf, &flash_program_buf, code_len); | 230 _flash_program_buf = (code_fun*) __anonymizer(&flash_program_buf); |
| 231 } | |
| 232 #else | |
| 233 { | |
| 234 int code_len; | |
| 235 extern char flash_program_buf[], flash_program_buf_end[]; | |
| 236 // Copy 'program' code to RAM for execution | |
| 237 code_len = (unsigned long)&flash_program_buf_end - (unsigned long)&flash_program_buf; | |
| 238 _flash_program_buf = (code_fun *)flash_info.work_space; | |
| 239 memcpy(_flash_program_buf, &flash_program_buf, code_len); | |
| 240 } | |
| 241 #endif | |
| 242 | |
| 243 printf("... Program from %p-%p at %p: ", (void*)data, | |
| 244 (void*)(((unsigned long)data)+len), (void*)addr); | |
| 245 | |
| 207 HAL_FLASH_CACHES_OFF(d_cache, i_cache); | 246 HAL_FLASH_CACHES_OFF(d_cache, i_cache); |
| 208 | |
| 209 printf("... Program from %p-%p at %p: ", (void*)data, (void*)(((unsigned long)data)+len), (void*)addr); | |
| 210 | |
| 211 while (len > 0) { | 247 while (len > 0) { |
| 212 size = len; | 248 size = len; |
| 213 if (size > flash_info.block_size) size = flash_info.block_size; | 249 if (size > flash_info.block_size) size = flash_info.block_size; |
| 214 #ifdef RAM_FLASH_DEV_DEBUG | 250 |
| 215 _flash_program_buf = &flash_program_buf; | |
| 216 #endif | |
| 217 stat = (*_flash_program_buf)(addr, data, size); | 251 stat = (*_flash_program_buf)(addr, data, size); |
| 218 stat = flash_hwr_map_error(stat); | 252 stat = flash_hwr_map_error(stat); |
| 219 if (stat) { | 253 if (stat) { |
| 220 *err_addr = (void *)addr; | 254 *err_addr = (void *)addr; |
| 221 break; | 255 break; |
| 235 int | 269 int |
| 236 flash_lock(void *addr, int len, void **err_addr) | 270 flash_lock(void *addr, int len, void **err_addr) |
| 237 { | 271 { |
| 238 unsigned short *block, *end_addr; | 272 unsigned short *block, *end_addr; |
| 239 int stat = 0; | 273 int stat = 0; |
| 240 extern char flash_lock_block[], flash_lock_block_end[]; | |
| 241 int code_len; | |
| 242 typedef int code_fun(unsigned short *); | 274 typedef int code_fun(unsigned short *); |
| 243 code_fun *_flash_lock_block; | 275 code_fun *_flash_lock_block; |
| 244 int d_cache, i_cache; | 276 int d_cache, i_cache; |
| 245 | 277 |
| 246 if (!flash_info.init) { | 278 if (!flash_info.init) { |
| 247 return FLASH_ERR_NOT_INIT; | 279 return FLASH_ERR_NOT_INIT; |
| 248 } | 280 } |
| 249 | 281 |
| 250 // Copy 'lock' code to RAM for execution | 282 #ifdef CYGHWR_IO_FLASH_DEVICE_IN_RAM |
| 251 code_len = (unsigned long)&flash_lock_block_end - (unsigned long)&flash_lock_block; | 283 { |
| 252 _flash_lock_block = (code_fun *)flash_info.work_space; | 284 externC code_fun flash_lock_block; |
| 253 memcpy(_flash_lock_block, &flash_lock_block, code_len); | 285 _flash_lock_block = (code_fun*) __anonymizer(&flash_lock_block); |
| 254 HAL_FLASH_CACHES_OFF(d_cache, i_cache); | 286 } |
| 287 #else | |
| 288 { | |
| 289 extern char flash_lock_block[], flash_lock_block_end[]; | |
| 290 int code_len; | |
| 291 // Copy 'lock' code to RAM for execution | |
| 292 code_len = (unsigned long)&flash_lock_block_end - (unsigned long)&flash_lock_block; | |
| 293 _flash_lock_block = (code_fun *)flash_info.work_space; | |
| 294 memcpy(_flash_lock_block, &flash_lock_block, code_len); | |
| 295 } | |
| 296 #endif | |
| 255 | 297 |
| 256 block = (unsigned short *)((unsigned long)addr & flash_info.block_mask); | 298 block = (unsigned short *)((unsigned long)addr & flash_info.block_mask); |
| 257 end_addr = (unsigned short *)((unsigned long)addr+len); | 299 end_addr = (unsigned short *)((unsigned long)addr+len); |
| 258 | 300 |
| 259 printf("... Lock from %p-%p: ", block, end_addr); | 301 printf("... Lock from %p-%p: ", block, end_addr); |
| 260 | 302 |
| 303 HAL_FLASH_CACHES_OFF(d_cache, i_cache); | |
| 261 while (block < end_addr) { | 304 while (block < end_addr) { |
| 262 #ifdef RAM_FLASH_DEV_DEBUG | |
| 263 _flash_lock_block = &flash_lock_block; | |
| 264 #endif | |
| 265 stat = (*_flash_lock_block)(block); | 305 stat = (*_flash_lock_block)(block); |
| 266 stat = flash_hwr_map_error(stat); | 306 stat = flash_hwr_map_error(stat); |
| 267 if (stat) { | 307 if (stat) { |
| 268 *err_addr = (void *)block; | 308 *err_addr = (void *)block; |
| 269 break; | 309 break; |
| 279 int | 319 int |
| 280 flash_unlock(void *addr, int len, void **err_addr) | 320 flash_unlock(void *addr, int len, void **err_addr) |
| 281 { | 321 { |
| 282 unsigned short *block, *end_addr; | 322 unsigned short *block, *end_addr; |
| 283 int stat = 0; | 323 int stat = 0; |
| 284 extern char flash_unlock_block[], flash_unlock_block_end[]; | |
| 285 int code_len; | |
| 286 typedef int code_fun(unsigned short *, int, int); | 324 typedef int code_fun(unsigned short *, int, int); |
| 287 code_fun *_flash_unlock_block; | 325 code_fun *_flash_unlock_block; |
| 288 int d_cache, i_cache; | 326 int d_cache, i_cache; |
| 289 | 327 |
| 290 if (!flash_info.init) { | 328 if (!flash_info.init) { |
| 291 return FLASH_ERR_NOT_INIT; | 329 return FLASH_ERR_NOT_INIT; |
| 292 } | 330 } |
| 293 | 331 |
| 294 // Copy 'lock' code to RAM for execution | 332 #ifdef CYGHWR_IO_FLASH_DEVICE_IN_RAM |
| 295 code_len = (unsigned long)&flash_unlock_block_end - (unsigned long)&flash_unlock_block; | 333 { |
| 296 _flash_unlock_block = (code_fun *)flash_info.work_space; | 334 externC code_fun flash_unlock_block; |
| 297 memcpy(_flash_unlock_block, &flash_unlock_block, code_len); | 335 _flash_unlock_block = (code_fun*) __anonymizer(&flash_unlock_block); |
| 298 HAL_FLASH_CACHES_OFF(d_cache, i_cache); | 336 } |
| 337 #else | |
| 338 { | |
| 339 extern char flash_unlock_block[], flash_unlock_block_end[]; | |
| 340 int code_len; | |
| 341 // Copy 'lock' code to RAM for execution | |
| 342 code_len = (unsigned long)&flash_unlock_block_end - (unsigned long)&flash_unlock_block; | |
| 343 _flash_unlock_block = (code_fun *)flash_info.work_space; | |
| 344 memcpy(_flash_unlock_block, &flash_unlock_block, code_len); | |
| 345 } | |
| 346 #endif | |
| 299 | 347 |
| 300 block = (unsigned short *)((unsigned long)addr & flash_info.block_mask); | 348 block = (unsigned short *)((unsigned long)addr & flash_info.block_mask); |
| 301 end_addr = (unsigned short *)((unsigned long)addr+len); | 349 end_addr = (unsigned short *)((unsigned long)addr+len); |
| 302 | 350 |
| 303 printf("... Unlock from %p-%p: ", block, end_addr); | 351 printf("... Unlock from %p-%p: ", block, end_addr); |
| 304 | 352 |
| 353 HAL_FLASH_CACHES_OFF(d_cache, i_cache); | |
| 305 while (block < end_addr) { | 354 while (block < end_addr) { |
| 306 #ifdef RAM_FLASH_DEV_DEBUG | |
| 307 _flash_unlock_block = &flash_unlock_block; | |
| 308 #endif | |
| 309 stat = (*_flash_unlock_block)(block, flash_info.block_size, flash_info.blocks); | 355 stat = (*_flash_unlock_block)(block, flash_info.block_size, flash_info.blocks); |
| 310 stat = flash_hwr_map_error(stat); | 356 stat = flash_hwr_map_error(stat); |
| 311 if (stat) { | 357 if (stat) { |
| 312 *err_addr = (void *)block; | 358 *err_addr = (void *)block; |
| 313 break; | 359 break; |
| 345 return "Device/region is write-protected"; | 391 return "Device/region is write-protected"; |
| 346 case FLASH_ERR_NOT_INIT: | 392 case FLASH_ERR_NOT_INIT: |
| 347 return "FLASH sub-system not initialized"; | 393 return "FLASH sub-system not initialized"; |
| 348 case FLASH_ERR_DRV_VERIFY: | 394 case FLASH_ERR_DRV_VERIFY: |
| 349 return "Data verify failed after operation"; | 395 return "Data verify failed after operation"; |
| 396 case FLASH_ERR_DRV_TIMEOUT: | |
| 397 return "Driver timed out waiting for device"; | |
| 398 case FLASH_ERR_DRV_WRONG_PART: | |
| 399 return "Driver does not support device"; | |
| 350 default: | 400 default: |
| 351 return "Unknown error"; | 401 return "Unknown error"; |
| 352 } | 402 } |
| 353 } | 403 } |
| 354 | 404 |
