📄 flsim.c
字号:
cnt = (simDoc->ppp_count[(int)page / 2]) >> 4; if (ppp != NULL) *ppp = cnt; if (cnt >= simDoc->conf.ppp_limit) { DEBUG_PRINT(("FLSim: PPP limit exceeded.\n")); return flWriteFault; } /* increment this page's PPP counter */ simDoc->ppp_count[(int)page / 2] += (1 << 4); } else { /* even page; PPP count is in FLSim_t.ppp_count[], bits 3..0 */ cnt = simDoc->ppp_count[(int)page / 2] & 0x0f; if (ppp != NULL) *ppp = cnt; if (cnt >= simDoc->conf.ppp_limit) { DEBUG_PRINT(("FLSim: PPP limit exceeded.\n")); return flWriteFault; } /* increment this page's PPP counter */ cnt ++; cnt &= 0x0f; simDoc->ppp_count[(int)page / 2] = cnt; } return flOK;}/* -------------------------------------------------------------------------- * * * * s i m _ c l e a r _ s t a t s * * * * Clear MTD statistics on simDoc. . * * * * Parameters: * * * * simDoc : simulated DiskOnChip * * * * -------------------------------------------------------------------------- */static void sim_clear_stats ( FLSim_t * simDoc ){ memset( &simDoc->stats, 0, sizeof(FLSimStat_t) );}/* -------------------------------------------------------------------------- * * * * s i m _ c o n f _ s a n i t y * * * * Check simDoc configuration structure for sanity. * * * * Parameters: * * * * conf : simDoc configuration to check * * * * -------------------------------------------------------------------------- */static FLStatus sim_conf_sanity ( FLSimConf_t * conf ){ if (conf == NULL) return flBadParameter; /* flash type is either NFTL_ENABLED or INFTL_ENABLED */ if ((conf->flags != NFTL_ENABLED) && (conf->flags != INFTL_ENABLED)) return flBadParameter; /* currently only interleaves 1, 2 and 4 are supported */ if ((conf->interlv != 1) && (conf->interlv != 2) && (conf->interlv != 4)) { DEBUG_PRINT(("FLSim: Unsupported interleave.\n")); return flBadParameter; } /* check PPP (Partial Page Programming) limit */ if ((conf->ppp_limit < FL_SIM_MIN_PPP_LIMIT) || (conf->ppp_limit > FL_SIM_MAX_PPP_LIMIT)) { DEBUG_PRINT(("FLSim: Unsupported PPP limit.\n")); return flBadParameter; } /* check ECC size */ if ((conf->ecc_size < 0) || (conf->ecc_size > FL_SIM_MAX_ECC_SIZE)) { DEBUG_PRINT(("FLSim: Unsupported ECC size.\n")); return flBadParameter; } /* block size must be multiple of page size */ if (conf->block_size % conf->page_size != 0) { DEBUG_PRINT(("FLSim: incompatible block and page sizes.\n")); return flBadParameter; } /* chip size must be multiple of block size */ if (conf->chip_size % conf->block_size != 0) { DEBUG_PRINT(("FLSim: incompatible block and chip sizes.\n")); return flBadParameter; } /* extra area should not be larger then page size */ if (conf->page_extra_size > conf->page_size) { DEBUG_PRINT(("FLSim: page's extra area is larger then page itself.\n")); return flBadParameter; } /* total size of flash array must be reasonable */ if ((conf->chips * (unsigned long)conf->chip_size) > FL_SIM_MAX_FLASH_ARRAY_SIZE) { DEBUG_PRINT(("FLSim: flash array is too large.\n")); return flBadParameter; } return flOK;}/* -------------------------------------------------------------------------- * * * * s i m _ c h k _ o v e r w r i t e * * * * Check if it is possible to write new data over existing one. * * * * Parameters: * * * * old : existing flash data * * new : new data to write over existing one * * new : number of bytes to overwrite * * * * Returns: * * * * flOK if it's possible to write over existing data, error otherwise * * * * -------------------------------------------------------------------------- */static FLStatus sim_chk_overwrite ( const char * old, const char FAR1 * new, int len ){ if( (len > 32) && ((pointerToPhysical(new) % sizeof(long) == 0)) && ((pointerToPhysical(old) % sizeof(long) == 0)) ) { /* buffers are aligned at long word and large, so do it in 32-bit */ unsigned long FAR1 * new32 = (unsigned long FAR1 *) new; unsigned long * old32 = (unsigned long *) old; int len32 = len / sizeof(unsigned long); for ( ; len32 > 0; new32++, old32++, len32--) { if( (*new32 & *old32) != *new32 ) { DEBUG_PRINT(("FLSim: can't write over unerased flash.\n")); return flWriteFault; } } len = len % sizeof(unsigned long); new = (char FAR1 *) new32; old = (char *) old32; } /* do it in 8-bit */ for ( ; len > 0; new++, old++, len--) { if( (*new & *old) != *new ) { DEBUG_PRINT(("FLSim: can't write over unerased flash.\n")); return flWriteFault; } } return flOK;}/* -------------------------------------------------------------------------- * * * * f l s i m M e m N e e d e d * * * * Helper routine, to be called from outside of simDoc module. * * Calculates how much memory required for simDoc of specified configuration. * * * * Parameters: * * * * conf : simDoc configuration * * * * Returns: * * * * zero if configuration is bad, otherwise amount of required memory * * * * -------------------------------------------------------------------------- */long flsimMemNeeded ( FLSimConf_t FAR1 * conf ){ FLSimConf_t tmp; long bytes_needed; long blocks; long pages; /* save configuration locally */ tffscpy (&tmp, conf, sizeof(FLSimConf_t)); /* check configuration for sanity */ if( sim_conf_sanity(&tmp) != flOK ) return 0; /* total blocks and pages on this simDoc */ blocks = (tmp.chips * tmp.chip_size) / tmp.block_size; pages = (tmp.chips * tmp.chip_size) / tmp.page_size; /* calculated how much we need for all simDoc's pages */ bytes_needed = pages * (tmp.page_size + tmp.page_extra_size); /* add BBT (1 byte per block) and PPP counters (4 bits per page) */ bytes_needed += blocks; bytes_needed += ((pages / 2) + 1); /* flsocket.c requires alignment at 4 KByte boundary ... */ bytes_needed += FL_SIM_4KB_ALIGNMENT; return bytes_needed;}/* -------------------------------------------------------------------------- * * * * f l s i m C l e a r S t a t i s t i c s * * * * Helper routine, to be called from outside of simDoc module. * * Clear MTD statistics on specified socket. * * * * Parameters: * * * * socket : socket # (0 .. SOCKETS) * * * * Returns: * * * * zero on success, otherwise -1 * * * * -------------------------------------------------------------------------- */int flsimClearStatistics ( int socket ){ if (socket >= SOCKETS) return -1; sim_clear_stats( &sims[socket] ); return 0;}/* -------------------------------------------------------------------------- * * * * f l s i m R e t r i e v e S t a t i s t i c s * * * * Helper routine, to be called from outside of simDoc module. * * Retruns MTD statistics on specified socket. * * * * Parameters: * * * * socket : socket # (0 .. SOCKETS) * * stats : pointer to FLSimStat_t struct to return MTD statistics in * * * * Returns: * * * * zero on success, otherwise -1 * * * * -------------------------------------------------------------------------- */int flsimRetrieveStatistics ( int socket, FLSimStat_t FAR1 * stats ){ /* argument sanity check */ if (socket >= SOCKETS) return -1; if (stats == NULL) return -1; /* copy this simDoc's MTD statistics into target buffer */ tffscpy( stats, &(sims[socket].stats), sizeof(FLSimStat_t) ); return 0;}/* -------------------------------------------------------------------------- * * * * f l s i m C h a n g e B B T * * * * Helper routine, to be called from outside of simDoc module. * * Change single BBT entry corresponding for specified address. * * * * Parameters: * * * * socket : socket # (0 .. SOCKETS) * * addr : block's address (not necessarily aligned at block's start) * * new : new entry to put in BBT * * old : if not NULL, return old BBT entry here * * * * Returns: * * * * zero on success, otherwise -1 * * * * -------------------------------------------------------------------------- */int flsimChangeBBT ( int socket, long addr, char new, char * old ){ FLSim_t * simDoc; long block; /* arguements sanity check */ if (socket >= SOCKETS) return -1; simDoc = &(sims[socket]); if (addr > (simDoc->conf.chips * simDoc->conf.chip_size)) return -1; block = addr / simDoc->conf.block_size; /* return old BBT entry if requested */ if (old != NULL) *old = simDoc->bbt[block]; /* change BBT entry as specified */ simDoc->bbt[block] = new; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -