gonzui


Format: Advanced Search

tkernel_2/monitor/driver/flash/src/cfi_16x1.cbare sourcepermlink (0.01 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T-Kernel 2.0 Software Package
    4:  *
    5:  *    Copyright 2011 by Ken Sakamura.
    6:  *    This software is distributed under the latest version of T-License 2.x.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by T-Engine Forum(http://www.t-engine.org/) at 2011/05/17.
   10:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
   11:  *
   12:  *----------------------------------------------------------------------
   13:  */
   14: 
   15: /*
   16:  *      cfi_16x1.c
   17:  *
   18:  *       Flash ROM write: CFI(Intel) specification 16bit x 1 configuration
   19:  */
   20: 
   21: #include "flash.h"
   22: 
   23: #ifndef SECSZ
   24: #define SECSZ           0x20000                  // sector size 128kB x 1
   25: #endif
   26: 
   27: #ifndef BSECSZ
   28: #define BSECSZ          0x02000                 // boot sector size 8KB x 1
   29: #endif
   30: 
   31: #define SECMSK          (SECSZ - 1)             // sector mask
   32: 
   33: #define MAX_RETRY       (3)                   // maximum number of retries
   34: #define WAIT_CNT        0x10000000             // wait count (enough time)
   35: 
   36: #define WBSZ            (16)                      // write buffer size (H unit)
   37: 
   38: EXPORT  const UW FROM_SECSZ = SECSZ;     // sector size
   39: 
   40: /*
   41:  * check Flash ROM
   42:  */
   43: LOCAL   const JEDEC_SPEC  *checkFlashROM(_UH *rom)
   44: {
   45:         const JEDEC_SPEC       *spec;
   46:         UH     man, dev;
   47:         W      i;
   48: 
   49:         /* read Signature */
   50:         rom[0] = 0x0090;
   51:         man = rom[0] & 0x00ff; // ignore upper 8 bits
   52:         dev = rom[1] & 0x00ff; // ignore upper 8 bits
   53: 
   54:         /* obtain Flash ROM specification */
   55:         for (i = 0; i < N_JedecSpec; ++i) {
   56:                 spec = &JedecSpec[i];
   57:                 if (spec->man != man || spec->dev != dev) continue;
   58: 
   59:                 return spec;
   60:         }
   61: 
   62:         return NULL;   // unsupported target
   63: }
   64: 
   65: /*
   66:  * write one sector
   67:  *       rom should be the beginning of sector
   68:  *       if data = NULL, only erasure is performed
   69:  */
   70: LOCAL   ER        writesec(_UH *rom, UH *data, const JEDEC_SPEC *spec)
   71: {
   72:         _UH    *rp, *xp;
   73:         UH     *dp, *ep;
   74:         UH     d;
   75:         UW     n, mask, ptn;
   76:         W      i;
   77: 
   78:         mask = (spec->size * (1024*1024) - 1) & ~SECMSK;
   79:         n = (UW)rom & mask;
   80: 
   81:         /* sector configuration */
   82:         ptn = ( n == 0    )? spec->bsec:       /* bottm sector */
   83:               ( n == mask )? spec->tsec:       /* top sector */
   84:                              0x8000;         /* other */
   85: 
   86:         /* erase sector */
   87:         mask = 0x10000;
   88:         for ( rp = rom; (ptn & (mask - 1)) != 0; rp += BSECSZ/sizeof(UH) ) {
   89:                 if ( (ptn & (mask >>= 1)) == 0 ) continue;
   90: 
   91:                 /* wait for Ready */
   92:                 *rp = 0x0070;
   93:                 for (i = WAIT_CNT; --i >= 0 && (*rp & 0x0080) == 0; );
   94:                 if (i < 0) return E_IO;
   95: 
   96:                 /* release lock */
   97:                 *rp = 0x0060;
   98:                 *rp = 0x00D0;
   99: 
  100:                 /* wait for Ready */
  101:                 *rp = 0x0070;
  102:                 for (i = WAIT_CNT; --i >= 0 && (*rp & 0x0080) == 0; );
  103:                 if (i < 0) return E_IO;
  104: 
  105:                 /* erase sector */
  106:                 *rp = 0x0020;
  107:                 *rp = 0x00D0;
  108: 
  109:                 /* wait for completion of erasure */
  110:                 for (i = WAIT_CNT; --i >= 0 && ((d = *rp) & 0x0080) == 0; );
  111:                 if (i < 0 || (d & 0x003A) != 0) {
  112:                         *rp = 0x0050;                // clear error
  113:                         return E_IO;
  114:                 }
  115:         }
  116: 
  117:         if (data == NULL) return E_OK; // erase only
  118: 
  119:         /* write (using a buffer) */
  120:         rp = rom;
  121:         ep = data + SECSZ / sizeof(UH);
  122:         for (dp = data; dp < ep; ) {
  123:                 xp = rp;
  124:                 for (i = WAIT_CNT; --i >= 0; ) {
  125:                         *rp = 0x00E8;
  126:                         if (*xp & 0x0080) break;     // XSR check
  127:                 }
  128:                 if (i < 0) goto abort;
  129: 
  130:                 *rp = WBSZ - 1;
  131:                 for (i = 0; i < WBSZ; i++) *rp++ = *dp++;
  132:                 *xp = 0x00D0;
  133: 
  134:                 /* wait for completion of write */
  135:                 // *xp = 0x0070;
  136:                 for (i = WAIT_CNT; --i >= 0 && ((d = *xp) & 0x0080) == 0; );
  137:                 if (i < 0 || (d & 0x001A) != 0) {
  138:                         *xp = 0x0050;        // clear error
  139:                         goto abort;
  140:                 }
  141:         }
  142: 
  143:  abort:
  144:         /* write end */
  145:         *rom = 0x00FF;
  146:         if (dp < ep) return E_IO;
  147: 
  148:         /* Verify write */
  149:         for (dp = data; dp < ep; ) {
  150:                 if (*rom ++ != *dp++) return E_IO;
  151:         }
  152: 
  153:         return E_OK;
  154: }
  155: 
  156: /*
  157:  * FlashROM write
  158:  */
  159: EXPORT  ER       flashwr(UW addr, void *data, W nsec, BOOL reset)
  160: {
  161:         const JEDEC_SPEC       *spec;
  162:         _UH    *rom;
  163:         W      sec, retry;
  164:         ER     err;
  165: 
  166:         /* FlashROM sector address */
  167:         rom = (_UH *)NOCACHE_ADDR(addr & ~SECMSK);
  168: 
  169:         /* check FlashROM */
  170:         spec = checkFlashROM(rom);
  171: 
  172:         /* reset FlashROM */
  173:         *rom = 0x00FF;
  174: 
  175:         /* report error for unsupported FlashROM */
  176:         if (spec == NULL) return E_IO;
  177: 
  178:         /* erase or write in sector unit */
  179:         for (sec = 0; sec < nsec; sec++) {
  180:                 retry = MAX_RETRY;
  181: 
  182:                 do {
  183:                         err = writesec(rom, data, spec);
  184:                         if (err >= E_OK) break;
  185: 
  186:                         /* firstly, reset */
  187:                         *rom = 0x00FF;
  188:                 } while (--retry > 0);
  189: 
  190:                 if (err < E_OK) return err;
  191: 
  192:                 rom = (_UH *)((B *)rom + SECSZ);
  193:                 data = (B *)data + SECSZ;
  194:         }
  195: 
  196:         if (reset) flashwr_reset();    // do not return
  197: 
  198:         return E_OK;
  199: }