PCIe学习笔记(1)Hot-Plug机制

文章目录

  • Hot-Plug Init
  • Hot Add Flow
  • Surprise Remove Flow
  • NPEM Flow

Hot-Plug Init

PCIe hot-plug是一种支持在不关机情况下从支持的插槽添加或删除设备的功能,PCIe架构定义了一些寄存器以支持原生热插拔。相关寄存器主要分布在Device Capabilities, Slot Capabilities, Slot Control, Slot Status和Slot Capabilities 2。Hot-Plug相关支持寄存器位置如下。
在这里插入图片描述
一个Downstream Port支持以下热插拔事件。

  • Slot Events:
    • Attention Button Pressed
    • Power Fault Detected
    • MRL Sensor Changed
    • Presence Detect Changed
  • Command Completed Events
  • Data Link Layer State Changed Events

主要事件都可以通过寄存器控制使能,需要在初始化时配置启用。如果要启用INTx message,需配置如下:

  • Command register内的Interrupt Disable位需要设为0
  • Slot Control register内的Hot-Plug Interrupt Enable位需要设为1
  • 至少使能一个hot-plug event控制寄存器
    如果要启用MSI/MSI-X,则需取消屏蔽关联向量。PME和Hot-Plug事件中断共享同一向量,由PCIE Capabilities的Interrupt Message Number域段控制。
    在这里插入图片描述

Hot-Plug事件产生需要启用PME_En位。
在这里插入图片描述

Hot Add Flow

主要处理Presence Detect Changed, Command Completed events(需要在No Command Completed Support为0时,否则硬件支持无通知式自动完成)。
pciehp_handle_presence_or_link_change函数为Presence Detect Changed事件中断服务函数。

void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events)
{int present, link_active;/** If the slot is on and presence or link has changed, turn it off.* Even if it's occupied again, we cannot assume the card is the same.*/mutex_lock(&ctrl->state_lock);switch (ctrl->state) {case BLINKINGOFF_STATE:cancel_delayed_work(&ctrl->button_work);fallthrough;case ON_STATE:ctrl->state = POWEROFF_STATE;mutex_unlock(&ctrl->state_lock);if (events & PCI_EXP_SLTSTA_DLLSC)ctrl_info(ctrl, "Slot(%s): Link Down\n",slot_name(ctrl));if (events & PCI_EXP_SLTSTA_PDC)ctrl_info(ctrl, "Slot(%s): Card not present\n",slot_name(ctrl));pciehp_disable_slot(ctrl, SURPRISE_REMOVAL);  //call remove_boardbreak;default:mutex_unlock(&ctrl->state_lock);break;}/* Turn the slot on if it's occupied or link is up */mutex_lock(&ctrl->state_lock);present = pciehp_card_present(ctrl);link_active = pciehp_check_link_active(ctrl);if (present <= 0 && link_active <= 0) {if (ctrl->state == BLINKINGON_STATE) {ctrl->state = OFF_STATE;cancel_delayed_work(&ctrl->button_work);pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,INDICATOR_NOOP);ctrl_info(ctrl, "Slot(%s): Card not present\n",slot_name(ctrl));}mutex_unlock(&ctrl->state_lock);return;}switch (ctrl->state) {case BLINKINGON_STATE:cancel_delayed_work(&ctrl->button_work);fallthrough;case OFF_STATE:ctrl->state = POWERON_STATE;mutex_unlock(&ctrl->state_lock);if (present)ctrl_info(ctrl, "Slot(%s): Card present\n",slot_name(ctrl));if (link_active)ctrl_info(ctrl, "Slot(%s): Link Up\n",slot_name(ctrl));ctrl->request_result = pciehp_enable_slot(ctrl);  //call board_added()break;default:mutex_unlock(&ctrl->state_lock);break;}
}
pciehp_enable_slot会调用board_added(通过__pciehp_enable_slot)和pciehp_set_indicators
static int pciehp_enable_slot(struct controller *ctrl)
{int ret;pm_runtime_get_sync(&ctrl->pcie->port->dev);ret = __pciehp_enable_slot(ctrl);if (ret && ATTN_BUTTN(ctrl))/* may be blinking */pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,INDICATOR_NOOP);pm_runtime_put(&ctrl->pcie->port->dev);mutex_lock(&ctrl->state_lock);ctrl->state = ret ? OFF_STATE : ON_STATE;mutex_unlock(&ctrl->state_lock);return ret;
}

