ATF bl1 ufshc_dme_get/set处理流程分析

以海思hikey960为例来介绍,简单介绍在ATF BL1阶段的初始化处理。

UFS术语缩略词

UTP:UFS Transport Protocol
DME:Device Management Entity
UCS:UFS Command Set
UIC:UFS Interconnect
UTRD:UTP Transfer Request Descriptor
UPIU:UFS Protocol Information Unit

1 ATF的下载链接

https://github.com/ARM-software/arm-trusted-firmware

可以通过下面的命令来下载ATF的代码,或者通过打包下载的方式也可以。

git clone git@github.com:ARM-software/arm-trusted-firmware.git

2 ATF BL1 ufshc_dme_get/set流程

  • 设置ufs dme get/set的cmd参数
  • ufshc_send_uic_cmd函数中首先等到UIC READY,然后配置UFS CMD ARG寄存器以及UIC CMD寄存器。

在这里插入图片描述

3 ufs总体架构图

3.1 UFS Top Level Architecture

在这里插入图片描述

3.2 UFS System Model

在这里插入图片描述

4 ufshc_dme_get/set函数接口详细分析

4.1 ufshc_dme_get

  • cmd.op = DME_GET;
  • ufshc_send_uic_cmd(base,&cmd);
int ufshc_dme_get(unsigned int attr, unsigned int idx, unsigned int *val)
{
        uintptr_t base;
        int result, retries;
        uic_cmd_t cmd;

        assert(ufs_params.reg_base != 0);

        if (val == NULL)
                return -EINVAL;

        base = ufs_params.reg_base;
        cmd.arg1 = (attr << 16) | GEN_SELECTOR_IDX(idx);
        cmd.arg2 = 0;
        cmd.arg3 = 0;
        cmd.op = DME_GET;

        for (retries = 0; retries < UFS_UIC_COMMAND_RETRIES; ++retries) {
                result = ufshc_send_uic_cmd(base, &cmd);
                if (result == 0)
                        break;
                /* -EIO requires UFS re-init */
                if (result == -EIO) {
                        return result;
                }
        }
        if (retries >= UFS_UIC_COMMAND_RETRIES)
                return -EIO;

        *val = mmio_read_32(base + UCMDARG3);
        return 0;
}

4.2 ufshc_dme_set

  • cmd.op = DME_SET;
  • ufshc_send_uic_cmd(base,&cmd);
int ufshc_dme_set(unsigned int attr, unsigned int val)
{
        uintptr_t base;
        int result, retries;
        uic_cmd_t cmd;

        assert((ufs_params.reg_base != 0));

        base = ufs_params.reg_base;
        cmd.arg1 = (attr << 16) | GEN_SELECTOR_IDX(idx);
        cmd.arg2 = 0;
        cmd.arg3 = val;
        cmd.op = DME_SET;

        for (retries = 0; retries < UFS_UIC_COMMAND_RETRIES; ++retries) {
                result = ufshc_send_uic_cmd(base, &cmd);
                if (result == 0)
                        break;
                /* -EIO requires UFS re-init */
                if (result == -EIO) {
                        return result;
                }                                                                                                                                                                                          
        }
        if (retries >= UFS_UIC_COMMAND_RETRIES)
                return -EIO;

        return 0;
}

4.3 ufshc_send_uic_cmd

  • data = mmio_read_32(base + HCS);读取Host Controller Status寄存器的值,仅当UCRDY置位时才继续执行对应的ufs cmd。该位被置位表示当前ufs 主控制器已经准备好处理UIC命令。

    在这里插入图片描述

  • mmio_write_32(base + IS,~0);使能IAGES,CQES,SQES,CEFES,SBFES,HCFES,UTPES,DFES,UCCS,UTMRCS,ULSS,ULLS,UHES,UHXS,UPMS,UTMS,UE,UDEPRI,UTRCS
  • mmio_write_32(base + UCMDARG1,cmd->arg1);将arg1参数值写入UCMDARG1寄存器中。
    MIBattribute: Indicates the ID of the attribute of the requested. See MIPI UniPro Specification for the details of the MIBattribute parameter.
    MIBattribute: 表示请求的属性 ID。有关 MIBattribute 参数的详细信息,请参见 MIPI UniPro Specification。
    GenSelectorIndex: Indicates the targeted M-PHY data lane or CPort or Test Feature when relevant. See MIPI UniPro Specification for the details of the GenSelectorIndex parameter.
    GenSelectorIndex: 表示目标 M-PHY 数据通道、CPort 或测试功能(如相关)。有关 GenSelectorIndex 参数的详细信息,请参阅 MIPI UniPro 规范。

    在这里插入图片描述


    ResetMode: Indicates the link startup mode. See MIPI UniPro Specification for the details of the ResetMode parameter.
    重置模式: 表示链路启动模式。有关 ResetMode 参数的详细信息,请参阅 MIPI UniPro 规范。

    在这里插入图片描述


    ResetLevel: Indicates the reset type. See MIPI UniPro Specification for the details of the ResetLevel parameter.
    重置级别: 表示复位类型。有关 ResetLevel 参数的详细信息,请参见 MIPI UniPro Specification。

    在这里插入图片描述

