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.

[参考译文] AM5728:AM5728:DSB 指令导致管道停滞(错误-1323)

Guru**** 666710 points
Other Parts Discussed in Thread: AM5728
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1242302/am5728-am5728-dsb-instruction-lead-to-pipeline-stalled-error--1323

器件型号:AM5728

您好、专家!

我们在使用 AM5728时遇到了一个问题、某个版本的应用程序会在几个小时内使流水线停顿、经过我们自己的分析后、这与中断处理有很大关系。

以下是 SDK 提供的中断处理代码

IRQHandler:
        STMFD    r13!, {r0-r3, r12, r14}  @ Save context in IRQ stack
        FMRX      r0, FPEXC                @ Check Neon/VFP Enable bit
        UBFX      r0, r0, #30, #1          @ Bit 30 extract for check
        CMP       r0, #0                   @ Compare for zero
        BEQ       vfp_disabled_irq_save    @ VFP bit is not enabled
        MRS       r12, spsr                @ Copy spsr
        VMRS      r1, FPSCR                @ Copy fpscr
        VMRS      r2, FPEXC                @ Copy fpexc
        STMFD     r13!, {r1-r2, r12}       @ Save spsr, fpscr and fpexc
        VSTMDB    r13!, {d0-d7}            @ Save D0-D7 Neon/VFP registers
        VSTMDB    r13!, {d16-d31}          @ Save D16-D31 Neon/VFP registers