board_added完成了pciehp_power_on_slot,pciehp_set_indicators,pciehp_configure_device (Off -> Blink -> On)

static int board_added(struct controller *ctrl)
{int retval = 0;struct pci_bus *parent = ctrl->pcie->port->subordinate;if (POWER_CTRL(ctrl)) {/* Power on slot */retval = pciehp_power_on_slot(ctrl);if (retval)return retval;}pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK,INDICATOR_NOOP);/* Check link training status */retval = pciehp_check_link_status(ctrl);if (retval)goto err_exit;/* Check for a power fault */if (ctrl->power_fault_detected || pciehp_query_power_fault(ctrl)) {ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(ctrl));retval = -EIO;goto err_exit;}retval = pciehp_configure_device(ctrl);if (retval) {if (retval != -EEXIST) {ctrl_err(ctrl, "Cannot add device at %04x:%02x:00\n",pci_domain_nr(parent), parent->number);goto err_exit;}}pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_ON,PCI_EXP_SLTCTL_ATTN_IND_OFF);return 0;err_exit:set_slot_off(ctrl);return retval;
}
int pciehp_power_on_slot(struct controller *ctrl)
{struct pci_dev *pdev = ctrl_dev(ctrl);u16 slot_status;int retval;/* Clear power-fault bit from previous power failures */pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);if (slot_status & PCI_EXP_SLTSTA_PFD)pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,PCI_EXP_SLTSTA_PFD);ctrl->power_fault_detected = 0;pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_ON, PCI_EXP_SLTCTL_PCC);ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL,PCI_EXP_SLTCTL_PWR_ON);retval = pciehp_link_enable(ctrl);if (retval)ctrl_err(ctrl, "%s: Can not enable the link!\n", __func__);return retval;
}

Surprise Remove Flow

需要处理AER和DPC events,然后处理hot-plug events。中断触发pciehp_handle_presence_or_link_change,然后pciehp_disable_slot会调用remove_board(通过__pciehp_disable_slot),remove_board主要完成pciehp_power_off_slot和pciehp_set_indicators (On -> Off)。Presense detected需要等待DPC先触发。

static int pciehp_disable_slot(struct controller *ctrl, bool safe_removal)
{int ret;pm_runtime_get_sync(&ctrl->pcie->port->dev);ret = __pciehp_disable_slot(ctrl, safe_removal);pm_runtime_put(&ctrl->pcie->port->dev);mutex_lock(&ctrl->state_lock);ctrl->state = OFF_STATE;mutex_unlock(&ctrl->state_lock);return ret;
}
static void remove_board(struct controller *ctrl, bool safe_removal)
{pciehp_unconfigure_device(ctrl, safe_removal);if (POWER_CTRL(ctrl)) {pciehp_power_off_slot(ctrl);/** After turning power off, we must wait for at least 1 second* before taking any action that relies on power having been* removed from the slot/adapter.*/msleep(1000);/* Ignore link or presence changes caused by power off */atomic_and(~(PCI_EXP_SLTSTA_DLLSC | PCI_EXP_SLTSTA_PDC),&ctrl->pending_events);}pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,INDICATOR_NOOP);
}
void pciehp_power_off_slot(struct controller *ctrl)
{pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_OFF, PCI_EXP_SLTCTL_PCC);ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL,PCI_EXP_SLTCTL_PWR_OFF);
}

NPEM Flow

NPEM(Native PCIe Enclosure Management) 是PCIe标准为NVMe设备定义的扩展LED控制功能,热插拔的LED控制机制由NPEM完成。可以实现在DP内或UP内,用于控制和更新LED状态。软件通过写入NPEM控制寄存器来发出NPEM指令,NPEM控制器根据指令更新LED状态,并使用completed机制指示软件完成。
在这里插入图片描述
NPEM支持实现OK/Locate/Fail/Rebuild等可选LED状态。
在这里插入图片描述
Linux Reference:
drivers/pci/hotplug /pciehp_hpc.c
driversdrivers/pci/hotplug/pciehp_ctrl.c

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2777494.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