在这里插入图片描述

  • mmio_write_32(base + UCMDARG2,cmd->arg2);将arg2参数值写入UCMDARG2寄存器中。

    在这里插入图片描述


    AttrSetType: Indicates whether the attribute value (AttrSet = NORMAL) or the attribute non-volatile reset value (STATIC) setting is requested. See MIPI UniPro Specification for the details of the AttrSetType parameter.
    AttrSetType: 表示请求设置属性值(AttrSet = NORMAL)还是属性非易失性重置值(STATIC)。有关 AttrSetType 参数的详细信息,请参阅 MIPI UniPro 规范。
    ConfigResultCode: Indicates the result of the UIC configuration command request. It is valid after host controller has set the IS.UCCS bit to ’1’. See MIPI UniPro Specification for the details of the ConfigResultCode parameter.
    ConfigResultCode: 表示 UIC 配置命令请求的结果。它在主机控制器将 IS.UCCS 位设置为 "1 "后有效。有关 ConfigResultCode 参数的详细信息,请参见 MIPI UniPro Specification。

    在这里插入图片描述


    GenericErrorCode: Indicates the result of the UIC control command request. It is valid after host controller has set the IS.UCCS bit to ’1’. See MIPI UniPro Specification for the details of the GenericErrorCode parameter.
    通用错误代码: 表示 UIC 控制命令请求的结果。它在主机控制器将 IS.UCCS 位设置为 "1 "后有效。有关 GenericErrorCode 参数的详细信息,请参见 MIPI UniPro Specification。

    在这里插入图片描述

  • mmio_write_32(base + UCMDARG3,cmd->arg3);将arg3参数值写入UCMDARG3寄存器中。

    在这里插入图片描述


    MIBvalue_R: Indicates the value of the attribute as returned by the UIC command returned. It is valid after host controller has set the IS.UCCS bit to ’1’. See MIPI UniPro Specification for the details of the MIBvalue parameter.
    MIBvalue_R: 表示 UIC 命令返回的属性值。它在主机控制器将 IS.UCCS 位设置为 "1 "后有效。有关 MIBvalue 参数的详细信息,请参阅 MIPI UniPro 规范。
    MIBvalue_W: Indicates the value of the attribute to be set. See MIPI UniPro Specification for details of the MIBvalue parameter.
    MIBvalue_W: 表示要设置的属性值。有关 MIBvalue 参数的详细信息,请参见 MIPI UniPro Specification。

  • mmio_write_32(base + UICCMD,cmd->op);将cmd-ops写入UICCMD寄存器中,使cmd开始处理。

    -

  • ufs_wait_for_int_status(UFS_INT_UCCS,UIC_CMD_TIMEOUT_MS,cmd->op == DME_SET); 等待期待的中断状态

int ufshc_send_uic_cmd(uintptr_t base, uic_cmd_t *cmd)
{
        unsigned int data;
        int result, retries;
                
        if (base == 0 || cmd == NULL)
                return -EINVAL;

        for (retries = 0; retries < 100; retries++) {
                data = mmio_read_32(base + HCS);
                if ((data & HCS_UCRDY) != 0) {
                        break;
                }
                mdelay(1);
        }
        if (retries >= 100) {                                                                                                                                                                              
                return -EBUSY;
        }

        mmio_write_32(base + IS, ~0);
        mmio_write_32(base + UCMDARG1, cmd->arg1);
        mmio_write_32(base + UCMDARG2, cmd->arg2);
        mmio_write_32(base + UCMDARG3, cmd->arg3);
        mmio_write_32(base + UICCMD, cmd->op);

        result = ufs_wait_for_int_status(UFS_INT_UCCS, UIC_CMD_TIMEOUT_MS,
                                         cmd->op == DME_SET);
        if (result != 0) {
                return result;
        }

        return mmio_read_32(base + UCMDARG2) & CONFIG_RESULT_CODE_MASK;
}

