海思物理地址和虚拟地址映射IO_ADDRESS、 ioremap和ioremap_nocache

1.函数原型

ioremap - 将一个IO地址空间映射到内核的虚拟地址空间上去

void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)

入口: phys_addr:要映射的起始的IO地址;

size:要映射的空间的大小;

flags:要映射的IO空间的和权限有关的标志;

 

void *ioremap(unsigned long phys_addr, unsigned long size)

phys_addr:是要映射的物理地址

size:是要映射的长度,单位是字节

头文件:io.h

ioremap 依靠 __ioremap实现,它只是在__ioremap中以第三个参数为0调用来实现.

ioremap是内核提供的用来映射外设寄存器到主存的函数:举个例子,比如某个驱动设备有100 个寄存器,他们都是连在一块的,位置是固定的,假如每个寄存器占4个字节,那么一共400个字节的空间被映射到内存成功后,ioaddr就是这段地址的开头(注意ioaddr是虚拟地址,而mmio_start是物理地址,它是BIOS得到的,肯定是物理地址,而保护模式下CPU不认物理地址,只认虚拟地址),ioaddr+0就是第一个寄存器的地址,ioaddr+4就是第二个寄存器地址(每个寄存器占4个字节),以此类推。

ioremap_nocache - 把内存映射到CPU空间

void __iomem * ioremap_nocache (unsigned long phys_addr, unsigned longsize);  

phys_addr:要映射的物理地址 

size:要映射资源的大小 

ioremap_nocache进行一系列平台相关的操作使得CPU可以通过readb/readw/readl/writeb/writew/writel等IO函数进行访问。
注:返回的地址不保证可以作为虚拟地址直接访问。

调用ioremap_nocache()函数之后,返回一个线性地址,此时CPU 可以访问设备的内存(已经将其映射到了线性地址空间中了),此时CPU可以使用访问内存的指令访问设备的内存空间(host bridge 判断访问物理内存还是设备中的内存),此时我们就可以像访问内存一样来访问设备的内存(寄存器)。

2.函数实例

#define GPIO_3_BASE 					  0x045F3000
#define SCL_SHIFT_NUM   			   2
#define SDA_SHIFT_NUM   			  3
#define SCL                 					  (0x1 << SCL_SHIFT_NUM)    /* GPIO3_2 */
#define SDA                						 (0x1 << SDA_SHIFT_NUM)    /* GPIO3_3 */


void __iomem * reg_i2c_base_va = NULL;

#define HI_IO_ADDRESS(x) (reg_i2c_base_va + ((x)-(GPIO_3_BASE)))

#define GPIO_I2C_SCL_REG    		  HI_IO_ADDRESS(GPIO_3_BASE + (0x1<<(SCL_SHIFT_NUM+2)))  /* 0x010 */
#define GPIO_I2C_SDA_REG   			 HI_IO_ADDRESS(GPIO_3_BASE + (0x1<<(SDA_SHIFT_NUM+2)))  /* 0x020 */
#define GPIO_I2C_SCLSDA_REG 	  HI_IO_ADDRESS(GPIO_3_BASE + ((0x1<<(SCL_SHIFT_NUM+2))+(0x1<<(SDA_SHIFT_NUM+2))))  /* 0x300 need check */
#define  GPIO_3_DIR   					   HI_IO_ADDRESS(GPIO_3_BASE + 0x400)	



#define HW_REG(reg)         			*((volatile unsigned int *)(reg))
#define DELAY(us)           				time_delay_us(us)


static int __init gpio_i2c_init(void)
{
    
	reg_i2c_base_va=ioremap(GPIO_3_BASE, 0x1000);
	
	if(!reg_i2c_base_va)
	{
	    printk("ioremap gpio group0 failed!\n");
	    return -1;
	}


    return 0;    
}

static void __exit gpio_i2c_exit(void)
{
	iounmap((void*)reg_i2c_base_va);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值