IO_ADDRESS()的實現

上面我們說了如何去在系統中自己實現一個設置系統寄存器的一個方法,上面歸根到底要進行物理地址到虛擬地址的映射
現在我們就說說IO_ADDRESS()的實現

#define __REG32ALI(addr)  (*((volatile unsigned long *)((addr) - ALI_REGS_PHYS_BASE + ALI_REGS_VIRT_BASE))
#define readl(IO_ADDRWSS(addr))    (*(volatile unsigned int *)(addr))

兩個宏的功能都是一樣的,所以對比可得:

IO_ADDRESS(addr)  <==>  (addr) - ALI_REGS_PHYS_BASE + ALI_REGS_VIRT_BASE

其中的addr都是物理地址,ALI_REGS_PHYS_BASE是System IO基地址,(addr) - ALI_REGS_PHYS_BASE
就能得到偏移的地址,ALI_REGS_VIRT_BASE是虛擬地址的基地址,這裏的虛擬地址其實是DRAM裏面的地
址,即我們要操作他映射到DRAM裏面的地址,我們看看ALI_REGS_VIRT_BASE的定義:

#define ALI_REGS_PHYS_BASE             	PHYS_SYSTEM 
#define ALI_REGS_VIRT_BASE             	VIRT_SYSTEM 
#define VMALLOC_END      0xfffffffff
#define SIZE_ALIIO		0x60000
#define VIRT_SYSTEM      (VMALLOC_END - SIZE_ALIIO)

可以看出虛擬地址的基地址是人爲劃分出的,是VMALLOC_END - SIZE_ALIIO得到的,
VMALLOC_END是cpu address mapping中給虛擬地址的內核空間劃分出的地址區間的末端地址,這個末端地址根據不同cpu的不同而有所不同,SIZE_ALIIO爲可以使用的空間大小
這個宏只是一個工具,是操作靜態映射後的宏的一種做法,在使用該宏前,必須已經對該IO地址所在的地址範圍做了靜態映射,即machine中對函數map_io中註冊一下靜態映射表,讓系統可以知道這種映射關係,否則系統根據算出的虛擬地址是訪問不到物理地址的,會出現異常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章