Freescale QUICC 引擎固件上传¶
2007 Timur Tabi <timur at freescale.com>, Freescale Semiconductor
修订信息¶
2007 年 11 月 30 日:Rev 1.0 - 初始版本
I - 固件软件许可¶
每个固件文件都有自己的软件许可。有关特定许可的信息,请参阅与固件一起分发的许可文本。
II - 微码可用性¶
固件文件通过各种渠道分发。有些可在 http://opensource.freescale.com 上获得。对于其他固件文件,请联系您的 Freescale 代表或您的操作系统供应商。
III - 描述和术语¶
在本文档中,术语“微码”指的是构成实际 QE 微码的 32 位整数序列。
术语“固件”指的是包含微码以及其他数据的二进制 blob,这些数据
描述微码的用途
描述如何以及在何处上传微码
指定各种寄存器的值
包括供特定设备驱动程序使用的其他数据
固件文件是仅包含固件的二进制文件。
IV - 微码编程细节¶
QE 架构允许每个 RISC 处理器在 I-RAM 中仅存在一个微码。要替换任何当前微码,必须首先执行完整的 QE 重置(这将禁用微码)。
QE 微码使用以下过程上传
使用 IRAM.IADD 和 IRAM.IDATA 寄存器将微码放置到 I-RAM 中的特定位置。
CERCR.CIR 位设置为 0 或 1,具体取决于固件是否需要拆分 I-RAM。拆分 I-RAM 仅对具有带有多个 RISC 处理器的 QE 的 SOC 有意义,例如 8360。拆分 I-RAM 允许每个处理器运行不同的微码,从而有效地创建非对称多处理 (AMP) 系统。
TIBCR 陷阱寄存器加载微码中陷阱处理程序的地址。
RSP.ECCR 寄存器使用提供的值进行编程。
如有必要,需要虚拟陷阱和扩展模式数据的设备驱动程序将使用它们。
虚拟微码陷阱
这些虚拟陷阱是微码中的条件分支。这些是在 ROMcode 中引入的“软”配置,以便实现更高的灵活性并节省硬件陷阱。如果新功能被激活或在 RAM 包中修复了问题,则应激活它们。此数据结构向微码发出信号,指示哪些虚拟陷阱处于活动状态。
此结构包含 6 个字,应用程序应将其复制到一些特定的已定义位置。下表描述了该结构
---------------------------------------------------------------
| Offset in | | Destination Offset | Size of |
| array | Protocol | within PRAM | Operand |
--------------------------------------------------------------|
| 0 | Ethernet | 0xF8 | 4 bytes |
| | interworking | | |
---------------------------------------------------------------
| 4 | ATM | 0xF8 | 4 bytes |
| | interworking | | |
---------------------------------------------------------------
| 8 | PPP | 0xF8 | 4 bytes |
| | interworking | | |
---------------------------------------------------------------
| 12 | Ethernet RX | 0x22 | 1 byte |
| | Distributor Page | | |
---------------------------------------------------------------
| 16 | ATM Globtal | 0x28 | 1 byte |
| | Params Table | | |
---------------------------------------------------------------
| 20 | Insert Frame | 0xF8 | 4 bytes |
---------------------------------------------------------------
扩展模式
这是一个双字位数组(64 位),定义了对软件驱动程序有影响的特殊功能。每个位都有其自己的影响,并且具有与其关联的软件的特殊说明。下表描述了此结构
-----------------------------------------------------------------------
| Bit # | Name | Description |
-----------------------------------------------------------------------
| 0 | General | Indicates that prior to each host command |
| | push command | given by the application, the software must |
| | | assert a special host command (push command)|
| | | CECDR = 0x00800000. |
| | | CECR = 0x01c1000f. |
-----------------------------------------------------------------------
| 1 | UCC ATM | Indicates that after issuing ATM RX INIT |
| | RX INIT | command, the host must issue another special|
| | push command | command (push command) and immediately |
| | | following that re-issue the ATM RX INIT |
| | | command. (This makes the sequence of |
| | | initializing the ATM receiver a sequence of |
| | | three host commands) |
| | | CECDR = 0x00800000. |
| | | CECR = 0x01c1000f. |
-----------------------------------------------------------------------
| 2 | Add/remove | Indicates that following the specific host |
| | command | command: "Add/Remove entry in Hash Lookup |
| | validation | Table" used in Interworking setup, the user |
| | | must issue another command. |
| | | CECDR = 0xce000003. |
| | | CECR = 0x01c10f58. |
-----------------------------------------------------------------------
| 3 | General push | Indicates that the s/w has to initialize |
| | command | some pointers in the Ethernet thread pages |
| | | which are used when Header Compression is |
| | | activated. The full details of these |
| | | pointers is located in the software drivers.|
-----------------------------------------------------------------------
| 4 | General push | Indicates that after issuing Ethernet TX |
| | command | INIT command, user must issue this command |
| | | for each SNUM of Ethernet TX thread. |
| | | CECDR = 0x00800003. |
| | | CECR = 0x7'b{0}, 8'b{Enet TX thread SNUM}, |
| | | 1'b{1}, 12'b{0}, 4'b{1} |
-----------------------------------------------------------------------
| 5 - 31 | N/A | Reserved, set to zero. |
-----------------------------------------------------------------------
V - 固件结构布局¶
Freescale 的 QE 微码通常以头文件的形式提供。此头文件包含将微码二进制文件本身以及用于上传该微码的一些其他数据定义为宏。这些文件的格式不利于简单地包含到其他代码中。因此,需要更可移植的格式。本节定义了该格式。
与其分发头文件,不如将微码和相关数据嵌入到二进制 blob 中。此 blob 传递给 qe_upload_firmware() 函数,该函数解析 blob 并执行上传微码所需的一切。
所有整数都是大端序。有关最新的实现信息,请参阅函数 qe_upload_firmware() 的注释。
此结构支持版本控制,其中结构的版本嵌入到结构本身中。为确保向前和向后兼容性,所有版本的结构都必须在开头使用相同的“qe_header”结构。
- “header”(类型:struct qe_header)
“length”字段是整个结构的大小(以字节为单位),包括嵌入其中的所有微码以及 CRC(如果存在)。
“magic”字段是一个包含字母“Q”、“E”和“F”的三个字节的数组。这是一个标识符,指示此结构是一个 QE 固件结构。
“version”字段是一个单字节,指示此结构的版本。如果结构的布局需要更改以添加对其他类型微码的支持,则还应更改版本号。
“id”字段是一个以 null 结尾的字符串(适合打印),用于标识固件。
“count”字段指示“microcode”结构的数量。每个 RISC 处理器必须只有一个且只有一个“microcode”结构。因此,此字段也代表此 SOC 的 RISC 处理器的数量。
“soc”结构包含用于将微码与 SOC 本身匹配的 SOC 编号和修订号。通常,微码加载程序应使用 SOC 编号和修订号检查此结构中的数据,并且仅在匹配时才上传微码。但是,并非所有平台都进行此检查。
虽然不推荐,但您可以在 soc.model 字段中指定“0”以完全跳过匹配 SOC。
“model”字段是一个 16 位数字,与实际 SOC 匹配。“major”和“minor”字段分别是 SOC 的主要和次要修订号。
例如,要匹配 8323,修订版 1.0
soc.model = 8323
soc.major = 1
soc.minor = 0
“padding”对于结构对齐是必要的。此字段确保“extended_modes”字段在 64 位边界上对齐。
“extended_modes”是一个位字段,用于定义对设备驱动程序有影响的特殊功能。每个位都有其自己的影响,并且驱动程序具有与其关联的特殊说明。此字段存储在 QE 库中,并且可供调用 qe_get_firmware_info() 的任何驱动程序使用。
“vtraps”是一个包含每个虚拟陷阱的虚拟陷阱值的 8 个字的数组。与“extended_modes”一样,此字段存储在 QE 库中,并且可供调用 qe_get_firmware_info() 的任何驱动程序使用。
- “microcode”(类型:struct qe_microcode)
对于每个 RISC 处理器,都有一个“microcode”结构。第一个“microcode”结构用于第一个 RISC,依此类推。
“id”字段是一个适合打印的以 null 结尾的字符串,用于标识此特定微码。
“traps”是一个包含 16 个字的数组,其中包含 16 个陷阱中的每一个的硬件陷阱值。如果 trap[i] 为 0,则忽略此特定陷阱(即,不写入 TIBCR[i])。整个值按原样写入 TIBCR[i] 寄存器,因此请务必根据需要设置 EN 和 T_IBP 位。
“eccr”是要编程到 ECCR 寄存器中的值。
“iram_offset”是将微码写入 IRAM 的偏移量。
“count”是微码中 32 位字的数量。
“code_offset”是从此结构的开头开始可以找到微码本身的偏移量(以字节为单位)。第一个微码二进制文件应位于“microcode”数组之后。
“major”、“minor”和“revision”分别是微码的主要、次要和修订版本号。如果所有值为 0,则忽略这些字段。
“reserved”对于结构对齐是必要的。由于“microcode”是一个数组,因此 64 位的“extended_modes”字段需要在 64 位边界上对齐,并且只有在“microcode”的大小是 8 字节的倍数时才会发生这种情况。为了确保这一点,我们添加了“reserved”。
最后一个微码之后是 32 位 CRC。可以使用以下算法计算它
u32 crc32(const u8 *p, unsigned int len)
{
unsigned int i;
u32 crc = 0;
while (len--) {
crc ^= *p++;
for (i = 0; i < 8; i++)
crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
}
return crc;
}
VI - 用于创建固件文件的示例代码¶
可以在 http://opensource.freescale.com 上找到一个 Python 程序,该程序可以从 Freescale 通常分发的头文件创建固件二进制文件。