aspeed BMC AST2500处理器ESPI驱动分析

1.概述

Enhanced SerialPeripheral Interface (eSPI) is an interface using pins of SPI, but runsdifferent protocol.

It interfacesupports peripheral, virtual wire, out-of-band, and flash sharing channels.

This controllersupports all 4 channels and operates at max frequency of 66MHz.

It alsosupports up to quad-io[4倍IO] mode.

2.特点

31.2 Features

• Supports 66, 50,33, 25, and 20MHz of eSPI clock frequency.

• Supports Quad-,Dual-, and Single-IO mode.

• Supports both alertmode: shared IO or dedicated[专用IO].

• Supports 4channels.

• Peripheral Channel:

– Maximum payloadsize is 64 bytes.

• Virtual WireChannel:

– Maximum virtualwire count is 8.

– Support 32interrupts.

– Support 32 GPIOs.These GPIOs can be connected to physical pins or software mode.

• Out-Of-BandChannel:

– Maximum payloadsize is 64 bytes.

• Run-time FlashSharing Channel:

– Maximum payloadsize is 64 bytes.

– Supports bothmaster- and slave-attached flash sharing.

3.寄存器基址

Registers :Base Address = 0x1E6E E000

4.驱动相关文件

/chipset/AST2500/drivers/espi_drv/OS/Linux/Host/AST2500/espi_drv.c

/Kernel/Host/AST2500/linux/arch/arm/plat-aspeed/dev-espi.c

espi_drv.c文件是espi驱动文件,里面定义了espiprobe、remove,中断处理函数等。

dev-espi.c文件是针对aspeedast2500 CPU的资源做了定义。资源包括各寄存器的基址,寄存器占用的内存大小等等。

5.驱动分析

5.1 硬件寄存器等资源配置

// dev-espi.c中定义寄存器基址、占用内存大小、设备名等信息的两个结构体。

static structresource ast_espi_resource[] = {

         [0] = {

                   .start = AST_ESPI_BASE,

                   .end = AST_ESPI_BASE + SZ_256-1,

                   .flags = IORESOURCE_MEM,

         },

         [1] = {

                   .start = IRQ_ESPI,

                   .end = IRQ_ESPI,

                   .flags = IORESOURCE_IRQ,

         },

};

static structplatform_device ast_espi_device = {

         .name       ="ast-espi",

         .id = 0,

         .dev = {

                   .dma_mask =&ast_espi_dma_mask,

                   .coherent_dma_mask =0xffffffff,

//               .platform_data =&ast_espi_info,

         },

         .resource = ast_espi_resource,

         .num_resources =ARRAY_SIZE(ast_espi_resource),

};

ast_espi_device会在驱动加载过程中用到。

5.2 espi驱动流程

// espi_drv.c

static structplatform_driver ast_espi_driver = {

         .probe      = ast_espi_probe,

         .remove     = ast_espi_remove,

         .driver     = {

                   .name   = "ast-espi",

                   .owner  = THIS_MODULE,

         },

};

platform_device_register和platform_driver_register驱动加载原理不细谈。只需要关注一点,当platform_driver_register(&ast_espi_driver)执行后,根据ast_espi_driver->driver.name遍历structplatform_device结构体,找到device->name相同的设备信息结构体。实现了驱动函数和具体的寄存器之间的绑定。

这里以espi_drv.c中static intast_espi_probe(struct platform_device *pdev)函数为切入点。当platform_driver_register(&ast_espi_driver)执行时候,找到对应的平台device后,会主动调用ast_espi_driver->probe,也就是ast_espi_probe函数。参数structplatform_device *pdev就是驱动加载过程中遍历到的结构体指针,即为& ast_espi_device。

此函数定义两个重要变量。

struct resource *res;

res是设备资源结构体,由传入的参数pdev-> resource赋值。

struct ast_espi_dev {

         void__iomem        *reg_base;

         int                  irq;

} *espi_dev;

espi_dev指针是一个指向堆内存的指针。一旦申请成功,这段堆内存会一直被espi驱动独享,除非驱动被卸载。espi_dev结构体只有两个成员:一个寄存器基址和中断号。

5.2.1 驱动准备阶段

         (1) espi_dev = kzalloc(sizeof(structast_espi_dev), GFP_KERNEL);

         (2) res = platform_get_resource(pdev,IORESOURCE_MEM, 0);   

         (3) res =request_mem_region(res->start, resource_size(res), pdev->name);

         (4) espi_dev->reg_base =ioremap(res->start, resource_size(res));

         (5) espi_dev->irq =platform_get_irq(pdev, 0);

过程(1) 给espi_dev分配内存。过程(2)从& ast_espi_device中获取资源并赋值给res。过程(3)(4)将物理基址0x1E6EE000映射为虚拟内存,赋值给espi_dev->reg_base。过程(5)从& ast_espi_device获取中断号并赋值给espi_dev->irq。

5.2.2 申请中断

ret =request_irq(espi_dev->irq, ast_espi_isr, IRQF_SHARED, "ast-espi",espi_dev);

由中断号申请中断处理函数ast_espi_isr。中断处理函数5.3讨论。

5.2.3 寄存器操作阶段

接着一大段寄存器操作。

1) ast_espi_write(espi_dev,ast_espi_read(espi_dev, AST_ESPI_CTRL) | (0x1 << 4), AST_ESPI_CTRL);

***********

4 RW OOBChannel Ready.

This bit must be set to Tx/Rx OOB Channel.

 

2) ast_espi_write(espi_dev,ESPI_SYS_INT_T0, AST_ESPI_SYS_INT_T0);

***********

0 RW Interrupttype 0 of NMI Out

9 RW Interrupttype 0 of SMI Out

8 RW Interrupttype 0 of Host Reset Warn

7 Reserved

6 RW Interrupttype 0 of OOB Reset Warn

5 RW Interrupttype 0 of PLTRSTN

4 RW Interrupttype 0 of Suspend Status

3 Reserved

2 RW Interrupttype 0 of S5 Sleep Control

1 RW Interrupttype 0 of S4 Sleep Control

0 RW Interrupttype 0 of S3 Sleep Control

关闭以上所有中断。

***********

 

3) ast_espi_write(espi_dev,ESPI_SYS_INT_T1, AST_ESPI_SYS_INT_T1);

***********

10 RW Interrupttype 1 of NMI Out

9 RW Interrupttype 1 of SMI Out

8 RW Interrupttype 1 of Host Reset Warn

6 RW Interrupttype 1 of OOB Reset Warn

5 RW Interrupttype 1 of PLTRSTN

4 RW Interrupttype 1 of Suspend Status

3 Reserved

2 RW Interrupttype 1 of S5 Sleep Control

1 RW Interrupttype 1 of S4 Sleep Control

0 RW Interrupttype 1 of S3 Sleep Control

关闭以上所有中断。

***********

 

4) ast_espi_write(espi_dev,ESPI_SYS_INT_T2, AST_ESPI_SYS_INT_T2);

***********

10 RW Interrupttype 2 of NMI Out

9 RW Interrupttype 2 of SMI Out

8 RW Interrupttype 2 of Host Reset Warn

7 Reserved

6 RW Interrupttype 2 of OOB Reset Warn

5 RW Interrupttype 2 of PLTRSTN

4 RW Interrupttype 2 of Suspend Status

3 Reserved

2 RW Interrupttype 2 of S5 Sleep Control

1 RW Interrupttype 2 of S4 Sleep Control

0 RW Interrupttype 2 of S3 Sleep Control

关闭以上所有中断。

***********

 

5) ast_espi_write(espi_dev,ESPI_SYS_INT, AST_ESPI_SYS_IER);

***********

10 RW EnableInterrupt of NMI Out

9 RW EnableInterrupt of SMI Out

8 RW Enable Interrupt of Host Reset Warn

7 Reserved

6 RW Enable Interrupt of OOB Reset Warn

5 RW Enable Interrupt of PLTRSTN

4 RW EnableInterrupt of Suspend Status

3 Reserved

2 RW EnableInterrupt of S5 Sleep Control

1 RW EnableInterrupt of S4 Sleep Control

0 RW EnableInterrupt of S3 Sleep Control

使能以上红色标注的中断。

***********

 

6) ast_espi_write(espi_dev,ESPI_SUS_WARN, AST_ESPI_SYS1_INT_T0);

***********

16 RW Interrupttype 0 of Host C10

15: 8 RWInterrupt type 0 of PCH Generic

7: 6 Reserved

5 RW Interrupttype 0 of Wireless Lan Sleep Control

4 RW Interrupttype 0 of Lan Sleep Control

3 RW Interrupttype 0 of A# Sleep Control

2 Reserved

1 RW Interrupttype 0 of Suspend PowerDown Ack

0 RW Interrupt type 0 of Suspend Warn

使能System Event 1 fromMaster对应的以上红色标注的中断。

***********

 

7) ast_espi_write(espi_dev,0x00000000, AST_ESPI_SYS1_INT_T1);

***********

16 RW Interrupttype 1 of Host C10

15: 8 RWInterrupt type 1 of PCH Generic

7: 6 Reserved

5 RW Interrupttype 1 of Wireless Lan Sleep Control

4 RW Interrupttype 1 of Lan Sleep Control

3 RW Interrupttype 1 of A# Sleep Control

2 Reserved

1 RW Interrupttype 1 of Suspend PowerDown Ack

0 RW Interrupttype 1 of Suspend Warn

关闭System Event 1 fromMaster对应以上所有的中断。

***********

 

8) ast_espi_write(espi_dev,0x00000000, AST_ESPI_SYS1_INT_T2);

***********

16 RW Interrupttype 2 of Host C10

15: 8 RWInterrupt type 2 of PCH Generic

7: 6 Reserved

5 RW Interrupttype 2 of Wireless Lan Sleep Control

4 RW Interrupttype 2 of Lan Sleep Control

3 RW Interrupttype 2 of A# Sleep Control

2 Reserved

1 RW Interrupttype 2 of Suspend PowerDown Ack

0 RW Interrupttype 2 of Suspend Warn

关闭System Event 1 fromMaster对应的以上所有的中断。

***********

 

9) ast_espi_write(espi_dev,ESPI_SUS_WARN, AST_ESPI_SYS1_IER);

************

3 RW EnableInterrput of A# Sleep Control

2 Reserved

1 RW EnableInterrput of Suspend PowerDown Ack

0 RW Enable Interrput of Suspend Warn

开启System Event 1 from Master对应的以上红色标记的中断。

************

 

10) ast_espi_write(espi_dev,0xFFFFFFFF, AST_ESPI_IER);

************

31 RW Enable of Hardware Reset Event

30:22 R Reserved

21 RW Enable of Flash Channel Tx Error

20 RW Enable of OOB Channel Tx Error

19 RW Enable of Flash Channel Tx Abort

18 RW Enable of OOB Channel Tx Abort

17 RW Enable of Peripheral Channel Non-Posted Tx Abort

16 RW Enable of Peripheral Channel Posted Tx Abort

15 RW Enable of Flash Channel Rx Abort

14 RW Enable of OOB Channel Rx Abort

13 RW Enable of Peripheral Channel Non-Posted Rx Abort

12 RW Enable of Peripheral Channel Posted Rx Abort

11 RW Enable of Peripheral Channel Non-Posted Tx Error

10 RW Enable of Peripheral Channel Posted Tx Error

9 RW Enable of Virtual Wire GPIO Event

8 RW Enable of Virtual Wire System Event

7 RW Enable of Flash Channel Tx Complete

6 RW Enable of Flash Channel Rx Complete

5 RW Enable of OOB Channel Tx Complete

4 RW Enable of OOB Channel Rx Complete

3 RW Enable of Peripheral Channel Non-Posted Tx Complete

2 R Reserved

1 RW Enable of Peripheral Channel Posted Tx Complete

0 RW Enable of Peripheral Channel Posted Rx Complete

开启以上红色标记的中断。

************

5.2.4 驱动收尾阶段

ast_espi_boot_ack(espi_dev);

设置Suspend Ack应答和Slave BootDone应答。

platform_set_drvdata(pdev,espi_dev);

将espi_dev堆内存的指针赋值给pdev。pdev即为& ast_espi_device。espi驱动掌握着这段数据的使用权,其他驱动无权访问,直到驱动被卸载(如果可以卸载)。

5.3 ast_espi_isr中断处理流程

中断处理流程会检查三个AST_ESPI_ISR寄存器的三个状态。

5.3.1 ESPI_ISR_HW_RESET(bit31)

31 RWHardware Reset Event

Setwhen Hardware Reset de-asserted.

Write1 Clear

顾名思义,这个状态位是硬件复位事件发生的状态。

5.3.2 ESPI_ISR_VIRTW_SYS(bit8)

8 RWVirtual Wire System Event

Setwhen System Event from Master is trigged.

Write1 Clear  

这个状态位是主机侧系统事件被触发。

5.3.3 ESPI_ISR_VIRTW_SYS1(bit22)

22 RWVirtual Wire System Event 1

Setwhen System Event 1 from Master is trigged.

Write1 Clear

此状态位是主机侧系统事件1被触发。

5.3.4 处理框图

AST_ESPI_ISR寄存器的bit状态。

aspeed BMC AST2500处理器ESPI驱动分析_第1张图片

 

                                                  


     aspeed BMC AST2500处理器ESPI驱动分析_第2张图片

6 业务处理

目前没有找到处理业务的代码。

[附录]

Inside tools

下面是我們的espi driver的debug recipe,請善加利用,感謝

/usr/bin/dbgrecipe.shstart driver espi -t 3 -f 8 -k 1 -p console

[参考文献]

1.      ast2500v131.pdf

2.      http://blog.csdn.net/skyflying2012/article/details/8672011

 

你可能感兴趣的:(linux内核)