[word] word分割线在哪里设置 #其他#经验分享

word分割线在哪里设置 在工作中有些技巧&#xff0c;可以快速提高工作效率&#xff0c;解决大部分工作&#xff0c;今天给大家分享word分割线在哪里设置的小技能&#xff0c;希望可以帮助到你。 1、快速输入分割线 输入三个【_】按下回车就是一条长直线&#xff0c;同样分别…

巧用liteflow,告别if else,SpringBoot整合liteflow

假设有一个三个原子业务&#xff0c;吃饭、喝水、刷牙。 现在有三个场景&#xff0c;分别是 场景A: 吃饭->刷牙->喝水 官网地址&#xff1a;https://liteflow.cc/ 1.添加依赖&#xff1a; <dependency><groupId>com.yomahub</groupId><artifactI…

Merging of neural networks

Merging of neural networks 论文链接&#xff1a;https://arxiv.org/pdf/2204.09973v2.pdf源码链接&#xff1a;https://github.com/fmfi-compbio/neural-network-merging 简介 典型的神经网络训练从随机初始化开始&#xff0c;并进行训练&#xff0c;直到在某些局部最优中…

GEE数据——美国农业部LANDFIRE (LF)数据集2.3.0版本

地面火灾数据集 LANDFIRE (LF)&#xff0c;即 "地貌火灾和资源管理规划工具"&#xff0c;是美国农业部森林服务局、美国内政部地质调查局和大自然保护协会的野地火灾管理项目之间的共享项目。前言 – 人工智能教程 LANDFIRE (LF) 图层是利用基于大量实地参考数据、…

【芯片设计- RTL 数字逻辑设计入门 14 -- 使用子模块实现三输入数的大小比较】

文章目录 三输入数的大小比较问题分析verilog codeTestBench Code综合图仿真波形图 三输入数的大小比较 在数字芯片设计中&#xff0c;通常把完成特定功能且相对独立的代码编写成子模块&#xff0c;在需要的时候再在主模块中例化使用&#xff0c;以提高代码的可复用性和设计的层…

时间序列预测 —— DeepAR 模型

时间序列预测 —— DeepAR 模型 DeepAR 模型是一种专门用于处理时间序列概率预测的深度学习模型&#xff0c;它可以自动学习数据中的复杂模式&#xff0c;提高预测的准确性。本文将介绍 DeepAR 模型的理论基础、优缺点&#xff0c;并通过 Python 实现单步预测和多步预测的完整…

JavaScript滚动事件

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 滚动是网页交互不可或缺的一部分。监听页面和元素的滚动事件,可以帮助…

数解 transformer 之 self attention transformer 公式整理

句子长度为n&#xff1b;比如2048&#xff0c;或1024&#xff0c;即&#xff0c;一句话最多可以是1024个单词。 1, 位置编码 可知&#xff0c;E是由n个列向量组成的矩阵&#xff0c;每个列向量表示该列号的位置编码向量。 2, 输入向量 加入本句话第一个单词的词嵌入向量是, 第…

汽车零部件MES系统解决方案

汽车零部件行业现状 随着全球汽车产业不断升级&#xff0c;汽车零部件市场竞争日趋激烈&#xff0c;从上游的钢铁、塑料、橡胶等生产到下游的主机厂配套制造&#xff0c;均已成为全球各国汽车制造大佬战略目标调整的焦点&#xff0c;其意欲在汽车零部件行业快速开疆扩土&#x…

EMC学习笔记(二十二)降低EMI的PCB设计指南(二)

降低EMI的PCB设计指南&#xff08;二&#xff09; 1.电源和地概述2.电感量3.两层板和四层板4.单层和双层设计中的微控制器接地5.信号返回地6.模拟、数字信号与大功率电源7.模拟电源引脚和模拟参考电源8.四层板电源设计参考注意事项 tips&#xff1a;资料主要来自网络&#xff0…