4.4 ufs_wait_for_int_status

  • interrupts_enabled = mmio_read_32(ufs_params.reg_base + IE);读取中断使能寄存器的值,该寄存器可启用或禁用向主机软件报告相应的中断。当某位被设置(‘1’)且相应的中断条件处于活动状态时,就会产生中断。被禁用(‘0’)的中断源仍会在 IS 寄存器中显示。该寄存器与 IS 寄存器对称。
  • interrupt_status = mmio_read_32(ufs_params.reg_base + IS) & interrupts_enabled;读取中断状态寄存器的值与中断使能寄存器的值与获取当前中断的状态值。
/*              
 * ufs_wait_for_int_status - wait for expected interrupt status
 * @expected: expected interrupt status bit
 * @timeout_ms: timeout in milliseconds to poll for
 * @ignore_linereset: set to ignore PA_LAYER_GEN_ERR (UIC error)
 *
 * Returns
 * 0 - received expected interrupt and cleared it
 * -EIO - fatal error,needs re-init
 * -EAGAIN - non-fatal error,caller can retry
 * -ETIMEDOUT - timed out waiting for interrupt status
 */
static int ufs_wait_for_int_status(const uint32_t expected_status,
                                   unsigned int timeout_ms,
                                   bool ignore_linereset)
{               
        uint32_t interrupt_status, interrupts_enabled;
        int result = 0;
        
        interrupts_enabled = mmio_read_32(ufs_params.reg_base + IE);
        do {
                interrupt_status = mmio_read_32(ufs_params.reg_base + IS) & interrupts_enabled;                                                                                                            
                if (interrupt_status & UFS_INT_ERR) {
                        mmio_write_32(ufs_params.reg_base + IS, interrupt_status & UFS_INT_ERR);
                        result = ufs_error_handler(interrupt_status, ignore_linereset);
                        if (result != 0) {
                                return result;
                        }
                }
        
                if (interrupt_status & expected_status) {
                        break;
                }
                mdelay(1);
        } while (timeout_ms-- > 0);
        
        if (!(interrupt_status & expected_status)) {
                return -ETIMEDOUT;
        }

        mmio_write_32(ufs_params.reg_base + IS, expected_status);

        return result;
}

