📄 altera_avalon_cfi_flash_table.c
字号:
/******************************************************************************
* *
* License Agreement *
* *
* Copyright (c) 2003-2004 Altera Corporation, San Jose, California, USA. *
* All rights reserved. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
* DEALINGS IN THE SOFTWARE. *
* *
* This agreement shall be governed in all respects by the laws of the State *
* of California and by the laws of the United States of America. *
* *
* alt_flash_cfi_table.c *
* *
* Functions for accessing the CFI Table *
* *
* Author PRR *
* *
******************************************************************************/
#include <errno.h>
#include <io.h>
#include "alt_types.h"
#include "altera_avalon_cfi_flash.h"
#include "altera_avalon_cfi_flash_amd_funcs.h"
#include "altera_avalon_cfi_flash_intel_funcs.h"
#define READ_ARRAY_MODE (alt_u8)0xFF
#define QUERY_MODE (alt_u8)0x98
#define QUERY_ADDR 0x10
#define PRIMARY_ADDR 0x15
#define INTERFACE_ADDR 0x28
#define BOTTOM_BOOT_DEVICE 2
#define TOP_BOOT_DEVICE 3
#define CFI_ALG_INTEL_STRATA 1
#define CFI_ALG_AMD 2
#define CFI_ALG_INTEL 3
/*
* Prototypes
*/
int alt_check_primary_table(alt_flash_cfi_dev* flash);
/*
* Read an 8 bit value from the CFI query table in flash
*/
alt_u8 alt_read_query_entry_8bit( alt_flash_cfi_dev* flash, int address)
{
return IORD_8DIRECT((alt_u8*)flash->dev.base_addr, address);
}
alt_u8 alt_read_query_entry_16bit( alt_flash_cfi_dev* flash, int address)
{
return (IORD_16DIRECT((alt_u8*)flash->dev.base_addr, address*2) & 0xff);
}
alt_u8 alt_read_query_entry_32bit( alt_flash_cfi_dev* flash, int address)
{
return (IORD_32DIRECT((alt_u8*)flash->dev.base_addr, address*4) & 0xff);
}
/*
* Write an 8 bit command to a flash
*/
void alt_write_flash_command_8bit_device_8bit_mode( void* base_addr, int offset, alt_u8 value)
{
IOWR_8DIRECT(base_addr, offset, value);
return;
}
void alt_write_flash_command_16bit_device_8bit_mode( void* base_addr, int offset, alt_u8 value)
{
if (offset % 2)
{
IOWR_8DIRECT(base_addr, offset*2, value);
}
else
{
IOWR_8DIRECT(base_addr, (offset*2)+1, value);
}
return;
}
void alt_write_flash_command_32bit_device_8bit_mode( void* base_addr, int offset, alt_u8 value)
{
IOWR_8DIRECT(base_addr, offset*4, value);
return;
}
void alt_write_flash_command_16bit_device_16bit_mode( void* base_addr, int offset, alt_u8 value)
{
IOWR_16DIRECT(base_addr, offset*2, ((alt_u16)value)& 0x00ff);
return;
}
void alt_write_flash_command_32bit_device_16bit_mode( void* base_addr, int offset, alt_u8 value)
{
IOWR_16DIRECT(base_addr, offset*4, ((alt_u16)value)& 0x00ff);
return;
}
void alt_write_flash_command_32bit_device_32bit_mode( void* base_addr, int offset, alt_u8 value)
{
IOWR_32DIRECT(base_addr, offset*4, ((alt_u32)value)& 0x000000ff);
return;
}
/*
* Write the value passed to the flash
*/
void alt_write_native_8bit( void* address, alt_u32 value)
{
IOWR_8DIRECT(address, 0, (alt_u8)(value&0xff));
return;
}
void alt_write_native_16bit( void* address, alt_u32 value)
{
IOWR_16DIRECT(address, 0, ((alt_u16)value)& 0xffff);
return;
}
void alt_write_native_32bit( void* address, alt_u32 value)
{
IOWR_32DIRECT(address, 0, value);
return;
}
/*
* alt_set_flash_width_func
*
* Setup the function pointers for writing a byte to the flash for the width
* of the device
*/
int alt_set_flash_width_func( alt_flash_cfi_dev* flash)
{
int ret_code = 0;
switch(flash->mode_width)
{
case 1:
{
flash->write_native = alt_write_native_8bit;
if (flash->device_width == 1)
{
flash->write_command = alt_write_flash_command_8bit_device_8bit_mode;
}
else if (flash->device_width == 2)
{
flash->write_command = alt_write_flash_command_16bit_device_8bit_mode;
}
else if (flash->device_width == 4)
{
flash->write_command = alt_write_flash_command_32bit_device_8bit_mode;
}
break;
}
case 2:
{
flash->write_native = alt_write_native_16bit;
if (flash->device_width == 2)
{
flash->write_command = alt_write_flash_command_16bit_device_16bit_mode;
}
else if (flash->device_width == 4)
{
flash->write_command = alt_write_flash_command_32bit_device_16bit_mode;
}
break;
}
case 4:
{
flash->write_native = alt_write_native_32bit;
flash->write_command = alt_write_flash_command_32bit_device_32bit_mode;
break;
}
default:
{
ret_code = -EACCES;
}
}
if (!ret_code)
{
switch(flash->device_width)
{
case 1:
{
flash->read_query = alt_read_query_entry_8bit;
break;
}
case 2:
{
flash->read_query = alt_read_query_entry_16bit;
break;
}
case 4:
{
flash->read_query = alt_read_query_entry_32bit;
break;
}
default:
{
ret_code = -EACCES;
}
}
}
return ret_code;
}
/*
* alt_set_flash_algorithm_func
*
* Setup the function pointers to the functions for this algorithm
*
*/
int alt_set_flash_algorithm_func( alt_flash_cfi_dev* flash)
{
int ret_code = 0;
switch(flash->algorithm)
{
case CFI_ALG_AMD:
{
flash->dev.erase_block = alt_erase_block_amd;
flash->dev.write_block = alt_program_amd;
break;
}
case CFI_ALG_INTEL:
case CFI_ALG_INTEL_STRATA:
{
flash->dev.erase_block = alt_erase_block_intel;
flash->dev.write_block = alt_program_intel;
break;
}
default:
{
ret_code = -EIO;
}
}
return ret_code;
}
/*
* read_16bit_query_entry
*
* Read a 16 bit entry from the CFI Query table
*/
static alt_u16 alt_read_16bit_query_entry(alt_flash_cfi_dev* flash, int address)
{
alt_u16 ret_code;
ret_code = (*flash->read_query)( flash, address);
ret_code |= (((int)(*flash->read_query)(flash, address+1)) << 8);
return ret_code;
}
/*
* read_cfi_table
*
* Read the CFI Table
*/
int alt_read_cfi_table(alt_flash_cfi_dev* flash)
{
int i,j;
int device_size;
int ret_code = 0;
int size = 0;
int swap;
int typical_timeout;
int max_timeout;
int offset = 0;
alt_u8 boot_mode;
/*
* Check that the Primary Vendor Specific table
* starts with the letters PRI
*/
ret_code = alt_check_primary_table(flash);
if (!ret_code)
{
flash->algorithm = (*flash->read_query)(flash, 0x13);
/*
* Let's read the write timeout values from the flash
*
*/
typical_timeout = (*flash->read_query)( flash, 0x1f);
max_timeout = (*flash->read_query)( flash, 0x23);
if ((typical_timeout == 0 ) || (max_timeout == 0))
{
flash->write_timeout = 1000; /* 1ms should be more than enough */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -