CFI定义了符合CFI规则设备的基本Query接口,包括已知或待拟定的flash Read/Write/Program/Erase控制接口。Query接口以结构体形式定义与flash设备相关的关键参数,但是CFI不会对单个flash设备厂家指定详细的指令集、状态轮询模式以及软件算法。
1.操作概要
设备接收到Query command code后进入Query模式,允许对CFI Query数据结构进行访问。CFI Query data structure包含16bit指令集、Control Interface ID code(控制接口)、通用flash内存参数和算法指定的数据域。
上述信息主要用于给指定的flash提供读写、擦除等操作。
2. 硬件接口
2.1 Query command interface
CFI Query结构的访问与NVM现有的”ID Mode”或”JEDEC ID”访问类似,但是使用不同的指令代码。Query 访问指令为98h,JEDEC ID 模式访问为90h。
上电后,假设NvM处于制度模式,Query 结构的内容必须能够在单个系统写周期的特定地址位置读取:1)98h被写入到设备地址空间内55h的地址位置(以最大设备总线宽度),2)设备处于任何有效的读状态,如“读阵列”或“读ID数据”。其他设备状态可能存在于一长串命令或数据输入中;在编写98h Query命令代码产生有效的Query数据结构输出之前,必须先完成或终止这些序列。
设备驱动程序应该始终在地址总线上提供55h,在数据总线上提供98h以进入查询模式;或者Flash设备可以选择忽略地址总线并进入查询模式,如果98h只在数据总线上看到。
Flash供应商必须为其他模式访问定义其他命令序列。

