andeyqi 发表于 2024-9-2 21:54

【匠芯创D133CBS】--4.eFuse 读写使用测试

本帖最后由 andeyqi 于 2024-9-2 22:32 编辑

## eFuse 简介
>芯片电路通常是生产时物理固化的电路,生产完成之后不可改变。实际应用中有一些重要信息,需要固化在芯片之中, 使得上电即可读取使用,比如一些硬件的性能参数信息。但是这些参数可能与芯片的生产工艺、所用的材料等有关系, 无法在设计时确定,因此需要有一种存储技术,即可以固化信息,又能够在生产之后进行修改。

> eFuse 就是一种允许芯片上的电路在运行时进行修改的技术。它类似 EEPROM,属于一次性可编程存储器。eFuse ROM 里初始存储的内容都是 0,当需要修改某个比特位的值时,通过片上电压(通常为2.5V)提供一个持续一定时长的直流脉冲, 将代表该比特位的单根熔丝烧断,使得该比特位变为 1。熔丝被烧断之后,无法再恢复连接,因此这样的修改是一次性不可逆的。

> SID(Secure ID)模块主要用于读写eFuse,包括每颗芯片独立ID,每颗芯片量产校准, 以及安全管理用到的KEY,HASH码等信息,eFuse 的控制可以使用 SID 来进行读写访问,对应的block 图如下。



对应的特性如下,结合block 可以了解efuse 的功能。
- 4Kbit eFuse双备份实现2Kbit空间,软件读写按照4Kbit空间,以32bit为单位
- 2Kbit SRAM缓存,上电复位放开后自动读取eFuse值到SRAM
- 2Kbit空间,以32bit为单位,可烧写禁止读操作或写操作
- 提供CE安全密钥功能(SSK/HUK/PNK/PSK0/PSK1/PSK2/PSK3)
- 具备 BROM 特权保护功能,固件防回滚计数区域仅在 BROM 中可烧
- 支持通过烧写关闭JTAG功能,并可通过安全认证再打开JTAG

从上述信息可以知道芯片内集成了4K bit即512byte fuse memory 空间,访问读写按照32bit 为单位即128 word 的操作空间,上述的128 word 按照双分区的模式被加载到SRAM空间,SRAM 空间大小为64 word,对应eFuse 的 和SRAM 的映射关系如下:


对应的fuse 64 word 的空间byte0~0xff 其中0x00~0xbf 芯片设计时已经定义好了使用方法,留给用户自定义使用的空间为0xc0~0xff 64 byte 的空间(word 48~63),我们本次实验也基于这个空间进行测试efuse 功能。


## eFuse 读写验证
env环境下 menuconfig 使能SDI 驱动测试接口


开启上述配置后系统年内汇集成efuse 驱动及efuse 读取写入测试接口,对应命令使用说明如下:
```
aic /> efuse help
efuse command usage:
efuse help                     : Get this help.
efuse dump   offset len      : Dump data from eFuse offset.
efuse read   addr offset len : Read eFuse data to RAM addr.
efuse write    addr offset len : Write data to eFuse from RAM addr.
efuse writehex offset data   : Write data to eFuse from input hex string.
efuse writestr offset data   : Write data to eFuse from input string.
```

我们先使用 efuse dump 命令dump 2Kbit efuse 数据
```c
aic /> efusedump 0 0x100
0x00000000: 00 00 00 0F 00 00 00 00 00 00 00 0F 00 00 00 00   |................|
0x00000010: C8 81 C6 B8 2C 3E 20 20 03 0C 03 45 02 00 30 04   |....,>...E..0.|
0x00000020: 00 00 00 00 21 00 00 00 0D 02 00 3F A8 65 5A 00   |....!......?.eZ.|
0x00000030: 00 00 00 00 D6 17 7D 2E 00 00 00 00 00 00 00 00   |......}.........|
0x00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   |................|
0x00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   |................|
0x00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   |................|
0x00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   |................|
0x00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   |................|
0x00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   |................|
0x000000a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   |................|
0x000000b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   |................|
0x000000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   |................|
0x000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   |................|
0x000000e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   |................|
0x000000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   |................|
```

