File indexing completed on 2025-05-11 08:23:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 #ifdef TESTING
0056
0057 #define TIMEOUT_US 100000
0058 #define rtems_task_wake_after(t) sleep(t)
0059 #define CLOCKRATE_GET(p) (*(p)=1)
0060
0061 #else
0062
0063 #include <rtems.h>
0064 #define TIMEOUT_US 1000
0065 #define CLOCKRATE_GET(p) *p = rtems_clock_get_ticks_per_second()
0066
0067 #endif
0068
0069 #define ERASE_TIMEOUT_S 2
0070
0071 #include <stdio.h>
0072 #include <inttypes.h>
0073 #include <stdlib.h>
0074
0075 #include <bsp/flashPgmPvt.h>
0076
0077 #define DEBUG 0
0078 #undef DEBUG
0079
0080 #ifdef DEBUG
0081 #define STATIC
0082 #else
0083 #define STATIC static
0084 #endif
0085
0086 #define NumberOf(arr) (sizeof(arr)/sizeof(arr[0]))
0087
0088
0089
0090
0091
0092
0093 #define F_CMD_RD_ARR 0xffffffff
0094 #define F_CMD_RD_ID 0x90909090
0095 #define F_CMD_RD_STA 0x70707070
0096 #define F_CMD_WR_STA 0x50505050
0097 #define F_CMD_WR_BUF 0xe8e8e8e8
0098 #define F_CMD_WR_WRD 0x40404040
0099 #define F_CMD_WR_ERA 0x20202020
0100 #define F_CMD_WR_LCK 0x60606060
0101 #define F_CMD_WR_CMD 0xd0d0d0d0
0102 #define F_CMD_WR_LCK_SET 0x01010101
0103
0104
0105 #define STA_RDY (1<<7)
0106 #define STA_ES (1<<6)
0107 #define STA_EE (1<<5)
0108 #define STA_PE (1<<4)
0109 #define STA_VE (1<<3)
0110 #define STA_PS (1<<2)
0111 #define STA_LE (1<<1)
0112 #define STA_EFP (1<<0)
0113
0114
0115 #define STA_ERROR (STA_EE|STA_PE|STA_VE|STA_LE)
0116
0117
0118 #define STA_RDYRDY 0x00800080
0119
0120
0121
0122 STATIC int
0123 flash_get_id_intel(struct bankdesc *, uint32_t, uint32_t *, uint32_t *);
0124
0125 STATIC void
0126 flash_unlock_block_intel(struct bankdesc *, uint32_t);
0127
0128 STATIC void
0129 flash_lock_block_intel(struct bankdesc *, uint32_t);
0130
0131 STATIC int
0132 flash_erase_block_intel(struct bankdesc *, uint32_t);
0133
0134 STATIC uint32_t
0135 flash_check_ready_intel(struct bankdesc *, uint32_t);
0136
0137 STATIC void
0138 flash_print_stat_intel(struct bankdesc *, uint32_t, int);
0139
0140 STATIC void
0141 flash_array_mode_intel(struct bankdesc *, uint32_t);
0142
0143 STATIC uint32_t
0144 flash_write_line_intel(struct bankdesc *, uint32_t, const char *, uint32_t);
0145
0146
0147
0148 static struct flash_bank_ops intelOps = {
0149 get_id : flash_get_id_intel,
0150 unlock_block: flash_unlock_block_intel,
0151 lock_block : flash_lock_block_intel,
0152 erase_block : flash_erase_block_intel,
0153 check_ready : flash_check_ready_intel,
0154 print_stat : flash_print_stat_intel,
0155 array_mode : flash_array_mode_intel,
0156 write_line : flash_write_line_intel,
0157 };
0158
0159 static struct devdesc intelDevs[] = {
0160 { 0x8801, "K3 64Mb", 8*1024*1024, 0x40, 0x20000 },
0161 { 0x8802, "K3 128Mb", 16*1024*1024, 0x40, 0x20000 },
0162 { 0x8803, "K3 256Mb", 32*1024*1024, 0x40, 0x20000 },
0163 { 0x8805, "K18 64Mb", 8*1024*1024, 0x40, 0x20000 },
0164 { 0x8806, "K18 128Mb", 16*1024*1024, 0x40, 0x20000 },
0165 { 0x8807, "K18 256Mb", 32*1024*1024, 0x40, 0x20000 },
0166 { 0x0016, "J3 32Mb", 4*1024*1024, 0x20, 0x20000 },
0167 { 0x0017, "J3 64Mb", 8*1024*1024, 0x20, 0x20000 },
0168 { 0x0018, "J3 128Mb", 16*1024*1024, 0x20, 0x20000 },
0169 { 0x001d, "J3 256Mb", 32*1024*1024, 0x20, 0x20000 },
0170 { 0, 0, 0, 0}
0171 };
0172
0173 struct vendesc BSP_flash_vendor_intel[] =
0174 {
0175 { 0x89, "Intel", intelDevs, &intelOps },
0176 { 0, 0}
0177 };
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187 STATIC uint32_t
0188 BSP_flashReadRaw(uint32_t cmd, uint32_t addr)
0189 {
0190 #if DEBUG > 4
0191 printf("Writing CMD *0x%08"PRIx32" = 0x%08"PRIx32"\n", addr, cmd);
0192 #endif
0193 #ifdef TESTING
0194 return STA_RDYRDY;
0195 #else
0196 if ( cmd & 0xffff0000 ) {
0197
0198 addr &= ~(sizeof(uint32_t)-1);
0199 *(A32)addr = cmd;
0200 return *(A32)addr;
0201 } else if ( cmd & 0xffffff00 ) {
0202
0203 addr &= ~(sizeof(uint16_t)-1);
0204 *(A16)addr = cmd;
0205 return *(A16)addr;
0206 } else {
0207 *(A8)addr = cmd;
0208 return *(A8)addr;
0209 }
0210 #endif
0211 }
0212
0213 STATIC void
0214 BSP_flashWriteRaw(uint32_t val, uint32_t addr)
0215 {
0216 #ifdef TESTING
0217 printf("Writing CNT *0x%08"PRIx32" = 0x%08"PRIx32"\n", addr, val);
0218 #else
0219
0220
0221 addr &= ~(sizeof(uint32_t)-1);
0222 *(A32)addr = val;
0223 #endif
0224 }
0225
0226 STATIC uint32_t
0227 flash_pend(struct bankdesc *b, uint32_t a, uint32_t timeout_us)
0228 {
0229 uint32_t then, now, sta;
0230
0231 then = BSP_flashBspOps.read_us_timer();
0232
0233 do {
0234 sta = BSP_flashReadRaw(F_CMD_RD_STA, a);
0235 now = BSP_flashBspOps.read_us_timer();
0236 if ( now-then > timeout_us ) {
0237
0238 sta = -1;
0239 break;
0240 }
0241 } while ( STA_RDYRDY != (STA_RDYRDY & sta) );
0242
0243
0244 flash_array_mode_intel(b, a);
0245
0246 return STA_RDYRDY == sta ? 0 : sta;
0247 }
0248
0249
0250
0251
0252 STATIC void
0253 flash_array_mode_intel(struct bankdesc *b, uint32_t a)
0254 {
0255 BSP_flashReadRaw(F_CMD_RD_ARR, a);
0256 }
0257
0258
0259 STATIC void
0260 flash_print_stat_intel(struct bankdesc *b, uint32_t sta, int verbose)
0261 {
0262 int ch;
0263 if ( sta & STA_ERROR ) {
0264 ch = ':';
0265 fprintf(stderr,"Errors found");
0266 if ( STA_EE & sta ) {
0267 fprintf(stderr,"%c ERASE",ch);
0268 ch = ',';
0269 }
0270 if ( STA_PE & sta ) {
0271 fprintf(stderr,"%c PROGRAM",ch);
0272 ch = ',';
0273 }
0274 if ( STA_VE & sta ) {
0275 fprintf(stderr,"%c VPEN TOO LOW",ch);
0276 ch = ',';
0277 }
0278 if ( STA_LE & sta ) {
0279 fprintf(stderr,"%c BLOCK LOCKED",ch);
0280 ch = ',';
0281 }
0282 fprintf(stderr,"\n");
0283 }
0284 if ( verbose ) {
0285 fprintf(stderr,"%sREADY\n",STA_RDY & sta ? "" : "NOT ");
0286 }
0287 }
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299 STATIC uint32_t
0300 flash_check_ready_intel(struct bankdesc *b, uint32_t addr)
0301 {
0302 uint32_t sta;
0303
0304 (void)BSP_flashReadRaw(F_CMD_WR_STA, addr);
0305 if ( STA_RDYRDY != (STA_RDYRDY & (sta=BSP_flashReadRaw(F_CMD_RD_STA, addr))) ) {
0306 fprintf(stderr,"Flash not ready (@0x%08"PRIx32")\n", addr);
0307 flash_print_stat_intel(b, sta, 0);
0308 } else {
0309 sta = 0;
0310 }
0311
0312 flash_array_mode_intel(b, addr);
0313 return sta;
0314 }
0315
0316
0317
0318
0319
0320
0321
0322
0323 STATIC int
0324 flash_erase_block_intel(struct bankdesc *b, uint32_t addr)
0325 {
0326 uint32_t sta;
0327 int i;
0328 rtems_interval p;
0329
0330 if ( (sta = flash_check_ready_intel(b, addr)) )
0331 return sta;
0332
0333 (void)BSP_flashReadRaw(F_CMD_WR_ERA, addr);
0334 (void)BSP_flashReadRaw(F_CMD_WR_CMD, addr);
0335
0336 CLOCKRATE_GET( &p );
0337 i = p * ERASE_TIMEOUT_S;
0338
0339 while ( STA_RDYRDY != (STA_RDYRDY & (sta = BSP_flashReadRaw(F_CMD_RD_STA, addr))) && --i > 0 ) {
0340 rtems_task_wake_after(1);
0341 }
0342
0343 (void)flash_array_mode_intel(b, addr);
0344 if ( 0 == i ) {
0345 fprintf(stderr,"Flash erase block: timeout\n");
0346 return -1;
0347 }
0348
0349
0350 for ( i = 0; i<b->fblksz; i++ ) {
0351 if ( (char)0xff != ((char*)addr)[i] ) {
0352 fprintf(stderr,"ERROR: Erase verification failed at %p\n",
0353 ((char*)addr) + i);
0354 return -1;
0355 }
0356 }
0357 return STA_RDYRDY == sta ? 0 : sta;
0358 }
0359
0360
0361
0362
0363
0364
0365
0366 STATIC void
0367 flash_unlock_block_intel(struct bankdesc *b, uint32_t addr)
0368 {
0369 #ifdef DEBUG
0370 printf("Unlocking block 0x%08"PRIx32"\n", addr);
0371 #endif
0372 (void)BSP_flashReadRaw(F_CMD_WR_LCK, addr);
0373 (void)BSP_flashReadRaw(F_CMD_WR_CMD, addr);
0374 flash_pend(b, addr, TIMEOUT_US);
0375 }
0376
0377
0378
0379
0380
0381
0382
0383 STATIC void
0384 flash_lock_block_intel(struct bankdesc *b, uint32_t addr)
0385 {
0386 #ifdef DEBUG
0387 printf("Locking block 0x%08"PRIx32"\n", addr);
0388 #endif
0389 (void)BSP_flashReadRaw(F_CMD_WR_LCK, addr);
0390 (void)BSP_flashReadRaw(F_CMD_WR_LCK_SET, addr);
0391 flash_pend(b, addr, TIMEOUT_US);
0392 }
0393
0394 STATIC uint32_t
0395 flash_write_line_intel(struct bankdesc *b, uint32_t a, const char *s, uint32_t N)
0396 {
0397 uint32_t sta, Nspla, nxt, j;
0398 union {
0399 uint32_t u;
0400 char c[sizeof(uint32_t)];
0401 } buf;
0402
0403
0404 if ( STA_RDYRDY != (sta = BSP_flashReadRaw(F_CMD_WR_BUF, a)) ) {
0405 return sta;
0406 }
0407
0408
0409 N /= FLASH_STRIDE(b);
0410
0411
0412 Nspla = (N<<8) | N;
0413 Nspla = (Nspla<<16) | Nspla;
0414 BSP_flashWriteRaw(Nspla - 0x01010101, a);
0415
0416
0417 for (nxt = a; N>0; N--) {
0418 #if defined(TESTING) || (DEBUG > 4)
0419 printf("Writing DAT *0x%08"PRIx32" = 0x%08"PRIx32"\n", nxt, *(const uint32_t*)s);
0420 #endif
0421
0422 for ( j=0; j<sizeof(buf.u); j++ ) {
0423 buf.c[j] = *s++;
0424 }
0425 *(A32)nxt = buf.u;
0426 nxt += FLASH_STRIDE(b);
0427 }
0428
0429 BSP_flashReadRaw(F_CMD_WR_CMD, a);
0430
0431 sta = flash_pend(b, a, TIMEOUT_US);
0432
0433 return sta;
0434 }
0435
0436
0437
0438
0439
0440
0441
0442
0443 STATIC int
0444 flash_get_id_intel(struct bankdesc *b, uint32_t addr, uint32_t *pVendorId, uint32_t *pDeviceId)
0445 {
0446 uint16_t v,d;
0447
0448 if ( 4 != FLASH_STRIDE(b) ) {
0449 fprintf(stderr,"intel flash programmer: Strides other than 4 not implemented yet\n");
0450 return -1;
0451 }
0452
0453
0454 v = BSP_flashReadRaw(F_CMD_RD_ID, addr);
0455 d = BSP_flashReadRaw(F_CMD_RD_ID, addr + FLASH_STRIDE(b));
0456
0457
0458 flash_array_mode_intel(b, addr);
0459
0460 *pVendorId = v;
0461 *pDeviceId = d;
0462
0463 return 0;
0464 }