MACHINE_START(S3C2440, "SMDK2440")
/* Maintainer: Ben Dooks <ben@fluff.org> */
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
.map_io = smdk2440_map_io,
.init_machine = smdk2440_machine_init,
.timer = &s3c24xx_timer,
MACHINE_END
之前的启动代码分析中发现, map_io 的作用主要是做物理地址到虚拟地址的静态映射,所以
smdk2440_map_io 被很早的调用了
static void __init smdk2440_map_io(void)
{
s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
s3c24xx_init_clocks(16934400);
s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
}
发现,这调用了 24xx 系列的通用函数,smdk2440_iodesc 给了一个板级的映射接口
方便添加需要的映射,其他就是初始化时钟和uart口。
iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
/* minimal IO mapping */
static struct map_desc s3c_iodesc[] __initdata = {
IODESC_ENT(GPIO),
IODESC_ENT(IRQ),
IODESC_ENT(MEMCTRL),
IODESC_ENT(UART)
};
#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x),
S3C24XX_SZ_##x, MT_DEVICE }
可以看出,这些IO是最小化必须被映射的,包括
S3C24XX_PA_GPIO 0X56000000
S3C24XX_PA_IRQ 0x4A000000
S3C24XX_PA_MEMCTRL 0X48000000
S3C24XX_PA_UART 0X50000000
接着还需要调用
s3c_init_cpu
cpu->map_io(); 根据不同的CPUID决定,例如调用的是 s3c244x_map_io
void __init s3c244x_map_io(void)
{
/* register our io-tables */
iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
}
其中
static struct map_desc s3c244x_iodesc[] __initdata = {
IODESC_ENT(CLKPWR),
IODESC_ENT(TIMER),
IODESC_ENT(WATCHDOG),
};
S3C24XX_PA_CLKPWR
S3C24XX_PA_TIMER
S3C24XX_PA_WATCHDOG
这些都是一般性的通用函数,例如设置PLL,时钟,看门狗等,是属于基本内容,都必须映射的。
映射函数到此基本完毕,对于没有映射的,可以采用动态的 ioremap形式,或者自己添加静态映射
。
/* Maintainer: Ben Dooks <ben@fluff.org> */
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
.map_io = smdk2440_map_io,
.init_machine = smdk2440_machine_init,
.timer = &s3c24xx_timer,
MACHINE_END
之前的启动代码分析中发现, map_io 的作用主要是做物理地址到虚拟地址的静态映射,所以
smdk2440_map_io 被很早的调用了
static void __init smdk2440_map_io(void)
{
s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
s3c24xx_init_clocks(16934400);
s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
}
发现,这调用了 24xx 系列的通用函数,smdk2440_iodesc 给了一个板级的映射接口
方便添加需要的映射,其他就是初始化时钟和uart口。
iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
/* minimal IO mapping */
static struct map_desc s3c_iodesc[] __initdata = {
IODESC_ENT(GPIO),
IODESC_ENT(IRQ),
IODESC_ENT(MEMCTRL),
IODESC_ENT(UART)
};
#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x),
S3C24XX_SZ_##x, MT_DEVICE }
可以看出,这些IO是最小化必须被映射的,包括
S3C24XX_PA_GPIO 0X56000000
S3C24XX_PA_IRQ 0x4A000000
S3C24XX_PA_MEMCTRL 0X48000000
S3C24XX_PA_UART 0X50000000
接着还需要调用
s3c_init_cpu
cpu->map_io(); 根据不同的CPUID决定,例如调用的是 s3c244x_map_io
void __init s3c244x_map_io(void)
{
/* register our io-tables */
iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
}
其中
static struct map_desc s3c244x_iodesc[] __initdata = {
IODESC_ENT(CLKPWR),
IODESC_ENT(TIMER),
IODESC_ENT(WATCHDOG),
};
S3C24XX_PA_CLKPWR
S3C24XX_PA_TIMER
S3C24XX_PA_WATCHDOG
这些都是一般性的通用函数,例如设置PLL,时钟,看门狗等,是属于基本内容,都必须映射的。
映射函数到此基本完毕,对于没有映射的,可以采用动态的 ioremap形式,或者自己添加静态映射
。