在GPIO中对其I/O端口虚拟地址的定义:
#define S3C24XX_VA_GPIO S3C2410_ADDR(0x00E00000)
#ifndef __ASSEMBLY__
#define S3C2410_ADDR(x) ((void __iomem *)0xF0000000 + (x))
#else
#define S3C2410_ADDR(x) (0xF0000000 + (x))
#endif
很显然,在2410中,I/O端口虚拟地址VA是由0xF0000000与(X)相加得到(相比于页表映射机制,2410的MMU实在是简单);
而且不同的寄存器偏移值都相差0x100000,比如
#define S3C24XX_VA_RTC S3C2410_ADDR(0x00F00000)
#define S3C24XX_VA_GPIO S3C2410_ADDR(0x00E00000)
#define S3C24XX_VA_IIS S3C2410_ADDR(0x00D00000)
现在得到的是S3C2410_VA_GPIO,即类似于S3C2410_PA_GPIO,前者得到的是I/O端口的起始虚拟地址,而后者是寄存器的起始物理地址。如果想要得到每一组I/O端口的起始虚拟地址,还需要用到以下宏定义:
#define S3C2410_GPIO_BASE(pin) ((((pin) & ~31) >> 1) + S3C24XX_VA_GPIO)
#define S3C2410_GPIO_OFFSET(pin) ((pin) & 31)
由S3C2410_GPIO_BASE(pin)得到的是每一组寄存器I/O端口的起始虚拟地址,例如:GPA为0x00+VA
GPB为0x10+VA, GPC 为0x20+VA等等。然后,通过S3C2410_GPIO_OFFSET(pin)得到每一组内的偏移值,即可得到所有I/O端口的虚拟地址。
举例来说:
pin&1111 1111 1110 0000
pin&0001 1111