一个函数分析(s3c2410_gpio_setpin),浅析ARM IO 内存映射
(这是我转载的一篇博客,不过我自己感觉其中有一点错误,不过按照这个上面的解释,还是有一点理解映射的机制的,呵呵)
目录:
1 S3c2410_gpio_setpin作用以及源码
2 在内核中队部分代码进行深入跟踪
3 ARM的IO内存映射计算及分析
4 一些琐碎的话
1 S3c2410_gpio_setpin作用以及源码
该函数根据传入的参数设这GPIO的数据输出。源码如下
void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
{
void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
unsigned long flags;
unsigned long dat;
local_irq_save(flags);
dat = __raw_readl(base + 0x04);
dat &= ~(1<< offs);
dat |= to << offs;
__raw_writel(dat, base + 0x04);
local_irq_restore(flags);
}
EXPORT_SYMBOL(s3c2410_gpio_setpin);
2 在内核中队部分代码进行深入跟踪
S3C24XX_GPIO_BASE的定义如下
#define S3C24XX_GPIO_BASE(x) S3C2400_GPIO_BASE(x) //这一句我感觉有问题,源码中是这样写的:#ifdef CONFIG_CPU_S3C2400
#define S3C24XX_GPIO_BASE(x) S3C2400_GPIO_BASE(x)
#define S3C24XX_MISCCR S3C2400_MISCCR
#else
#define S3C24XX_GPIO_BASE(x) S3C2410_GPIO_BASE(x)
#define S3C24XX_MISCCR S3C24XX_GPIOREG2(0x80)
#endif /* CONFIG_CPU_S3C2400 */
由于CONFIG_CPU_S3C2400,对于2410和2440,应该是执行#else后面的宏定义的不是么?
我很疑惑,可是再网上都没有关于这方面的解释,所以说我还是按照他上面说的做的。。
#define S3C2400_GPIO_BASE(pin) (pin < S3C2410_GPIO_BANKC ? \
S3C2400_BASEA2B(pin)+S3C24XX_VA_GPIO : \
S3C2400_BASEC2H(pin)+S3C24XX_VA_GPIO)
#define S3C2410_GPIO_BANKC (32*2)
#define S3C2400_BASEA2B(pin) ((((pin) & ~31) >> 2))
#define S3C2400_BASEC2H(pin) ((S3C2400_BANKNUM(pin) * 10) + \
(2 * (S3C2400_BANKNUM(pin)-2)))
#define S3C2400_BANKNUM(pin) (((pin) & ~31) / 32)
#define S3C24XX_VA_GPIO ((S3C24XX_PA_GPIO-S3C24XX_PA_UART)+S3C24XX_VA_UART)
#define S3C24XX_PA_GPIO S3C2410_PA_GPIO
#define S3C2410_PA_GPIO (0x56000000)
#define S3C2410_PA_UART (0x50000000)
#define S3C24XX_VA_UART S3C_VA_UART
#define S3C_VA_UART S3C_ADDR(0x01000000) /* UART */
#ifndef __ASSEMBLY__
#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x))
#else
#define S3C_ADDR(x) (S3C_ADDR_BASE + (x))
#endif
#define S3C_ADDR_BASE (0xF4000000)
以上就是用cscope跟踪内核代码的结果。 |