- 论坛徽章:
- 0
|
LPC3250 IO空间图
![]()
机器描述 在board-smartarm3250.c中实现:
MACHINE_START (LPC3XXX, "SmartARM3250 board with the LPC3250 Microcontroller") /* Maintainer: Kevin Wells, NXP Semiconductors */ .phys_io = UART5_BASE, .io_pg_offst = ((io_p2v (UART5_BASE))>>18) & 0xfffc, .boot_params = 0x80000100, .map_io = lpc32xx_map_io, //CPU IO映射入口 .init_irq = lpc32xx_init_irq, .timer = &lpc32xx_timer, .init_machine = smartarm3250_board_init,MACHINE_END
IO映射实现 LPC3250移植代码对已经安排了外设的片内IO空间进行了映射,包括IRAM、AHB总线上的外设、FAB和APB总线上的外设。在arch-lpc32xx.c中实现:
static struct map_desc lpc32xx_io_desc[] __initdata = {{ //AHB0总线空间IO映射 .virtual = io_p2v(AHB0_START), .pfn = __phys_to_pfn(AHB0_START), .length = AHB0_SIZE, .type = MT_DEVICE},{ //AHB1总线空间IO映射 .virtual = io_p2v(AHB1_START), .pfn = __phys_to_pfn(AHB1_START), .length = AHB1_SIZE, .type = MT_DEVICE},{ //FAB和APB总线空间IO映射 .virtual = io_p2v(FABAPB_START), .pfn = __phys_to_pfn(FABAPB_START), .length = FABAPB_SIZE, .type = MT_DEVICE},{ //IRAM空间IO映射 .virtual = io_p2v(IRAM_BASE), .pfn = __phys_to_pfn(IRAM_BASE), .length = (SZ_64K * 4), .type = MT_DEVICE},};
void __init lpc32xx_map_io(void){ iotable_init (lpc32xx_io_desc, ARRAY_SIZE (lpc32xx_io_desc));}
涉及到的宏定义在
platform.h
文件中定义所使用的宏定义。以AHB0为例:/* * AHB 0 physical base addresses */
#define SLC_BASE 0x20020000#define SSP0_BASE 0x20084000#define SPI1_BASE 0x20088000#define SSP1_BASE 0x2008C000#define SPI2_BASE 0x20090000#define I2S0_BASE 0x20094000#define SD_BASE 0x20098000#define I2S1_BASE 0x2009C000#define MLC_BASE 0x200A8000
#define AHB0_START SLC_BASE#define AHB0_SIZE ((MLC_BASE - SLC_BASE) + SZ_4K)
延伸阅读 添加用户的特定IO映射 如果要用户外扩了设备,需要添加IO映射,可以修改.map_io为用户自定义io_map函数,在自定义io_map函数中调用CPU的io_map函数。下面是基于PXA270的mainstone系统。
首先声明一个map_desc结构,然后在自定义io_map函数中调用iotable_init函数对用户空间映射进行初始化:
610 static struct map_desc mainstone_io_desc[] __initdata = { 611 { /* CPLD */ 612 .virtual = MST_FPGA_VIRT, 613 .pfn = __phys_to_pfn(MST_FPGA_PHYS), 614 .length = 0x00100000, 615 .type = MT_DEVICE 616 } 617 }; 618 619 static void __init mainstone_map_io(void) 620 { 621 pxa_map_io(); 622 iotable_init(mainstone_io_desc, ARRAY_SIZE(mainstone_io_desc)); 623 624 /* for use I SRAM as framebuffer. */ 625 PSLR |= 0xF04; 626 PCFR = 0x66; 627 } 628 629 MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") 630 /* Maintainer: MontaVista Software Inc. */ 631 .phys_io = 0x40000000, 632 .boot_params = 0xa0000100, /* BLOB boot parameter setting */ 633 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 634 .map_io = mainstone_map_io, //IO空间映射 635 .init_irq = mainstone_init_irq, 636 .timer = &pxa_timer, 637 .init_machine = mainstone_init, 638 MACHINE_END _phys_to_pfn _phys_to_pfn在arch/arm/include/asm/memory.h文件中定义: 120 /* 121 * Convert a physical address to a Page Frame Number and back 122 */ 123 #define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT) 124 #define __pfn_to_phys(pfn) ((pfn)
而下面这是LPC3250的io_p2v实现:
/* Start of virtual addresses for IO devices */#define IO_BASE 0xF0000000
#define io_p2v(x) (IO_BASE | (((x) & 0xff000000) >> 4) | ((x) & 0x000fffff))#define io_v2p(x) ((((x) & 0x0ff00000)
PAGE_SHIFT 见arch/arm/include/asm/page.h文件: 13 /* PAGE_SHIFT determines the page size */ 14 #define PAGE_SHIFT 12 15 #define PAGE_SIZE (1UL 16 #define PAGE_MASK (~(PAGE_SIZE-1))
io_p2v 每个处理器都有自己的io_p2v实现,下面是PXA270处理器的,见arch/arm/mach-pxa/include/mach/hardware.h文件: 28 /* 29 * Intel PXA2xx internal register mapping: 30 * 31 * 0x40000000 - 0x41ffffff 0xf2000000 - 0xf3ffffff 32 * 0x44000000 - 0x45ffffff 0xf4000000 - 0xf5ffffff 33 * 0x48000000 - 0x49ffffff 0xf6000000 - 0xf7ffffff 34 * 0x4c000000 - 0x4dffffff 0xf8000000 - 0xf9ffffff 35 * 0x50000000 - 0x51ffffff 0xfa000000 - 0xfbffffff 36 * 0x54000000 - 0x55ffffff 0xfc000000 - 0xfdffffff 37 * 0x58000000 - 0x59ffffff 0xfe000000 - 0xffffffff 38 * 39 * Note that not all PXA2xx chips implement all those addresses, and the 40 * kernel only maps the minimum needed range of this mapping. 41 */ 42 #define io_p2v(x) (0xf2000000 + ((x) & 0x01ffffff) + (((x) & 0x1c000000) >> 1)) 43 #define io_v2p(x) (0x3c000000 + ((x) & 0x01ffffff) + (((x) & 0x0e000000)
添加外扩设备寄存器 18 #define MST_FPGA_PHYS PXA_CS2_PHYS 19 #define MST_FPGA_VIRT (0xf0000000) 20 #define MST_P2V(x) ((x) - MST_FPGA_PHYS + MST_FPGA_VIRT) 21 #define MST_V2P(x) ((x) - MST_FPGA_VIRT + MST_FPGA_PHYS) 22 23 #ifndef __ASSEMBLY__ 24 # define __MST_REG(x) (*((volatile unsigned long *)MST_P2V(x))) 25 #else 26 # define __MST_REG(x) MST_P2V(x) 27 #endif 28 29 /* board level registers in the FPGA */ 30 31 #define MST_LEDDAT1 __MST_REG(0x08000010) 32 #define MST_LEDDAT2 __MST_REG(0x08000014) 33 #define MST_LEDCTRL __MST_REG(0x08000040) 34 #define MST_GPSWR __MST_REG(0x08000060) 35 #define MST_MSCWR1 __MST_REG(0x08000080) 36 #define MST_MSCWR2 __MST_REG(0x08000084) 37 #define MST_MSCWR3 __MST_REG(0x08000088) 38 #define MST_MSCRD __MST_REG(0x08000090) 39 #define MST_INTMSKENA __MST_REG(0x080000c0) 40 #define MST_INTSETCLR __MST_REG(0x080000d0) 41 #define MST_PCMCIA0 __MST_REG(0x080000e0) 42 #define MST_PCMCIA1 __MST_REG(0x080000e4)
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/51797/showart_2070464.html |
|