单龙芯3A3000-7A1000PMON研究学习-(27)撸起袖子干-再来一杯代码9-reset_ht_link

这篇博客详细解析了一段用于配置和检查HT总线的代码,包括复位、解除复位、等待链接重启成功、频率锁定和CRC错误检查等步骤。在复位和解除复位过程中,通过读取特定寄存器的值来判断操作是否成功,并通过CRC错误检查确保数据传输的准确性。整个流程涉及到硬件频率设置、连接状态判断和错误处理机制。
摘要由CSDN通过智能技术生成

1.回到start.S,继续

    move    a1, t2           //t2的值在691行赋值(当前793行)
    bal     reset_ht_link    //返回值不为0,表示有错误发生
    nop
    li      a0, 0xf3f3
    and     a0, a0, v0
    beqz    a0, 8f
    nop
    move    t8, v0
    TTYDBG("!!!LS3A-7A link error occur. Error status: ")
    move    a0, t8
    bal     hexserial
    nop

设置a1的值作为参数。

跳转到函数,执行

之后有对v0(保存了返回值)进行验证,为0表示没有出错,继续,不为0则函数执行出错。

2.重点关注reset_ht_link函数,这也是HT配置后的第二步。

// support 1 way and 2 way connection.  //支持1路和2路连接,我的硬件只有1路
// Because of the stupid bug, we have to keep all HT1 link reset together. //由于愚蠢的bug,必须要HT同步重启
// 
// reset multi-times seems useless when linkup fail.  //连接失败,重启多次看起来是没用的。

//input:
//a1: HT bus and hard freq mode related setting    //传入的参数,硬件频率设置
//[    0]: reconnect, 0: not reconnect; 1: reconnect

//output:
//v0: setup_link status:    //返回值,重启连接的状态
//0: success
//!0: fail

//register usage:
//t0: Node 0 LS3A HT1 cntl register base address    //3A基地址
//t1: Node 0 LS7A HT1 cntl register base address    //7A基地址
//t2: Node 1 LS3A HT1 cntl register base address    //3A基地址,不存在多个3A,不使用
//t3: Node 1 LS7A HT1 cntl register base address    //7A基地址,不存在多个7A,不使用
//t5, t6: tmp variable
//t8: store return value  //t8 保存返回值
//s1: store ra            //保存返回地址

注释也值得看一眼。 

2.1 准备工作,不多解释了

reset_ht_link:       //执行前面的config_ht_link后,马上就会跳转进来
					 //有一个参数a1 = ((HT1_HARD_FREQ_CFG << 12) | (HT1_HARD_FREQ_CFG << 8) | (HT1_GEN_CFG << 4) | (HT1_WIDTH_CFG << 1) | (HT1_RECONNECT << 0))
    move    s1, ra

reset_start:
    dli     t0, 0x90000efdfb000000    //注意650行的注释
    dli     t1, 0x90000efdfe000000

    dli     t2, 0x90001efdfb000000    //需要这个LS7A_2WAY_CONNECT ??   1100行用了这个
    dli     t3, 0x90001efdfe000000

    move    t8, $0     //清零,记录错误的位号,作返回值使用

    and     a0, a1, 0x1  /* a1参数的最低位是否为0,不为0则继续 */
    beqz    a0, 88f    /* 等于0,结束,函数返回,实际不等于0 */
    nop

a1 =  9<<12 | 9<<8 | 3<<4 | 1<<1 | 1<<0

2.2 3A端控制HT总线复位,7A应该是一起复位吧?

    TTYDBG("Reset Node 0 HT1-lo bus\r\n")    //开始执行
    lb      a0, 0x3e(t0)         //3A部分设置
    li      a1, 0x40
    or      a0, a0, a1           //[6] = 1 对应 --》 0x3c [22]位
    sb      a0, 0x3e(t0)         //总线复位 0--》1
    lw      a0, 0x3c(t0)           
    bal     hexserial
    nop
    TTYDBG("\r\n")

    //wait until HT link down
    TTYDBG("Wait HT bus down.")
    li      t5, 0x1f   //31
1:
    TTYDBG(">")
    addi    t5, t5, -1
    bnez    t5, 2f
    nop
    TTYDBG("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b=")
    li      t5, 0x1f
    //failed more than given time, set fail mark
    or      t8, t8, (0x1 << HT1_LINKDOWN_FAIL_OFFSET)
2:
    lw      a0, 0x44(t0)    /* 链路状态控制寄存器     0x20  表示初始化完成 */
    li      a1, 0x20
    and     a0, a0, a1    /* 结果为0,才表示复位成功 */
    bnez    a0, 1b
    nop

    TTYDBG("\r\n")          //信息打印
    lw      a0, 0x44(t0)
    bal     hexserial
    nop
    TTYDBG("\r\n")

两个寄存器,0x3e和0x44

 22位,由0-->1,总线复位。

 等待0x44,第[5]位为0,表示复位成功。

 

 2.3 3A端控制HT总线解除复位

    TTYDBG("\r\nDereset Node 0 HT1 bus\r\n")    //执行这里
    lb      a0, 0x3e(t0)
    li      a1, 0x40
    not     a1, a1				//0100 -》 ffff,ffbf
    and     a0, a0, a1         //[6]清零
    sb      a0, 0x3e(t0)       //总线解复位 1--》0
    lw      a0, 0x3c(t0)       //信息打印
    bal     hexserial
    nop
    TTYDBG("\r\n")

