首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ARM:我可以直接访问ioremap_nocache()返回的范围(而不使用ioread*()/iowrite*())吗?

ARM:我可以直接访问ioremap_nocache()返回的范围(而不使用ioread*()/iowrite*())吗?
EN

Stack Overflow用户
提问于 2015-03-16 18:03:45
回答 1查看 1.5K关注 0票数 2

我正在使用TI AM3358 SoC,运行一个运行Linux3.12的ARM Cortex-A8处理器。我在设备树中启用了GPMC节点的一个子设备,它探测我的驱动程序,在那里,我用设备树节点提供的资源调用ioremap_nocache(),以获得一个未缓存的区域。

我之所以不请求缓存,是因为它不是连接到GPMC总线的实际内存设备,它当然会从处理器缓存中受益,而是一个FPGA设备。因此,访问需要始终通过实际的电线。

当我这么做时:

代码语言:javascript
运行
复制
u16 __iomem *addr = ioremap_nocache(...);

iowrite16(1, &addr[0]);
iowrite16(1, &addr[1]);
iowrite16(1, &addr[2]);
iowrite16(1, &addr[3]);
ioread16(&addr[0]);
ioread16(&addr[1]);
ioread16(&addr[2]);
ioread16(&addr[3]);

我看到这8次访问是用逻辑分析器在电线上完成的。然而,当我这样做时:

代码语言:javascript
运行
复制
u16 v;

addr[0] = 1;
addr[1] = 1;
addr[2] = 1;
addr[3] = 1;
v = addr[0];
v = addr[1];
v = addr[2];
v = addr[3];

我看到了四个写访问,但没有看到后续的读访问。

我是不是遗漏了什么?ioread16()和直接内存访问之间有什么区别,因为它知道整个GPMC范围应该和内存一样是可寻址的?

这种行为是否是可以避免的编译器优化的结果?我还没有看生成的指令,但在那之前,可能有人有足够的经验,有一些有趣的答复。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-24 22:00:08

ioread*()iowrite*()在ARM上执行数据内存屏障,然后执行volatile访问,例如:

代码语言:javascript
运行
复制
#define readb(c)                ({ u8  __v = readb_relaxed(c); __iormb(); __v; })
#define readw(c)                ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
#define readl(c)                ({ u32 __v = readl_relaxed(c); __iormb(); __v; })

#define writeb(v,c)             ({ __iowmb(); writeb_relaxed(v,c); })
#define writew(v,c)             ({ __iowmb(); writew_relaxed(v,c); })
#define writel(v,c)             ({ __iowmb(); writel_relaxed(v,c); })

__raw_read*()__raw_write*() ( *bwl)可用于直接读/写。它们执行这些操作所需的精确的单一指令,将地址指针转换为volatile指针。

__raw_writew()示例(存储寄存器,半字):

代码语言:javascript
运行
复制
#define __raw_writew __raw_writew
static inline void __raw_writew(u16 val, volatile void __iomem *addr)
{
        asm volatile("strh %1, %0"
                     : "+Q" (*(volatile u16 __force *)addr)
                     : "r" (val));
}

但是,请注意,这两个函数没有插入任何障碍,因此您应该在任何您希望对内存访问进行排序的地方调用rmb() (读内存屏障)和wmb() (写内存屏障)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29083876

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档