📄 nand_media.c
字号:
/*============================================================================
____________________________________________________________________________
______________________________________________
SSSS M M CCCC Standard Microsystems Corporation
S MM MM SSSS C Austin Design Center
SSS M M M S C 11000 N. Mopac Expressway
S M M SSS C Stonelake Bldg. 6, Suite 500
SSSS M M S CCCC Austin, Texas 78759
SSSS ______________________________________________
____________________________________________________________________________
Copyright(C) 1999, Standard Microsystems Corporation
All Rights Reserved.
This program code listing is proprietary to SMSC and may not be copied,
distributed, or used without a license to do so. Such license may have
Limited or Restricted Rights. Please refer to the license for further
clarification.
____________________________________________________________________________
Notice: The program contained in this listing is a proprietary trade
secret of SMSC, Hauppauge, New York, and is copyrighted
under the United States Copyright Act of 1976 as an unpublished work,
pursuant to Section 104 and Section 408 of Title XVII of the United
States code. Unauthorized copying, adaption, distribution, use, or
display is prohibited by this law.
____________________________________________________________________________
Use, duplication, or disclosure by the Government is subject to
restrictions as set forth in subparagraph(c)(1)(ii) of the Rights
in Technical Data and Computer Software clause at DFARS 52.227-7013.
Contractor/Manufacturer is Standard Microsystems Corporation,
80 Arkay Drive, Hauppauge, New York, 1178-8847.
____________________________________________________________________________
____________________________________________________________________________
nand_media.c - nand flash media class implementation
____________________________________________________________________________
comments tbd
____________________________________________________________________________
Revision History
Date Who Comment
________ ___ _____________________________________________________________
06/21/02 cds initial version - derives from the sm_media methods to ensure
the correct chip is selected before performing any sort of
access to the flash ram. These methods are called by the
media and mapper code, set up the media, then call the base
sm_media functions to perform the work.
06/25/02 cds incorporated boot block reading/writing for device usb config
info
06/26/02 cds fixed multi-card reads/writes by adjusting when the card select
is called in the fmc xfers, and fixed the chip select to
multiply the # of chips by the max zone for the particular type
of chip detected, instead of assuming that it was 8 zones per chip.
06/27/02 cds - implemented nand-specific set_read/write/erase addr functions
that can be called vcalled from the smart media base class. these
functions calculate the chip-based zone from the global g_addr_zone.
- fixed select_chip equation to correctly select a chip from g_addr_zone
- added new variables g_nand_num_chips and g_nand_max_zones_per_chip
to allow future chip auto-detection.
07/09/02 cds _media_data(sectors_per_block) and g_addr_sector 8->16 bit conversion
07/09/02 cds renamed WorkBuf to g_sector_buffer
07/16/02 cds removed extra code that checks for 256 byte page sizes. these
aren't supported on nand arrays.
08/06/02 cds added some debug code (commented out in real build) to dump
all pages from a particular logical block.
08/09/02 cds - used attribute flag to determine whether to force Smart Media
compatible rw cycle timing for a data xfer.
- separated setting the device address from code that calculates
a the physical address from the mapper's virtual address.
- converted physical address variable into 3 separate xdata bytes
for quick-access when incrementing & writing to the device.
08/13/02 cds updated nand_va2pa functions to call the n2k versions for calculating
addresses on 2k paged media.
08/20/02 cds removed some debug code which dumped logical sectors
09/04/02 cds address name & usage change-over
g_addr_sector => g_addr_page,
g_addr_page => g_addr_segment,
_media_data(sectors_per_block) => _media_data(pages_per_block)
_media_data(cis_phy_block) => _media_data(boot_block)
_media_data(cis_sector) => _media_data(boot_sector)
(new item) => _media_data(segments_per_page)
10/16/02 cds fixed nand_boot_seek and nand_boot_write_flush to work with
2k paged chips by calling virtual _write_sector() function, and
setting g_addr_segment to 0.
10/17/02 cds - project-wide lun data & vtbl paging to reduce code space.
- removed g_active_media from _lun_data, _lun_() virtual functions
- added _lun_data_rd() and _lun_data_wr() macros to bypass lun paging
- added lun_set_active(log_lun) function to switch luns
10/23/02 cds set g_addr_rd_phy_blk to _media_data(boot_block) on nand_boot_write_flush
for 2k paged media for copying existing data into to the buffer before overwriting
with nvstore data. (future robustization)
11/21/02 ds Modified nand_write_boot_flush to suit nand_int implementation.
============================================================================*/
#define __nand_media_dot_c__
#include "project.h"
// provide vtable definition for 'nand_media'
code _vtbl_defn(nand_media) ;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
extern xdata uint8 g_sector_buffer[] ;
extern void fmc_dbg_dump_sector(uint8* sector) reentrant ;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
t_result sm_media_check_format(void)reentrant;
t_result sm_media_seek_cis(void) reentrant;
t_result sm_read_cis_sect(uint8 *)reentrant;
t_result sm_validate_cis(uint8 *) reentrant ;
t_result sm_media_erase_block(void)reentrant;
t_result sm_wait_rdy_with_timeout(uint16 ) reentrant;
extern void util_trace_buffer(uint8* sector, uint16 size) reentrant;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static xdata uint8 _nand_boot_cache[256] ;
//+-----------------------------------------------------------------------------
// Name:
// nand_boot_read()
//
// Declaration:
// t_result nand_boot_read(void) reentrant
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
uint8 nand_boot_read(uint8 addr) reentrant
{
TRACE2(427, nand, 0, "nand_boot_read(%d): %02x", addr, (_nand_boot_cache[addr]) ) ;
return (_nand_boot_cache[addr]) ;
}
//+-----------------------------------------------------------------------------
// Name:
// nand_boot_read()
//
// Declaration:
// t_result nand_boot_read(void) reentrant
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void nand_boot_write(uint8 addr, uint8 datum) reentrant
{
TRACE2(428, nand, 0, "nand_boot_write( addr:%d, datum:%02x )", addr, datum) ;
_nand_boot_cache[addr] = datum ;
}
//+-----------------------------------------------------------------------------
// Name:
// nand_boot_write_flush()
//
// Declaration:
// void nand_boot_write_flush(void) reentrant
//
// Purpose:
// flushes cached boot block data to the media
//
// Arguments:
//
// Return:
//
// Notes:
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
t_result nand_boot_write_flush() reentrant
{
TRACE0(429, nand, 0, "nand_boot_write_flush()") ;
lun_set_active(k_lun_nand); // g_active_lun=k_lun_nand ;
fmc_select_nand() ;
// erase boot block
g_addr_zone=0 ;
g_addr_wr_phy_blk=_media_data(boot_block);
g_addr_rd_phy_blk=_media_data(boot_block);
g_addr_page=_media_data(boot_page) ;
g_addr_segment=0;
_media_data(sector_buffer)=g_sector_buffer;
_media_erase_block();
if(g_active_media == k_ix_media_nand_int)
nand_int_select_chip(g_addr_segment);
else
nand_select_card() ;
nand_rd_va2pa();
nand_wr_va2pa();
// start erasing
_sm_wr_cmd_begin(k_sm_erase1);
_media_set_erase_addr() ;
_sm_set_wr_cmd(k_sm_erase2);
// create a "nvstore" sector while erase is going on
memcpy(g_sector_buffer, _nand_boot_cache, 256) ;
memset(g_sector_buffer+256, 0, 256) ;
memset(x_sm_redt_data, 0, 16);
if (sm_wait_rdy_with_timeout(k_sm_busy_erase_timeout))
{
TRACE0(430, nand, 0, "block erase failed.") ;
nand_cmd_reset_device();
return k_error ;
}
// write the sector to the media and bail
return _media_write_sector();
}
//+-----------------------------------------------------------------------------
// Name:
// nand_boot_seek()
//
// Declaration:
// void nand_boot_seek(void) reentrant
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
extern void sm_dbg_dump_redt_data() reentrant;
void nand_boot_seek() reentrant
{
uint16 i ;
TRACE0(431, nand, 0, "nand_boot_seek()");
// could try looping here, akin to the seek_cis in sm_media,
// but that will be a TBD which probably won't BD unless there
// are issues with certain chips having bad first blocks at
// some point.
g_addr_zone=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -