- 博客(23)
- 资源 (1)
- 收藏
- 关注
原创 Linux pcie【9】基于GIC-V3 ITS实现pcie msi中断
本文基于Linux 6.6内核,介绍了如何通过GIC-V3 ITS驱动实现PCIe MSI功能。主要分析了MSI中断的申请流程:从pci_alloc_irq_vectors开始,经过MSI domain的创建和初始化,到ITS设备的分配和中断映射建立。重点阐述了request ID的计算、ITS设备表的创建、LPI中断的分配,以及最终建立device ID和event ID到init ID的映射关系。通过这一系列操作,PCIe设备发出的MSI中断能够被正确路由到GIC-V3的redistributor处理。
2025-12-03 18:18:22
742
1
原创 Linux pcie【8】GIC-V3 ITS驱动
本文介绍了Linux内核中GICv3 ITS驱动的实现框架,基于kernel 6.6版本。主要内容包括:1) ITS驱动入口its_init()通过dts方式初始化,调用its_of_probe()创建ITS节点;2) its_probe_one()负责分配命令队列和中断表内存,并初始化ITS域;3) 中断处理采用三层irq_domain层次结构,将EventID转换为虚拟中断号;4) its_init_domain()创建irq_domain用于MSI/MSIX中断映射。文章重点梳理了驱动初始化流程的关键
2025-11-24 15:53:00
441
原创 GIC-V3 ITS介绍
本文介绍了GIC-V3中断控制器中的ITS模块功能。相比GIC-V2,GIC-V3支持基于消息的中断传输,并新增了Redistributor模块和LPI中断类型。ITS模块负责接收外设的消息中断,通过DeviceID和EventID进行中断映射,将LPI中断转发至目标Redistributor。其映射表存储在DDR中,由CPU通过专门的命令队列进行配置管理。文章还提供了GIC600实现的技术参考文档链接。
2025-11-21 15:22:20
368
原创 linux pcie【7】- epf设备创建过程
本文分析了Linux 5.15内核中PCIe端点函数(epf)设备的创建过程,重点介绍了基于kernel的pci-epf-test例程的实现机制。首先通过pci_ep_cfs_init在configfs中创建pci_ep子系统,并建立functions和controllers两个config_group。然后详细解析了epf设备创建流程:从驱动注册到设备绑定,再到配置空间设置和与端点控制器(epc)的关联。最后说明如何通过写入start文件触发epc_start操作来完成与host的连接。整个过程涉及con
2025-06-20 16:54:59
1041
原创 linux pcie【6】- epf驱动介绍
本文介绍了在Linux 5.15内核中实现PCIe端点(EP)固件驱动的过程。主要内容包括:通过pci_epf_register_driver注册pci_epf_driver,实现probe和ops回调;在pci_epf_ops中完成bind/unbind操作,包括获取控制器参数、BAR空间分配、配置空间设置等;详细分析了COMMAND_COPY命令的处理流程,包括内存分配、地址映射和DMA传输机制;同时对比了主机端驱动程序的处理过程。文章以Synopsys控制器为例,展示了底层硬件寄存器的具体操作实现,为
2025-06-13 16:09:19
1253
原创 cortext-A7支持optee问题
通过上面的分析可以说明是IRQ向量引发的data abort,而且data abort后执行的地址是0xFFFF000C,说明optee里初始化的VBAR没有起作用,导致异常向量表在0xFFFF0000处,这里是我们的romcode,FPGA验证阶段的romcode没有设置IRQ的异常向量,导致IRQ发生后程序跑飞出现data abort。然后检查出错后的寄存器可以发现IRQ的R14寄存器正是"出错前的地址+8",所以说明打开IRQ和FIQ后立马进入了IRQ然后才发生的data abort。
2025-05-16 16:08:42
75
原创 linux pcie【5】- ep控制器驱动介绍
addr_space空间主要为outbound使用,717-738行, ep->phys_base保存addr_space的物理地址,其实就是outbound访问的物理基地址,ep->ob_window_map保存outbound访问的虚拟地,ep->outbound_addr用来保存outbound访问实际分配的物理地址。cpu 访问pci上的地址空间时,使用的是ob_window_map虚拟地址,然后转换为outbound_addr物理地址,最后通过outbound寄存器转换为pci总线地址。
2025-05-09 17:36:22
686
原创 linux pcie【4】- msi irq介绍
pp->msi_domain的parent为pp->irq_domain,对应的irq_chip为dw_pcie_msi_irq_chip,但是dw_pcie_msi_irq_chip并没有定义irq_write_msi_msg,这个会在pci_msi_domain_update_chip_ops里被赋值。我们先看一下pp->irq_domain,它的irq_domain_ops为dw_pcie_msi_domain_ops,对应的irq_chip为dw_pci_msi_bottom_irq_chip。
2025-04-29 19:55:06
638
1
原创 linux pcie【3】- device驱动介绍
pci_device_id的定义如下,控制器驱动扫描设备时会读取出设备配置空间里的Vendor ID, Device ID, Subsystem vendor ID, Subsystem device ID 等信息用来和pci_device_id里的对应字段匹配,配置成功后绑定相应的驱动。pci设备驱动使用pci_driver表示一个pci设备驱动。pci_device_id用来匹配一个pci_dev,probe和remove为驱动绑定和解绑的回调。下面介绍一些常用的api接口。
2025-04-24 19:30:47
433
原创 linux pcie【2】- rc控制器驱动介绍
本文分析了Linux 5.15内核中基于新思PCIe控制器的驱动实现。主要内容包括:1) PCIe控制器的数据结构组织,从dw_pcie到pcie_port再到pci_host_bridge和pci_bus的层级关系;2) dw_pcie_host_init函数的初始化流程,包括地址空间映射、MSI中断域设置、资源配置等关键步骤;3) PCIe总线扫描和设备枚举过程,重点分析了pci_host_probe和pci_scan_child_bus等核心函数;4) 配置空间访问机制,通过Type0/Type1配置
2025-04-22 18:23:14
1412
原创 linux pcie 【1】- 控制器介绍
主要有两种形式, 一种是IC集成的时候带AXI bridge,一种是不带AXI bridge(Native PCIe controller),一般arm soc集成的时候会配置成带AXI bridge这种形式,这样就就不用再处理控制器内部自定义的总线。本文主要介绍一下新思的PCIE控制器。首先看一下硬件控制器的框图。
2025-04-07 14:38:59
715
原创 Linux usb【4】- gadget configfs介绍
usb_add_config_only主要就是将config_usb_cfg->usb_configuration 结构挂到gadget_info->usb_composite_dev->configs链表上,同时将config_usb_cfg->usb_configuration->usb_composite_dev赋值为gadget_info->usb_composite_dev,并将这个配置描述符里的接口描述符清0。有了这个usb_ep结构,uac2驱动就可以使用它进行数据收发了。
2025-01-22 17:26:20
1958
原创 Linux usb【3】- gadget驱动介绍
在dwc3_gadget_init中主要就是调用dwc3_gadget_init_endpoints初始化ep, 并且申请了usb_gadget数据结构,并初始化里面的usb_gadget_ops回调函数, 然后调用usb_add_gadget。usb device设备对应的驱动是usb_gadget_driver ,这个驱动是在usb_gadget_probe_driver里面根据控制器名字绑定的,usb_gadget_probe_driver何时调用我们会在随后的文章中介绍。
2025-01-20 18:05:23
943
原创 Linux usb【2】- hub 驱动介绍
然后调用kick_hub_wq,用来处理刚上电时hub的端口状态。hub_probe里主要就是分配了一个usb_hub结构,并且注册了一个events工作队列和一个rq_urb_retry定时器,events工作队列主要用来出来hub的一些插拔事件,rq_urb_retry用来向hub发送hub->urb失败后通过定时器回调重新发送。再看下hub_irq,它除了调用kick_hub_wq,还会调用hub_resubmit_irq_urb,再次发送hub->urb用来轮询hub状态。
2025-01-03 17:25:02
1265
原创 zephyr介绍
这样的线程成为了当前线程后,它可以在任何时刻被协作式线程或者优先级更高(或相等)的抢占式线程替代。同一个内存片上面的所有内存块的尺寸是固定(相同)的,这样做的好处是可以高效地分配和释放,避免了内存碎片问题。基于单链表实现的异步传输。消息队列(message queue) 是一个内核对象,它实现了一个简单的消息队列,允许线程和 ISR 异步地发送和接收大小固定的数据项。用户之间的memory是隔离的, 加到同一个memory domain的线程才可以共享同一domain的memory partition。
2024-11-27 15:16:30
257
原创 linux DMA框架【3】-DMA map操作
当我们希望通过DMA访问DDR时,就要考虑两个问题,一就是DMA访问DDR的地址是什么,还有就是DMA访问的这块DDR空间CPU也会访问时,如何做缓存一致性。linux kernel抽象出dma map操作就是用来解决这两个问题的。为了提高性能cpu或者某些高速设备会使用cache,由于会存在cpu和设备访问同一个DDR空间的可能,这就会引入cache一致性问题,所以kernel使用dma map操作来解决这个问题,屏蔽底层的差异。
2024-11-18 17:14:12
1813
原创 linux crypto框架
crypto_alg,定义了一个crypto所有支持算法的基类, 所有算法结构除了定义自己特殊的一些成员,都会包含crypto_alg这个结构, alg其实就是对应的具体算法的现,它会对应到cipher engine内的一个算法实体,这个实体驱动就是通过实现alg里的回调来实现的。cypto_queue的list就用用来挂载所有的request的,如果所有的requet的数量大于max_qlen, 新提交的request会从第一个开始,被backlog记录下来,并返回一个-EBUSY错误。
2024-11-15 17:02:04
1456
原创 linux dma框架【2】-peripheral和dma request id的绑定
client申请channel时直接使用dma_request_channel来申请一个channel, 它在参数里需要一个filter回调来帮助选择一个合适的channel,然后通过dmaengine_slave_config配置这个channel时,将dma_slave_config里的slave_id成员设置为对应的request id,这当然需要dma控制器驱动的支持。of_dma_controller_register就是用来注册of_dma结构的,它被挂到of_dma_list全局链表里。
2024-11-04 18:46:54
732
2
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