Linu下基于AHCI controller模块实现SATA Platform驱动附代码详细流程

目录

    • 一、简介
    • 二、驱动开发
      • 2.1 整体开发过程总结
      • 2.2 详细过程
    • 三、Platform驱动讲解
      • 3.1 整体概念
      • 3.2 驱动架构
    • 四、其他相关链接
      • 1、SATA模块之HBA卡开发总结(一)
      • 2、SATA信息传输FIS结构总结
      • 3、SATA驱动中FIS命令处理详细流程
      • 4、PCIe物理层总结-PCIE专题知识(一)
      • 5、PCIe数据链路层图文总结-PCIe专题知识(二)
      • 6、SSD硬盘SATA接口和M.2接口区别总结

一、简介

本文主要是针对ARM A55集成了AHSATA controller模块开发sata驱动,通过Platform的形式在linux识别到SSD,本文详细讲述整个开发过程,同时对SATA Platform驱动进行讲解。

二、驱动开发

2.1 整体开发过程总结

1、配置SATA Phy的初始化;
2、打开SATA Platform相关编译开关;
3、配置设备树;
4、linux启动识盘。

2.2 详细过程

1、Phy的配置
因为该芯片集成的是Synopsys的SATA IP,要通过SPCS的方式写入Phy的配置,同时设置OOB和CLOCK,因为代码不具有通用性就只粘贴一部分。
在这里插入图片描述

2、内核config配置

CONFIG_DAPU_AHCI_HOST=y
CONFIG_ATA=y
CONFIG_SATA_HOST=y                                                        
CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_ATA_FORCE=y
CONFIG_SATA_PMP=y 
CONFIG_SATA_AHCI_PLATFORM=y
CONFIG_ATA_SFF=y
CONFIG_PATA_PLATFORM=y
CONFIG_PATA_OF_PLATFORM=y
#CONFIG_CHR_DEV_SG=y

注意CONFIG_CHR_DEV_SG=y要注释掉,该模块会影响CPU多核启动。

3、配置设备树

	sata: ahci@25000000 {
		compatible = "dapu,host-ahci";
		reg = <0x0 0x25000000 0x0 0x600>;
		interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;  //CSS_IRQ_AHSATA0 112 - 32
		interrupt-names = "hostc";
		ports-implemented = <0xFF>;
		status = "okay";
	};		

注意SATA的基地址要根据具体controller的地址填充,中断也是一样。

在platform驱动中加入dts的匹配内容
在这里插入图片描述

4、Linux启动

在这里插入图片描述
在这里插入图片描述

三、Platform驱动讲解

3.1 整体概念

Platform驱动主要是进行SATA寄存器的配置、reset controller、使能FIS,识盘,最后可进行读写操作。
首先通过分层的思想一下AHSATA的通路:
1、物理层采用全双工串行传输方式,主要功能是进行信号的串并及并串转化。
2、链路层的主要功能是通过控制原语的传递来控制信息帧的整个传输过程,保证帧信息能够正确的发送与接收,并能进行流量的控制,防止数据发送过快或接收过多。
3、传输层主要负责FIS帧信息结构的封装与解封。
4、应用层能够接收来自主机端的命令,根据命令的要求将自身的信息发送给主机端,或是接收来自主机端的以PIO或DMA方式传输的数据,同时写入闪存中,也能从闪存中以PIO或DMA的方式读出数据,传送给主机端。在应用层采用两个FIFO对数据进行缓冲,一个为读FIFO,一个为写FIFO。应用层能接收来自传输层的数据帧送入写FIFO中或将来自设备内部总线的数据保存在读FIFO中,然后通知传输层构造数据帧。

3.2 驱动架构

在这里插入图片描述

具体代码详细解析:

//初始化时
ahci_host_activate
    ->ata_host_activate
        ->ahci_port_start
//Command Header初始化位置:
ahci_port_resume
    -> ahci_power_up
        ->配置PxCMD寄存器,开启Staggered Spin-up(交错启动模式),切换到Active模式
    -> ahci_start_port
        -> ahci_start_fis_rx
            ->writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
            -> 配置PxCLB、PxCLBU、PxFB、PxFBU寄存器
            -> 配置PxCMD寄存器,使能接收FIS
        -> ahci_start_engine
            -> 配置PxCMD寄存器,使能端口DMA引擎
        -> 配置LED闪烁定时器及回调函数
//运行时
ata_port_schedule_eh
    ->ata_std_sched_eh
        ->scsi_schedule_eh
            ->scsi_error_handler//SCSI的主错误处理内核态线程, 通过scsi_eh_wakeup唤醒
                ->ata_scsi_error
                    ->ata_scsi_port_error_handler
                        ->ata_eh_handle_port_resume
                            ->ahci_port_resume

四、其他相关链接

1、SATA模块之HBA卡开发总结(一)

2、SATA信息传输FIS结构总结

3、SATA驱动中FIS命令处理详细流程

4、PCIe物理层总结-PCIE专题知识(一)

5、PCIe数据链路层图文总结-PCIe专题知识(二)

6、SSD硬盘SATA接口和M.2接口区别总结