原文地址:https://blog.csdn.net/u014100559/article/details/132287337

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读774次,点赞24次,收藏16次。typescript项目中我们使用typings-for-css-modules-loader来替代css-loader实现css modules。1、typings-for-css-modules-loader加载器介绍 Webpack加载器,用作css-loader的替代产品,可动态生成CSS模块的TypeScript类型这句话是什么意思呢?就是编译时处理css文件...
文章浏览阅读784次。react router redux antd eslint prettier less axios_react+antd+redux+less
文章浏览阅读3.9k次,点赞5次,收藏11次。需要删除.security-7索引文件。把在第1步中的被注释的配置打开。之后就是按照提示输入密码。执行bin目录下的文件。_failed to authenticate user 'elastic' against
文章浏览阅读1.2k次,点赞23次,收藏24次。Centos 8 安装es_centos8 yum elasticsearch
文章浏览阅读3.2k次。设置完之后,数据会⾃动同步到其他节点。修改密码时,将第⼀步配置删除,然后重启。单独使⽤⼀个节点⽣成证书;执⾏设置⽤户名和密码的命令。执⾏完上⾯命令以后就可以在。⽂件,在⾥⾯添加如下内容。这个⽂件复制到其他节点下。其中⼀个节点设置密码即可。依次对每个账户设置密码。全部节点都要重启⼀遍。需要在配置⽂件中开启。个⽤户分别设置密码,⽬录下,证书⽂件名为。功能,并指定证书位置。_es设置账号和密码
文章浏览阅读1.9k次,点赞2次,收藏7次。针对多数据源写入的场景,可以借助MQ实现异步的多源写入,这种情况下各个源的写入逻辑互不干扰,不会由于单个数据源写入异常或缓慢影响其他数据源的写入,虽然整体写入的吞吐量增大了,但是由于MQ消费是异步消费,所以不适合实时业务场景。不易出现数据丢失问题,主要基于MQ消息的消费保障机制,比如ES宕机或者写入失败,还能重新消费MQ消息。针对这种情况,有数据强一致性要求的,就必须双写放到事务中来处理,而一旦用上事物,则性能下降更加明显。可能出现延时问题:MQ是异步消费模型,用户写入的数据不一定可以马上看到,造成延时。_mysql同步es
文章浏览阅读3.6w次,点赞48次,收藏44次。【程序员洲洲送书福利-第十九期】《C++ Core Guidelines解析》
文章浏览阅读1.3k次。当我们在开发Vue应用时,经常需要对表单进行校验,以确保用户输入的数据符合预期。Vue提供了一个强大的校验规则机制,通过定义rules规则,可以方便地对表单进行验证,并给出相应的错误提示。_vue ruler校验
文章浏览阅读2k次,点赞16次,收藏12次。Linux内核源码下载地址及方式_linux源码下载
文章浏览阅读1k次。这样在每天自动生成的索引skywalking_log_xxx就会使用上述模版来生成,timestamp会被设置成date类型。然后此时在–>索引管理–>kibana–>索引模式添加skywalking_log*索引时就会有时间字段了。在通过skywalking将日志收集到es后,由于skywalking收集的日志(skywalking_log索引)没有date类型的字段导致在es上再索引模式中没有时间范围的查询。skywalking收集的日志有时间戳字段timestamp,只是默认为long类型。_skywalking timestamp
文章浏览阅读937次,点赞18次,收藏21次。1.初始化git仓库,使用git int命令。2.添加文件到git仓库,两步走:2.1 使用命令,注意,可反复多次使用,添加多个文件;2.2 使用命令,完成。此笔记是我个人学习记录笔记,通过廖雪峰的笔记进行学习,用自己能理解的笔记记录下来,如果侵权,联系删。不存在任何盈利性质,单纯发布后,用于自己学习回顾。
文章浏览阅读786次,点赞8次,收藏7次。上述示例中的 origin 是远程仓库的名称,https://github.com/example/repository.git 是远程仓库的 URL,(fetch) 表示该远程仓库用于获取更新,(push) 表示该远程仓库用于推送更新。你可以选择在本地仓库创建与远程仓库分支对应的本地分支,也可以直接将本地仓库的分支推送到远程仓库的对应分支。将 替换为远程仓库的名称(例如 origin), 替换为要推送的本地分支的名称, 替换为要推送到的远程分支的名称。_git remote 智能切换仓库
文章浏览阅读1.5k次。配置eslint校验代码工具_eslint 实时校验
文章浏览阅读1.2k次,点赞28次,收藏26次。Git入门基础介绍,什么是Git,如何使用Git,以及Git的工作的基本原理
文章浏览阅读2.7k次。基于官方给出的几种不同环境不同的安装方式,本文将会选择在使用.zip文件在Windows上安装Elasticsearch在Linux或macOS上从存档文件安装ElasticsearchInstall Elasticsearch with Docker (此种方式待定)使用Docker安装Elasticsearch。_elasticsearch安装部署windows
文章浏览阅读3.3k次,点赞5次,收藏11次。【Linux驱动】内核模块编译 —— make modules 的使用(单模块编译、多模块编译)_make modules
文章浏览阅读1k次。docker启动es报错_max virtual memory areas vm.max_map_count [65530] is too low, increase to at
文章浏览阅读4.2k次,点赞2次,收藏6次。使用docker单机安装elasticsearch后再安装kibana时找不到es。_unable to retrieve version information from elasticsearch nodes. security_ex
文章浏览阅读1.1k次。日志处理对于任何现代IT系统都是关键部分,本教程专为新手设计,通过详细解释Logstash的三大核心组件,为您展示如何从零开始搭建强大的日志处理系统。您还将学习如何同步MySQL数据到Elasticsearch,并通过一个"Hello World"示例快速入门。无论您是完全的新手还是有一些基础,本教程都将引导您顺利掌握Logstash的基本操作和高级应用。_logstash mysql
文章浏览阅读1.1w次,点赞5次,收藏25次。执行这条指令之后,你的本地项目就与远程Git仓库建立了连接,你就可以开始对你的代码进行版本追踪和协作开发了。使用“git remote add origin”指令,可以轻松地将本地项目连接到远程Git仓库。git remote set-url origin 执行这条指令之后,Git就会将已经添加的名为“origin”的仓库删除。git remote add origin 其中,是你的远程Git仓库的网址。_git remote add origin