vfp_disabled_irq_save:
        LDR      r1, =addrIar             @ Load global variable addrIar address into r1
        LDR      r0, [r1]                 @ Load IAR address into r0
        LDR      r1, [r0]                 @ Get the Active IRQ
        MOV      r2, r1                   @ save active IRQ in r2
        AND      r1, r1, #IAR_INT_ID_MASK @ Mask the Active IRQ number
        SUB      r1, r1, #PPI_SGI_MASK    @ Get Shared pheriperal int number
        LDR      r3, =fnRAMVectors        @ Load the base of the vector table
        LDR      r0, =argArray            @ Load base of argument
        LDR      r0, [r0, r1, lsl #2]     @ Load argument
        STMFD    r13!, {r2}               @ Save active IRO in stack
        ADD      r14, pc, #0              @ Save return address in LR
        LDR      pc, [r3, r1, lsl #2]     @ Jump to the ISR
        LDMFD    r13!, {r2}               @ Get active IRO from stack
        LDR      r1, =addrEoi             @ Load global variable addrEoi address into r1
        LDR      r3, [r1]                 @ Acknowledge the current IRQ
        STR      r2, [r3]
        DMB                               @ Barrier to complete the data write
        FMRX      r0, FPEXC                @ Check Neon/VFP Enable bit
        UBFX      r0, r0, #30, #1          @ Bit 30 extract for check
        CMP       r0, #0                   @ Compare for zero
        BEQ       vfp_disabled_irq_restore @ VFP bit is not enabled
        VLDMIA    r13!, {d16-d31}          @ Restore D16-D31 Neon/VFP registers
        VLDMIA    r13!, {d0-d7}            @ Restore D0-D7 Neon/VFP registers
        LDMFD     r13!, {r1-r2, r12}       @ Get fpscr, fpexc and spsr
        MSR       spsr, r12                @ Restore spsr
        VMSR      fpscr, r1                @ Restore fpscr
        VMSR      fpexc, r2                @ Restore fpexc
vfp_disabled_irq_restore:
        LDMFD    r13!, {r0-r3, r12, r14}  @ Restore registers from IRQ stack
        SUBS     pc, r14, #0x4            @ Return to program before IRQ

在此基础上、我实现了在双线程之间来回切换的功能、以下代码是我自己修改过的中断处理汇编代码

hi_pCurrentTaskStructConst: .word hi_pCurrentTaskStruct

Hanix_IRQHandler:
        SUB       lr, lr, #4
        SRSDB     sp!, #MODE_SYS //保存状态寄存器的值到系统模式下的栈中
        MSR       cpsr_c, #MODE_SYS|0x80
        PUSH      {R0-R12, R14}
        FMRX      r0, FPEXC                @ Check Neon/VFP Enable bit
        UBFX      r0, r0, #30, #1          @ Bit 30 extract for check
        CMP       r0, #0                   @ Compare for zero
        BEQ       check_hanix_task          @ VFP bit is not enabled
        VMRS      r1, FPSCR                @ Copy fpscr
        VMRS      r2, FPEXC                @ Copy fpexc
        STMFD     r13!, {r1-r2}             @ Save fpscr and fpexc
        VSTMDB    r13!, {d0-d7}            @ Save D0-D7 Neon/VFP registers
        VSTMDB    r13!, {d16-d31}          @ Save D16-D31 Neon/VFP registers
check_hanix_task:
        LDR          R0, hi_pCurrentTaskStructConst
        LDR          R1, [R0]
        STR          SP, [R1]
vfp_disabled_irq_save:
        LDR      r1, =addrIar             @ Load global variable addrIar address into r1
        LDR      r0, [r1]                 @ Load IAR address into r0
        LDR      r1, [r0]                 @ Get the Active IRQ
        MOV      r2, r1                   @ save active IRQ in r2
        AND      r1, r1, #IAR_INT_ID_MASK @ Mask the Active IRQ number
        SUB      r1, r1, #PPI_SGI_MASK    @ Get Shared pheriperal int number
        LDR      r3, =fnRAMVectors        @ Load the base of the vector table
        LDR      r0, =argArray            @ Load base of argument
        LDR      r0, [r0, r1, lsl #2]     @ Load argument
        STMFD    r13!, {r2}               @ Save active IRO in stack
        ADD      r14, pc, #0              @ Save return address in LR
        LDR      pc, [r3, r1, lsl #2]     @ Jump to the ISR
        LDMFD    r13!, {r2}               @ Get active IRO from stack
        LDR      r1, =addrEoi             @ Load global variable addrEoi address into r1
        LDR      r3, [r1]                 @ Acknowledge the current IRQ
        STR      r2, [r3]
        DSB
        ISB

             /* Set the SP to point to the stack of the task being restored. */
        LDR          R0, hi_pCurrentTaskStructConst
        LDR          R1, [R0]
        LDR          SP, [R1]
check_neon:
        FMRX      r0, FPEXC                @ Check Neon/VFP Enable bit
        UBFX      r0, r0, #30, #1          @ Bit 30 extract for check
        CMP       r0, #0                   @ Compare for zero
        BEQ       vfp_disabled_irq_restore @ VFP bit is not enabled
        VLDMIA    r13!, {d16-d31}          @ Restore D16-D31 Neon/VFP registers
        VLDMIA    r13!, {d0-d7}            @ Restore D0-D7 Neon/VFP registers
        LDMFD     r13!, {r1-r2}       @ Get fpscr, fpexc and spsr
        VMSR      fpscr, r1                @ Restore fpscr
        VMSR      fpexc, r2                @ Restore fpexc
vfp_disabled_irq_restore:
        POP          {R0-R12, R14}
        RFEIA sp!

当 CPU 管线被暂停时、使用 xds200仿真器连接至 AM5728、并显示以下消息:

ERROR-1323@0x8024F858该地址的反汇编代码如下所示:

我猜应该是 CPU 正在执行 DSB 命令、这个命令还没有完成。我想问我修改的中断汇编代码是否有问题吗? 何时会发生这种情况?

此致、
哈恩克
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    此失速在 TI EVM 上是否可重现?  DSB 是停止的常见点、因为它等待未完成的事务完成、然后才允许流水线进行处理。  如果您的应用程序导致访问的某个地址空间崩溃、DSB 将是第一次遇到该不良影响的地方。

    在定制电路板上、如您所提到的拖延通常是由电路板级电压问题引起的。  第一个实验是对处理器 VDD_MPU/VDD_CORE/...的电压进行升压。 执行10%的降压、然后查看问题是否仍然存在。  这是定制电路板的问题、因此我询问您是否可以在 EVM 上预制失速。  可以触发 EVM 上的失速、但在时钟速度或时序违规方面往往发生失速。

    一种通用技术是在挂起时连接到隐藏的 DAP 目标、并检查并查看各种地址空间的运行状况。  您应该首先开始转储 DDR、看看它是否正常工作。  在说... 我看到过70%以上的失速情况是由 DDR 的崩溃或不稳定引起的。  通用的主板测试验证协议应该让您使用此来源(https://pyropus.ca./software/memtester/)在主板上运行一个较大的内存大小(>4MB)的内存表,度过周末。  我们在 BareMetal 和 Linux 级别运行此代码。  新的电路板经常无法正常工作、直到它们能够进入更大的系统为止、软件挂起只是浪费时间。

    如果 DDR 在压力测试中测试正常、则应确保作为应用一部分的外设的地址空间正常。   例如,如果您的 PCI 空间没有响应,那么只有一个时间问题,当某个驱动器访问该范围可能导致挂起。  驱动程序"写"可能会传递(因为写操作会触发并忘记传递的空间),并且只有稍后才会在某个 DSB 点挂起系统,从而强制缓冲区流入系统。

    以另一种方式说明... 由于 CCS 无法连接而导致的挂起源于调试器无法暂停 CPU。  在当前执行流水线中的所有指令都完成之后、CPU 才会停止。  如果事务未完成(由于 DDR 或某些其他从器件未响应)、则结果为挂起。  DSB 是查看挂起的常见位置、因为它无法清除管道并在完成之前停用所有未完成的访问。

    作为回顾、我首先要通过周末测试来确保 DDR 稳定可靠、memtester 在 A15上的测试超过4MB。  接下来、我会检查在您的用例中使用的 IO 从器件的地址空间、其中一个可能已折叠。   升高电压始终是新电路板上的一项很好的测试、因为电压"DNP"会导致 IO 从器件不能正确响应。

    此致、
    理查德·W·
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Richard  

    如果在使用 MSR 切断 ARM 模式指令之前和之后没有添加 DSB 存储器边界指令、是否有可能导致流水线停顿? 因为在 MSR 指令前后添加4个 NOP 指令后、没有出现流水线停滞

    此致、
    哈恩克
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Hannc:

    一些 MSR 指令要求使用 DSB、但不会发生一些问题。  "常用"选项处理 MMU 更新。  在发出 MSR 之前、需要 DSB 确保在更改特殊寄存器之前完成所有未完成的查找。  对于 MRS/MRS 操作、你填充了 NOP、应该在 ARM-Arch 手册和 Cortex-A-SPECIFIC-TRM 中查看是否有明确的要求。  您也可能只是移动了一些计时窗口、问题被屏蔽了。

    此致、
    理查德·W·