2.2 Query structure output
Query 数据只在数据输出(D7 - D0)上显示。
因此,对于字节宽(x8)设备,Query结构的前两个字节,即ASCII中的“Q”和“R”,出现在设备地址10h和11h处,这与绝对字节地址相同。相同逻辑应用到x16、x32设备。下表Query数据输出的示例:
3 Query Structure
3.1 Query结构总览
|   Offset  |   Section名称  |   描述  | 
|   00h  |   Reserved  |   指令算法信息  | 
|   10h  |   CFI Query Identification  |   命令集ID和算法数据偏移量  | 
|   1Bh  |   System Interface Information  |   设备时间、电压信息  | 
|   27h  |   Device Geomerty Definition  |   Flash设备的layout  | 
|   P  |   主算法的特定扩展  |   主算法的特定扩展  | 
|   A  |   备选算法的特定扩展  |   备选算法的特定扩展  | 
3.2 CFI Query Identification
|   Offset  |   Length (bytes)  |   Description  | 
|   10h  |   03h  |   三字节的“QRY”查询结构标记  | 
|   13h  |   02h  |   两字节的主算法命令集和控制接口ID码  | 
|   15h  |   02h Value=P  |   主算法扩展表的地址P  | 
|   17h  |   02h  |   备选算法命令集和控制接口ID码  | 
|   19h  |   02h Value=A  |   备选算法扩展表的地址A  | 
3.3 System Interface Information
|   Offset  |   Length(Bytes)  |   含义  |   举例(Intel 28 F800BVT)  | 
|   10H  |   03H  |   查询ASCII字符串“QRY”  |   10:0051H ‘Q’ 11:0052H ‘R’ 12:0059H ‘Y’  | 
|   13H  |   02H  |   制造商命令集和控制接口识别码ID  |   13:0003H 14:0000H  | 
|   1BH  |   01H  |   逻辑供电Vcc最小电压。位7-4:BCD伏 位3-0:BCD100毫伏  |   1B:0030H(3伏)  | 
|   1CH  |   01H  |   逻辑供电Vcc最大电压。位7-4:BCD伏 位3-0:BCD100毫伏  |   1C:0055H(5.5伏)  | 
|   1DH  |   01H  |   编程/擦除供电Vpp最小电压。位7-4:HEX伏 位3-0:BCD100毫伏  |   1D:0045H(4.5伏)  | 
|   1EH  |   01H  |   编程/擦除供电Vpp最大电压。位7-4:HEX伏 位3-0:BCD100毫伏  |   1E:00C6H(12.6伏)  | 
|   1FH  |   01H  |   典型单字节/字写周期定时时间,2Nus  |   1F:0003H(3.8us)  | 
|   21H  |   01H  |   典型单块擦除定时时间,2Nms  |   21:000AH(1.024s)  | 
|   22H  |   01H  |   典型整片擦除定时时间,2Nms  |   22:0000H(不支持)  | 
|   23H  |   01H  |   单字节/字写周期最大定时时间,2Nx典型单字节/字写周期定时时间  |   23:0004H(24x8us)  | 
|   25H  |   01H  |   单块擦除最大定时时间,2Nx典型单块擦除定时时间  |   25:0004H(24x1.024s)  | 
|   26H  |   01H  |   整片擦除最大定时时间,2Nx典型整片擦除定时时间  |   26:0000H(不支持)  | 
3.4 Device geometry definition
|   Offset  |   Length(Bytes)  |   含义  |   举例(Intel 28 F800BVT)  | 
|   28H  |   02H  |   Flash器件接口识别码ID  |   28:0002H 29:0000H  | 
|   2CH  |   01H  |   器件可擦除块区域个数。Bit7-0=可擦除块个数  |   2C:0004H 4个擦除块  | 
|   2DH  |   04H  |   擦除块信息域1。Bit31-16=z(高两字节表示擦除块大小对于256字节的倍数,0表示128B)。Bit15-0=y(低两字节+1表示擦除块的个数,0表示没有块)  |   2D:0006H 2E:0000H 7个擦除块 2F:0000H 30:0002H 256x200H=128K字节  | 
|   31H  |   04H  |   擦除块信息域2。  |   31:0000H 32:0000H 33:0080H 34:0001H  | 
|   35H  |   04H  |   擦除块信息域3。  |   35:0001H 36:0000H 37:0020H 38:0001H  | 
|   39H  |   04H  |   擦除块信息域4。  |   39:0000H 3A:0000H 3B:0040H 3C:0000H  | 
3.5 主算法的特定扩展
如下表所示:
|   Offset  |   Length (bytes)  |   Description  | 
|   Ph  |   03h  |   主算法扩展查询表标记字符串“PRI”  | 
|   (P+3)h  |   01h  |   主版本号  | 
|   (P+4)h  |   01h  |   次版本号  | 
|   (P+5)h  |   Variable  |   主算法扩展查询结构内容  | 
3.6 备用算法的特定扩展
如下表所示
|   Offset  |   Length (bytes)  |   Description  | 
|   Ah  |   03h  |   备用算法扩展查询表标记字符串“ALT”  | 
|   (A+3)h  |   01h  |   主版本号  | 
|   (A+4)h  |   01h  |   次版本号  | 
|   (A+5)h  |   Variable  |   备用算法扩展查询结构内容  | 
4. CFI代码示例
Std_ReturnType Fls_HwCfiQuery(uint32 CfiBaseAddr,uint8 CfiCmd, _CfiValueType *CfiValueBuf)
{
    Std_ReturnType retVal = E_NOT_OK;
    uint16 i=0;
    /* #10 Handle CFI query cmd */
    Fls_lCmdProcessing((_FLS_CFI_BASE_ADDRESS + CfiBaseAddr),CfiCmd);
    /* #20  Check that the CFI interface is operable */
    if ((Fls_lCfiReadValue(_FLS_CFI_BASE_ADDRESS + _FLS_CFI_QUERY_OFFSET_ONE)   != 0x51U)
      ||(Fls_lCfiReadValue(_FLS_CFI_BASE_ADDRESS + _FLS_CFI_QUERY_OFFSET_TWO)   != 0x52U)
      ||(Fls_lCfiReadValue(_FLS_CFI_BASE_ADDRESS + _FLS_CFI_QUERY_OFFSET_THREE) != 0x59U))
    {
        retVal = E_NOT_OK;
    }
    else
    {
         /* #30: Read the required CFI Info */
        for(i = 0; i < 256; i++)
        {
            CfiValueBuf[i] = Fls_lCfiReadValue(_FLS_CFI_BASE_ADDRESS + (uint32)i);
        }
        retVal = E_OK;
    }
    return retVal; 


















