mini2440的IO内存映射是在函数mini2440_map_io()函数中的s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc));我们发现mini2440_iodesc是一个空的。static struct map_desc mini2440_iodesc[] __initdata = {
};
那么怎么映射呢。
struct map_desc {
unsigned long virtual;
unsigned long pfn;
unsigned long length;
unsigned int type;
};
void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
{
unsigned long idcode = 0x0;
iotable_init(mach_desc, size);
iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
if (cpu_architecture() >= CPU_ARCH_ARMv5) {
idcode = s3c24xx_read_idcode_v5();
} else {
idcode = s3c24xx_read_idcode_v4();
}
arm_pm_restart = s3c24xx_pm_restart;
s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
}
s3c24xx_init_io()函数里面iotable_init(mach_desc, size)并映射什么。实际的映射在iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
下面看s3c_iodesc是怎么定义的。
static struct map_desc s3c_iodesc[] __initdata = {
IODESC_ENT(GPIO),
IODESC_ENT(IRQ),
IODESC_ENT(MEMCTRL),
IODESC_ENT(UART)
};
IODESC_ENT()宏定义:
#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
所以我们可以得到展开的s3c_iodesc[]
static struct map_desc s3c_iodesc[] __initdata = {
{
unsigned long S3C24XX_VA_GPIO,
__phys_to_pfn(S3C24XX_PA_GPIO),
S3C24XX_SZ_GPIO,
MT_DEVICE
},
{
unsigned long S3C24XX_VA_IRQ,
__phys_to_pfn(S3C24XX_PA_IRQ),
S3C24XX_SZ_IRQ,
MT_DEVICE
},
{
unsigned long S3C24XX_VA_MENCTRL,
__phys_to_pfn(S3C24XX_PA_MENCTRL),
S3C24XX_SZ_MENCTRL,
MT_DEVICE
},
{
unsigned long S3C24XX_VA_UART,
__phys_to_pfn(S3C24XX_PA_UART),
S3C24XX_SZ_UART,
MT_DEVICE
}
};
我们可以找到S3C24XX_VA_GPIO,S3C24XX_PA_GPIO...可以在/* linux/include/asm-arm/plat-s3c24xx/map.h找到他的定义。
我们看看GPIO