Tuesday, 15 March 2011

linux kernel - ARM: May I do direct memory accesses to a range returned by ioremap_nocache() [without using ioread*()/iowrite*()]? -


I am using a TI AM3358 SOC running an ARM Cortex-A8 processor, which runs Linux 3.12 is. I have enabled a child device of the GPMC node in the device tree, which checks my driver, and there I provided the device tree node to get an unwanted area of ​​ ioremap_nocache () Calling with the resource I got. / P>

The reason for this is that I am not asking for any cash, that it is not a real memory device connected to a GPMC bus, which will definitely benefit from the processor cache, but an FPGA device. Therefore it is necessary to always go through the actual wires.

When I do this:

  u16 __iomem * addr = ioremap_nocache (...); Iowrite16 (1, and eder [0]); Iowrite16 (1, and Eder [1]); IORIT 16 (1, End And [2]); Iowrite16 (1, and Eder [3]); Ioread16 (& amp; addr [0]); Ioread16 (& amp; addr [1]); Ioread16 (& amp; addr [2]); Ioread16 (& amp; addr [3]);  

I think 8 access is done on the wires using a logic analyzer. However, when I do this:

  u16 v; Editor [0] = 1; Edit [1] = 1; ADR [2] = 1; Copula [3] = 1; V = addr [0]; V = Eder [1]; V = Eder [2]; V = addr [3];  

I look at the four writing accesses, but there is no access to reading later.

Am I missing something? Knowing the difference between ioread16 () and a direct memory access, knowing that the GPMC range is completely similar to memory?

Could this behavior be the result of any compiler optimization that can be avoided? I have not seen the guidelines that have come so far, but by then, maybe something interesting is enough to give someone enough answers to be experienced.

ioread * () and iowrite * () , at ARM, after blocking a data storage, unstable access, e.g. :

  #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 );) Written in #define (v, c) ({__iowmb (); writew_relaxed (v, c);}) #define writel (v, c) ({__iowmb (); writel_relaxed (v, c) ;})  

__ Raw _read * () and __ raw_write * () (where * The b , w , or L ) can be used to read / write directly to the exact instructions necessary for those tasks. Do the address indicator a variable For casting, do castings. Examples (store register, half word):

  #define __raw_writew __raw_writew static inline zero __raw_writew (u16 val, unstable) Zero __iomem * ADR) {ASM WaterLeil ("SBR% 1,% 0": "+ Q" (* (fluctuations, 16 __forbs *) edit): "R" (val)); }  

Be careful that these two functions do not contain any constraints, so you should read rmb () (read the memory barrier) and Wmb () (type memory block) anywhere you want your memory to be accessed.


No comments:

Post a Comment