从上面的efuse 功能介绍可知,SID 模块在启动后会将efuse 的数据加载到内部的SRAM 中,对应的寄存器为efuse_data


我们来添加命令来dump 该段寄存器的数值和fuse 的数据比较看是否一致,对应的寄存器地址为sid_base + offfset = 0x19010000 + 0x200 = 0x19010200
```c
aic /> hexdump10x19010200   256   1
         00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000:00 00 00 0F 00 00 00 00 00 00 00 0F 00 00 00 00      ................
00000010:C8 81 C6 B8 2C 3E 20 20 03 0C 03 45 02 00 30 04      ....,>...E..0.
00000020:00 00 00 00 21 00 00 00 0D 02 00 3F A8 65 5A 00      ....!......?.eZ.
00000030:00 00 00 00 D6 17 7D 2E 00 00 00 00 00 00 00 00      ......}.........
00000040:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00      ................
00000050:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00      ................
00000060:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00      ................
00000070:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00      ................
00000080:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00      ................
00000090:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00      ................
000000a0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00      ................
000000b0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00      ................
000000c0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00      ................
000000d0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00      ................
000000e0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00      ................
000000f0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00      ................
```
我们compare 下这两组数据,比较结果也是一致的符合预期值。


efuse 的读写控制流程如下:
写流程:
> 1.检查eFuse控制寄存器(EFUSE_CTL)状态位(EFUSE_WRITE_START/EFUSE_READ_START/EFUSE_AUTO_STATUS),若为非空闲则等待,若都为空闲则继续步骤2;
> 2.配置要烧写eFuse地址到eFuse地址寄存器(EFUSE_ADDR);
3.配置要烧写eFuse数据到eFuse写数据寄存器(EFUSE_WDATA);
4.配置eFuse控制寄存器(EFUSE_CTL)启动烧写流程,EFUSE_WRITE_START和EFUSE_OP_CODE都需要配置;
5.等待EFUSE_WRITE_START自动清零,硬件自动关闭LDO。

读取流程:
> 1.检查eFuse控制寄存器(EFUSE_CTL)状态位(EFUSE_WRITE_START/EFUSE_READ_START/EFUSE_AUTO_STATUS),若为非空闲则等待,若都为空闲则继续步骤2;
2.配置要读取eFuse地址到eFuse地址寄存器(EFUSE_ADDR);
3.配置eFuse控制寄存器(EFUSE_CTL)启动读取流程,EFUSE_READ_START和EFUSE_OP_CODE都需要配置;
4.等待EFUSE_READ_START自动清零,读取eFuse读数据寄存器(EFUSE_RDATA)获得eFuse的值。

我们对用户自定义的0xc0~0xff 区间的0xc0 地址空间写入01测试 写入功能,然后dump数据发现0x01 已经被写入

写入01后我们再次写入00 发现dump 回来的数据还是1,因为fuse 是只能写入一次的。

对写入的数据还是需要谨慎的,一旦被写入后是无法再次被修改的。

从以下efuse 的初始化流程说明可知,修改完fuse 后SID的SRAM 的数据和efuse 的数据是不一致的,触发读取操作后会更先SRAM数据
> 每次系统上电复位后,SID会自动读取所有eFuse值到SRAM,软件只需要读取对应地址的值即可。 注意第一次烧写后,SRAM值不会自动更新,此时可通过软件读操作将对应地址的值读到寄存器。

我们对c0 地址更新为010310 ,然后读取SRAM 数据和efuse 数据进行比较查看是否是不一致的,对0xc0 更新后,读取SRAM数据发现并没有更新为写入数据跟上述说明一致。再此基础上我们使用dump 命令读取efuse 数据在dump SRAM数据,理论上此时0xc0会被更新为03,按照此流程进行验证运行结果如下,和上述说明保持一致。



Jacktang 发表于 2024-9-3 07:48

<p>&nbsp;BROM 特权保护功能,固件防回滚计数区域仅在 BROM 中可烧,这个功能可以有</p>
页: [1]
查看完整版本: 【匠芯创D133CBS】--4.eFuse 读写使用测试