⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flashspecificgomad.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的flash文件系统的程序源码。
💻 C
字号:
/*
 *  COPYRIGHT (c) 1995,2000 TriMedia Technologies Inc.
 *
 *   +-----------------------------------------------------------------+
 *   | THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED |
 *   | AND COPIED IN ACCORDANCE WITH THE TERMS AND CONDITIONS OF SUCH  |
 *   | A LICENSE AND WITH THE INCLUSION OF THE THIS COPY RIGHT NOTICE. |
 *   | THIS SOFTWARE OR ANY OTHER COPIES OF THIS SOFTWARE MAY NOT BE   |
 *   | PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. THE   |
 *   | OWNERSHIP AND TITLE OF THIS SOFTWARE IS NOT TRANSFERRED.        |
 *   +-----------------------------------------------------------------+
 *
 *  Module name              : FlashSpecificGomad.c    1.10
 *
 *  Title                    : Low level flash manipulation routines
 *
 *  Last update              : 11:38:39 - 00/06/19
 *
 *  Reviewed                 : 
 *
 *  Revision history         : 
 *
 *  Description              : Implementation of flash access functions
 *                             for Philips GOMAD board (containing Am29f016B).
 *
 */

/*------------------------------- Includes -----------------------------------*/

#include <stdio.h>
#include <tmlib/tmtypes.h>
#include <tmlib/tmFlash.h>
#include <tm1/mmio.h>
#include <tm1/tmPCI.h>

/*---------------------------- Physical flash --------------------------------*/

#define  PCI_VENDOR_ID_SOUTH       0x056510AD

#define  PHY_FLASH_BASE_ADDRESS   ((Address)0xFF800000)

#define  PHY_BANK_SIZE             0x00600000  /* there seems to be a Gomad problem */
#define  PHY_FLASH_SIZE            0x00200000        /* with high flash banks, so   */
#define  PHY_BLOCK_SIZE            0x00010000        /* disable them                */
#define  NROF_PHY_BANKS                     2

#define  MEM_CTL_REG	        ((VAddress)0x110)
#define  FLASH_BANK_SELECT               0x08

#define  RETRY_COUNT                       20

#define LROUND_DOWN(v,bs)  (((UInt) (v)/(UInt) (bs))*(UInt) (bs))


typedef volatile Byte   *VAddress;
typedef volatile UInt32  VUInt32;



/*----------------------------- Logical flash --------------------------------*/


#define LOG_BLOCK_SIZE          PHY_BLOCK_SIZE
#define BLOCK_CLUSTER_FACTOR   (LOG_BLOCK_SIZE / PHY_BLOCK_SIZE)


Int     SZOF_FLASH_BLOCK   = LOG_BLOCK_SIZE;
Int     NROF_FLASH_BLOCKS  = (NROF_PHY_BANKS * PHY_BANK_SIZE) / LOG_BLOCK_SIZE;



              /* ------- . ------- */



UInt32 
FLASH_read(Pointer address)
{
	UInt32   log_address   = (UInt32) address;

	UInt32   bank_number   = log_address / PHY_BANK_SIZE;
	UInt32   lf_address    = log_address % PHY_BANK_SIZE;

	VUInt32 *phy_address   = (UInt32*)(PHY_FLASH_BASE_ADDRESS + lf_address);

       *MEM_CTL_REG = (FLASH_BANK_SELECT | bank_number);

        return *phy_address;
}

        /* ------- . ------- */

/* this commented out version of FLASH_block_read is more efficient,
   speed wise, than the version below. However this version is too
   large, codewise, for Flash booting. The uncommented out version
   should be used for flash booting. For normal applications a user
   can use the commented out version of FLASH_block_read as it is
   more efficient speed wise */

/* version of FLASH_block_read can be used for normal applications */
/*void FLASH_block_read( Pointer address, Pointer image, Int nrof_words )
{
        UInt32      log_address   = (UInt32) address;

	UInt32      bank_number   = log_address / PHY_BANK_SIZE;
	UInt32      lf_address    = log_address % PHY_BANK_SIZE;

	UInt32     *phy_address   = (UInt32*)(PHY_FLASH_BASE_ADDRESS + lf_address);
        Int32      *i             = ((Int32*)image);

       *MEM_CTL_REG = (FLASH_BANK_SELECT | bank_number);

        while (nrof_words--) {
            *(i++) = *(phy_address++);
        } 
}
*/