Go语言的100个错误使用场景(30-40)|数据类型与字符串使用

前言 大家好&#xff0c;这里是白泽。 《Go语言的100个错误以及如何避免》 是最近朋友推荐我阅读的书籍&#xff0c;我初步浏览之后&#xff0c;大为惊喜。就像这书中第一章的标题说到的&#xff1a;“Go: Simple to learn but hard to master”&#xff0c;整本书通过分析100…

【Rust日报】2024-02-08 Loungy:使用 Rust 和 GPUI 开发的 MacOS 启动器

Mira Screenshare&#xff1a;基于 Rust 和 WebRTC 的高性能屏幕分享工具 一群大学生宣布推出了他们的期末项目&#xff1a;Mira Screenshare&#xff0c;一个开源、高性能的屏幕共享工具&#xff0c;由 Rust 和 WebRTC 构建。此项目支持 4k 60 FPS 和 110ms 端到端延迟的屏幕…

这种学习单片机的顺序是否合理?

这种学习单片机的顺序是否合理&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「单片机的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01…

图像处理之《鲁棒图像隐写术:隐藏频率系数中的信息》论文精读

一、文章摘要 隐写术是一种将秘密信息隐藏到公共多媒体对象中而不会引起第三方怀疑的技术。然而&#xff0c;大多数现有的工作不能提供良好的抗有损JPEG压缩鲁棒性&#xff0c;同时保持相对较大的嵌入容量。提出了一种基于可逆神经网络的端到端鲁棒隐写系统。该方法将秘密信息…

【开源】基于JAVA+Vue+SpringBoot的智慧社区业务综合平台

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 业务类型模块2.2 基础业务模块2.3 预约业务模块2.4 反馈管理模块2.5 社区新闻模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 业务类型表3.2.2 基础业务表3.2.3 预约业务表3.2.4 反馈表3.2.5 社区新闻表 四、系统展…

【Python中Selenium元素定位的各种方法】

1、元素定位操作&#xff1a; 2、创建浏览器驱动操作&#xff0c;导入By模块&#xff1a; from selenium import webdriver # 用于界面与浏览器互动 from selenium.webdriver.common.by import By # 用于元素定位 driver webdriver.Chrome() # 调用Chrome类&#xff0c;创…

知识图谱与图神经网络融合:构建智能应用的新前沿

目录 前言1 知识图谱表示学习1.1 典型模型1.2 下游任务 2 图神经网络与知识图谱表示学习2.1 Compgcn&#xff1a;合成图卷积模型2.2 知识图谱嵌入在归纳设置下的推进 3 图神经网络与知识图谱构建3.1 关系抽取的进阶应用3.2 结构信息补全与知识图谱的完整性 4 图神经网络与知识图…

基于css-vars-ponyfill实现换肤

文章目录 一、换肤二、换肤调研2.1、ElementUI2.2、ant.design 三、换肤痛点和思考四、换肤架构五、换肤技术选型和实现5.1、该方案的亮点和规则5.2、核心原理5.3、色组 & 色值平台设计5.4、获取在当前主题自定义变量颜色 六、总结七、最后 一、换肤 网站或者应用一键切换…

【大厂AI课学习笔记】【1.5 AI技术领域】(8)文本分类

8,9,10&#xff0c;将分别讨论自然语言处理领域的3个重要场景。 自然语言处理&#xff0c;Natual Language Processing&#xff0c;NLP&#xff0c;包括自然语言识别和自然语言生成。 用途是从非结构化的文本数据中&#xff0c;发掘洞见&#xff0c;并访问这些信息&#xff0…

Flume安装部署

安装部署 安装包连接&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1m0d5O3Q2eH14BpWsGGfbLw?pwd6666 &#xff08;1&#xff09;将apache-flume-1.10.1-bin.tar.gz上传到linux的/opt/software目录下 &#xff08;2&#xff09;解压apache-flume-1.10.1-bin.tar.gz…