- 这里讲述了,但是描述的不太清晰,本文分几个概念来讲述
arm & x86
x86 有 I/O端口(有load store 指令)与I/O内存(没有inb outb 指令) 的概念
x86 可以只有 IO内存
x86 可以 有 两个 : IO内存 和 IO端口
arm 只有 IO内存(有load store 指令)的概念,没有I/O端口(没有inb outb 指令) 的概念
arm-linux & x86-linux
------------------------------
x86-linux 有 I/O端口与I/O内存的概念
iowrite32(xx,xx) 函数 中调用了store 指令
outl(xx,xx) 函数中调用了 iol 指令
arm-linux 有 IO端口的概念,有I/O内存的概念
iowrite32(xx,xx) 函数 中调用了 store 指令
outl(xx,xx) 函数中调用了 iowrite32(xx,xx),最终还是调用了 store 指令
为什么arm-linux 要 有 ioports
因为 arm 要用 PCIe
PCIe 设备中有的 BAR 支持 ioport ,所以我们就要支持
支持PCIe 其实也不需要构造ioport , 但是为了易于分辨,我们就构造出了 ioport
实际上这个还是一块内存,还是用load,store 访问,但是到了pcie总线的时候,会转换为iord 和 iowr
在arm中,只有pcie控制器驱动会添加ioport资源
devm_of_pci_get_host_bridge_resources 的时候,会注册
1. iomem 资源
2. ioports 资源
3. bus 资源
linux ioport & linux iomem 的本质
#define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name), 0)
#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), 0)
struct resource ioport_resource = {
.name = "PCI IO",
.start = 0,
.end = IO_SPACE_LIMIT,
.flags = IORESOURCE_IO,
};
EXPORT_SYMBOL(ioport_resource);
struct resource iomem_resource = {
.name = "PCI mem",
.start = 0,
.end = -1,
.flags = IORESOURCE_MEM,
};
EXPORT_SYMBOL(iomem_resource);
static const struct seq_operations resource_op = {
.start = r_start,
.next = r_next,
.stop = r_stop,
.show = r_show,
};
__initcall(ioresources_init);
ioresources_init
proc_create_seq_data("ioports", 0, NULL, &resource_op, &ioport_resource); /proc/ioports
proc_create_seq_data("iomem", 0, NULL, &resource_op, &iomem_resource); /proc/iomem
cat /proc/ioports 的时候, 会利用 r_next 遍历 ioport_resource 下的 resource , 调用 r_show 打印出 resource 信息
cat /proc/iomem 同理
不同层级的request_region API
level 1 :request_mem_region
level 2 :devm_request_mem_region
level 1 : request_region
level 2 : devm_request_region
其他API
level 1 : ioremap
level 2 : devm_ioremap
#include <asm/io.h>
unsigned int ioread8(void *addr);
unsigned int ioread16(void *addr);
unsigned int ioread32(void *addr);
void iowrite8(u8 value, void *addr);
void iowrite16(u16 value, void *addr);
void iowrite32(u32 value, void *addr);
void ioread8_rep(void *addr, void *buf, unsigned long count);
void ioread16_rep(void *addr, void *buf, unsigned long count);
void ioread32_rep(void *addr, void *buf, unsigned long count);
void iowrite8_rep(void *addr, const void *buf, unsigned long count);
void iowrite16_rep(void *addr, const void *buf, unsigned long count);
void iowrite32_rep(void *addr, const void *buf, unsigned long count);
- Why iomem_resource 's name is “PCI mem”?
https:
Q: just want to check with you usage of request_mem_region for noPCI devices.
kernel/resource.c suggests that it should be used just for PCI iomem
(iomem_resource uses name PCI mem).
If I grep architectures I see several usage for noPCI devices.
Does it mean that request_mem_region should be used for all devices
which request io memory? Or just for PCI iomem?
A:
It's meant for all types of memory mapped I/O.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)