/* version of FLASH_block_read to be used for Flash File system booting */
void FLASH_block_read( Pointer flash, Pointer image, Int nrof_words )
{
    Int32 *f = ((Int32*)flash);
    Int32 *i = ((Int32*)image);

    while (nrof_words--) {
        *(i++) = FLASH_read( f++ );
    } 
}

              /* ------- . ------- */



	static void 
	flash_byte_write(VAddress phy_address, UInt32 lf_address, Byte data)
	{
		Int      i;
		Byte     old_data      = *phy_address;
		Byte     new_data      = old_data & data;

		VAddress phy_flashbase = (VAddress)(PHY_FLASH_BASE_ADDRESS + LROUND_DOWN(lf_address, PHY_FLASH_SIZE));
	
		if (new_data == old_data) { return; }

		for (i = 0; i < RETRY_COUNT; i++) {
			phy_flashbase[0x555] = 0xAA;
			phy_flashbase[0x2AA] = 0x55;
			phy_flashbase[0x555] = 0xA0;
	
			*phy_address = data;
	
			while ((*phy_address ^ *phy_address) & 0x40) {}
	
			if (*phy_address == data) {
				return;
			}
		}
	}


Bool 
FLASH_write(Pointer address, UInt32 data)
{
	Int i;

	UInt32      log_address   = (UInt32) address;

	UInt32      bank_number   = log_address / PHY_BANK_SIZE;
	UInt32      lf_address    = log_address % PHY_BANK_SIZE;

	VAddress    phy_address   = (VAddress)(PHY_FLASH_BASE_ADDRESS + lf_address);

        UInt32      data1         = data;

       *MEM_CTL_REG = (FLASH_BANK_SELECT | bank_number);

#ifdef __BIG_ENDIAN__
        for (i=3; i >= 0; i--) {
#else
        for (i=0; i <  4; i++) {
#endif
            flash_byte_write( phy_address+i, lf_address, (Byte)data1 );
            data1 >>= 8;
        }

        return *((VUInt32*) phy_address) == data;
}

Bool
FLASH_block_write( Pointer flash, Pointer image, Int nrof_words )
{
    Int32 *f = ((Int32*)flash) + nrof_words;
    Int32 *i = ((Int32*)image) + nrof_words;

    Bool result;

    do {
        result = FLASH_write( --f, *(--i) );
    } while ((Pointer)f != flash && result);

    return result;
}




              /* ------- . ------- */



	static Bool 
	flash_block_erase(UInt block_index)
	{
		UInt32      log_blockbase = block_index * PHY_BLOCK_SIZE;
		UInt32      log_flashbase = LROUND_DOWN(log_blockbase, PHY_FLASH_SIZE);
	
		VAddress    phy_blockbase = (VAddress)PHY_FLASH_BASE_ADDRESS + (log_blockbase % PHY_BANK_SIZE);
		VAddress    phy_flashbase = (VAddress)PHY_FLASH_BASE_ADDRESS + (log_flashbase % PHY_BANK_SIZE);
	
		UInt32      bank_number   = log_blockbase / PHY_BANK_SIZE;
	
	
		*MEM_CTL_REG = (FLASH_BANK_SELECT | bank_number);
	
	
		*((phy_flashbase + 0x555)) = 0xAA;
		*((phy_flashbase + 0x2AA)) = 0x55;
		*((phy_flashbase + 0x555)) = 0x80;
		*((phy_flashbase + 0x555)) = 0xAA;
		*((phy_flashbase + 0x2AA)) = 0x55;
	
		*(phy_blockbase) = 0x30;
	
		while (*phy_blockbase != 0xff) {};
	
		return True;
	}


Bool
FLASH_block_erase(UInt ab, Bool check_if_necessary)
{
	Int i;

	if (check_if_necessary) {
		UInt       *pt        = (Pointer) (ab * SZOF_FLASH_BLOCK);
		Bool        necessary = False;

		for (i = 0; i < (SZOF_FLASH_BLOCK / sizeof (UInt)); i++) {
			if (FLASH_read(pt++) != 0xffffffff) {
				necessary = True;
				break;
			}
		}

		if (!necessary) {
			return True;
		}
	}

        for ( i= 0; i < BLOCK_CLUSTER_FACTOR; i++ ) {
            flash_block_erase( ab * BLOCK_CLUSTER_FACTOR + i );
        }

        return True;
}




/*---------------------------- Initialization --------------------------------*/




Bool 
FLASH_init()
{
  UInt32 south_addr;

  return !pciAddressFind(PCI_VENDOR_ID_SOUTH, &south_addr)
       & !pciConfigWrite((south_addr | 0x4c), 0x00041300);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -