您好!
根据 SYS/BIOS 6.76.01.12的发行说明、 SYS/BIOS 6.76.00.08以来修复的缺陷之一是 JIRA ID 为 SysBIOS-1052的"C28调度程序对齐问题":
有人能向我提供有关此问题的更多详细信息吗?
谢谢!
罗伯特·斯特劳德
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好!
根据 SYS/BIOS 6.76.01.12的发行说明、 SYS/BIOS 6.76.00.08以来修复的缺陷之一是 JIRA ID 为 SysBIOS-1052的"C28调度程序对齐问题":
有人能向我提供有关此问题的更多详细信息吗?
谢谢!
罗伯特·斯特劳德
此问题位于/family/c28/Hwi_disp_asm.s28.中 有一些类似这样的代码:
movz ar0,@sp .if (.TMS320C2800_FPU32 == 1) subb xar0, #13 ; point to IER on stack .else subb xar0, #11 ; point to IER on stack .endif ; Note: if we change order of items ; pushed on stack, double check ; the value here. mov *xar0, ier ; IER value may have changed by ; the user till this time ; this need to be corrected in ; the stack where value of IER ; have been saved as hardware ; context and will be restored ; as a part of iret instruction
下面是错误的说明:
它正在将当前 IER 寄存器值(可能在 HWI 中修改)写入相对于当前栈指针的位置、其中 IER 由硬件作为 IRET 序列的一部分恢复。 因此、目的是在中断结束时保留当前 IER 值。
这就是问题所在。 写入栈的32位寄存器对在偶数地址对齐、而栈指针本身的对齐不变(SP 首先无条件递增、以避免覆盖)。 TMS320C28x CPU 和指令集"手册的"可屏蔽中断的3.4标准操作"部分介绍了确切序列。 它的工作方式、当中断被触发时、根据 SP 寄存器的初始(奇数或偶数)值、最终 SP 值和 IER 恢复位置之间的偏移量可能是10或11个字(FPU 为12或13) 上述代码的执行速度。 代码假定固定值为11 (使用 FPU 的情况下为13)、使用最初奇数对齐的 SP 触发中断时、该值错误。 因此、使用 IER 值覆盖数据页(DP)寄存器。 这会导致在中断后运行的代码从错误的存储器位置读取或写入到错误的存储器位置。
惠特尼
惠特尼、您好!
感谢您的快速响应、这非常有用。
令人困惑的是、dispatchMain 开头描述 中断上下文切换后堆栈内容的注释错误:
; At this point, the following registers have already been saved: ; ** Automatic interrupt context save (see SPRU513C) ** ; ST0, T, AL, AH, PL, PH, AR0, AR1, DP, ST1, DBGSTAT, PC, and IER.
订单实际上是
;st0、T、AL、AH、 PL、PH、AR0、AR1 ST1、DP、IER ,DBGSTAT,PC
这使错误描述更有意义,因为 DP 与 IER 相邻。
再次感谢。
罗伯特
您好!
作为对我原来的问题的跟进、这似乎是一个令人讨厌的错误、但在实践中有多少问题呢?
如果出于某些原因、栈指针几乎始终与 偶数地址对齐(例如、因为代码是用 C 编写的)、则当栈与奇数地址对齐时、发生硬件中断可能很不常见。
我认为 C 编译器要求在调用函数之前在偶数地址边界上对齐栈- Hwi_Dispatch 逻辑可以确保这一点-但也足以在执行 C 代码时确保栈始终在偶数边界上、 或者堆栈是否可以位于奇数地址边界上?
谢谢。
罗伯特
是的、这就是我对为什么没能早点发现的理解。 故障记录包含以下附加信息:
我们不能始终看到这一点的原因可能与编译器使用和对齐函数内栈帧的方式有关、因此栈在大多数时间都是偶数对齐的。 在_disable_interrupts ()内在函数中、ST1的16位值会放在使 SP ODD 的栈上、如果在其实际被禁用之前立即被中断取代、则 DP 现在是错误的。
对于参考_disable_interrupts、相当于以下汇编代码:
PUSH ST1 SETC INTM, DBGM POP reg16
惠特尼