2.4 等待HTlink重启成功。

wait_ht3_link_up:
    //wait until HT link up
    TTYDBG("Wait HT bus up.")
    li      t5, 0xff
1:
    TTYDBG(">")
    addi    t5, t5, -1
    bnez    t5, 2f        //不为0,跳转到1088的2标识符位置  
    nop

    li      a1, 0x1
    b	    reset_start    //跳到前面去(662行),重启cpuHT总线
    nop

    TTYDBG("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b=")
    li      t5, 0x1f
    or      t8, t8, (0x1 << HT1_LINKUP_FAIL_OFFSET)
2:
    lw      a0, 0x44(t0)   
    li      a1, 0x20            //[5] 总线初始化是否完成
    and     a0, a0, a1
    beqz    a0, 1b      /* 结果为0表示未初始化成功 */
    nop                 //不等于0,向下继续执行

    TTYDBG("\r\n")          //信息打印
    lw      a0, 0x44(t0)
    bal     hexserial
    nop
    TTYDBG("\r\n")
    lw      a0, 0x68(t2)      //这个是否有意义?  NODE1不存在
    li      t5, 0x1000;
4:    
    addi    t5, t5, -1;
    bnez    t5, 4b;           //延时等待一下。
    nop
    lw	    a1, 0x68(t2);
    beq     a0, a1, 3f;     //往前跳,标号3,
    nop
//reset bus
    dli     t5, 0x90000ffdfb000000   //正常情况下,这里没有被执行。。。。。。。
    sb      zero, 0x3e(t5)    //又重启HT总线?? 
    sync
    li      a1, 0x40          //0-1 重启
    sb      a1, 0x3e(t5)
    sync
    sb      zero, 0x3e(t5)    //1-0 解重启????
    sync

    b      wait_ht3_link_up     //1071行,回跳?
    nop
3:

这段代码只有前半截有点用,后半截没有执行,直接跳到3f了。

就是查询0x44寄存器,第5位,为1,则表示重启成功了。

2.5 频率锁定,及CRC错误检查

#ifdef  CHECK_HT_PLL_LOCK    //需要执行
    //check HT PLL lock
    move    t5, $0
    lw      a0, LS3A_HT_PLL_CONF(t0)    //0x178
    srl     a0, a0, 3            //逻辑右移3位
    and     a0, a0, 0x1         //[3] 是保留位,没意义啊?????
    bnez    a0, 2f
    nop
    PRINTSTR("\r\nError: After reconfigure, 3A HT PLL not locked!!!\r\n")
    add     t5, t5, 1    //出错了才加1
2:
#ifdef  CHECK_7A_HT_PLL_LOCK   //需要执行
    lw      a0, 0x1F4(t1)
    srl     a0, a0, 3      //逻辑右移
    and     a0, a0, 0x1      // PLL锁定了吗?? 为1就是锁定了
    bnez    a0, 2f
    nop
    PRINTSTR("\r\nError: After reconfigure, 7A HT PLL not locked!!!\r\n")
    add     t5, t5, 1    //出错了才加1
2:
#endif
    bnez    t5, 2b    // t5 不为0 表示出错了
    nop
    TTYDBG("\r\nAfter reconnect, PLL check success.\r\n")
#endif

#if 1//Check if CRC error bit set and reset it
    TTYDBG("Checking Node 0 HT1 CRC error.")
    li      t5, MAX_HT_CRC_ERR_COUNT     //256
1:
    TTYDBG(">")
    addi    t5, t5, -1
    bnez    t5, 2f               //肯定跳转
    nop

    li      a1, 0x1
    b	    reset_start   /* 重来一次 */
    nop
    or      t8, t8, (0x1 << HT1_SB_CRC_FAIL_OFFSET)
    li      t5, MAX_HT_CRC_ERR_COUNT
2:
    lw      a0, 0x44(t1)      //7A桥片
    li      a1, 0x300         //地址0x45 的[1:0]两位
    and     a0, a0, a1        //地址0x44 的[9:8]两位 CRC error
    beqz    a0, 3f            //应该等于0
    nop
    or      t8, t8, (0x1 << HT1_SB_CRC_ERR_OFFSET)
    TTYDBG("\r\nCRC error found\r\n")
    lw      a0, 0x44(t1)
    bal     hexserial
    nop

    lw      a0, 0x44(t1)
    li      a1, 0xfffffcff
    and     a0, a0, a1
    sw      a0, 0x44(t1)
    b       1b
    nop
3:
    TTYDBG("\r\n")

3A端 0x178寄存器的第3位,频率已锁定。前面的文章已经提过了。

7A端 0x1f4寄存器的第3位,频率已锁定。前面的文章已经提过了。

检查3A及7A的CRC错误。

 

 

 2.6 函数返回。

3.总结

这一截代码不少,很多是循环等待。

从3A端控制HT总线复位,然后等待HT重启成功,检查频率是否锁定,以及CRC错误。

 理解的难度不大。建议多参考手册。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大智兄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值