The difference between Ioremap and ioremap_cachable in Linux (MIPS architecture) __linux

Source: Internet
Author: User
The difference between Ioremap and ioremap_cachable in Linux (MIPS architecture)

In Arch/mips/include/asm/io.h
/*
* Ioremap-map bus memory to CPU space
* @offset: Bus address of the memory
* @size: Size of the resource to map
*
* Ioremap performs a platform specific sequence of operations to
* Make bus memory CPU accessible via the readb/readw/readl/writeb/
* Writew/writel functions and the other Mmio helpers. The returned
* Address isn't guaranteed to usable directly as a virtual
* Address.
*/
#define IOREMAP (offset, size) \
__ioremap_mode (offset), (size), _cache_uncached)

/*
* Ioremap_cachable-map bus memory to CPU space
* @offset: Bus address of the memory
* @size: Size of the resource to map
*
* Ioremap_nocache performs a platform specific sequence of operations to
* Make bus memory CPU accessible via the readb/readw/readl/writeb/
* Writew/writel functions and the other Mmio helpers. The returned
* Address isn't guaranteed to usable directly as a virtual
* Address.
*
* This version of Ioremap ensures that the memory was marked cachable by
* The CPU.  Also enables full write-combining. Useful for some
* Memory-like regions on I/O busses.
*/
#define IOREMAP_CACHABLE (offset, size) \
__ioremap_mode (offset), (size), _page_cachable_default)
#define IOREMAP_CACHED (offset, size) ioremap_cachable (offset, size)


static inline void __iomem * __ioremap_mode (phys_t offset, unsigned long size,
unsigned long flags)
{
void __iomem *addr = plat_ioremap (offset, size, flags);

if (addr)
return addr;

#define __IS_LOW512 (Addr) ( (phys_t) (addr) & (phys_t) ~0x1fffffffull))

if (cpu_has_64bit_addresses) {
U64 base = Uncac_base;

/*
* R10000 supports a 2 bit uncached attribute therefore
* Uncac_base may not equal io_base.
*/
if (flags = = _cache_uncached)
Base = (u64) io_base;
return (void __iomem *) (unsigned long) (base + offset);
else if (__builtin_constant_p (offset) &&
__builtin_constant_p (size) && __builtin_constant_p (flags)) {
phys_t phys_addr, last_addr;

PHYS_ADDR = fixup_bigphys_addr (offset, size);

/* Don ' t allow wraparound or zero size. */
LAST_ADDR = phys_addr + size-1;
if (!size | | last_addr < PHYS_ADDR)
return NULL;

/*
* Map uncached objects in 512MB of
* Space using KSEG1.
*/
if (__is_low512 (phys_addr) && __is_low512 (last_addr) &&
Flags = = _cache_uncached)
return (void __iomem *)
(unsigned long) CKSEG1ADDR (PHYS_ADDR);
}

return __ioremap (offset, size, flags);

#undef __is_low512
}

where the __builtin_constant_p (x) effect is used to determine whether a value is constant at compile time (using to determine whether a value is a constant at compile-time).
True if x can get a constant value at compile time, or false if it is a variable

In the ARCH/MIPS/MM/IOREMAP.C:
/*
* Remap an arbitrary physical address spaces into the kernel virtual
* Address spaces. Needed the kernel wants to access high addresses
* directly.
*
* note! We need to allow non-page-aligned mappings Too:we'll obviously
* Have to convert them into an offset in a page-aligned mapping, but the
* Caller shouldn ' t need to know that small detail.
*/
void __iomem * __IOREMAP (phys_t phys_addr, phys_t size, unsigned long flags)
{
...
}
The following text is transferred from http://blog.csdn.net/bing_bing/article/details/5774294

void * __IOREMAP (unsigned long phys_addr, unsigned long size, unsigned long flags)
Entrance: phys_addr: The initial IO address to map;

Size: The amount of space to map;

Flags: To map the IO space and the permissions associated with the flags;

Function: To map an IO address space to the virtual address space of the kernel for easy access;

Implementation: To determine the IO address space to map, the low Pci/isa address does not need to remap, also does not allow users to map the IO address space to the RAM in use, and finally apply for a VM_AREA_STRUCT structure, call Remap_area_pages fill out the page table, If the completion process is unsuccessful, release the application vm_area_struct space;

Significance:
For example, ISA device and PCI device, or FB, the hardware jumper or physical connection determines the CPU physical address the memory on the hardware is alluding to.
Access to these addresses in the kernel must be allocated to the memory to the virtual address, which is exactly what __ioremap is, and it is important to note that the physical memory has "existed" without alloc page to this address.

The comments in the file are also more detailed and expose only the __ioremap,iounmap two functions for other modules
Block invocation, the function remap_area_pte,remap_area_pmd,remap_area_pages is used only for __ioremap.

--------
In order for the software to access I/O memory, the device must be assigned a virtual address. This is Ioremap's job. This function is designed to assign virtual addresses (spaces) to the I/O memory area. Ioremap does nothing for the directly mapped I/O address. With Ioremap (and Iounmap), the device can access any I/O memory space, regardless of whether it maps directly to the virtual address space. However, these addresses can never be used directly (referring to physical addresses) and use the READB function.

Depending on the computer platform and the bus used, I/O memory may or may not be accessed through a page table, which is accessed through a page table as a unified address (PowerPC), otherwise it is a stand-alone address (Intel). If the access is done through the page table, the kernel must first schedule the physical address to be visible to the device driver (which usually means that ioremap must be invoked before any I/O is done). If you do not need a page table, I/O memory regions are much like I/O ports and can be read and written to them using the appropriate form of functions.

The direct use of pointers to I/O memory is discouraged, regardless of the need to invoke ioremap when accessing I/O memory. Although (described in "I/O ports and I/OS memory") I/O memory is addressed as normal RAM at the hardware level, it is recommended that you do not use normal pointers in cases that require extra care described in "I/O registers and conventional memory." Instead, using the wrapped function to access I/O memory is secure on all platforms and, on the other hand, is optimized when you can perform an operation directly on the memory area to which the pointer points.

-------
I originally thought that when the storage space on the video card was assigned a bus address a, the corresponding virtual space was determined. That's a+3g. But in fact, the implementation in the Ioremap.c file is not the case. The function used is __ioremap (unsigned long PHYS_ADDR, unsigned long, unsigned long flags, is implemented to assign a virtual address to a physical address that starts at a size from phys_addr. Notice here is the assignment, Instead of specifying. I think the assignment should be to specify that the corresponding virtual address according to Phys_addr is phys_addr+3g. I think a reasonable explanation is this: the address space on the mapped non-IO card in the system virtual space satisfies the 3G difference, and the memory space on the IO card is not satisfied. Welcome to the discussion

Under the X86 system, the physical address of the CPU and the PCI bus address share a space. The Linux kernel maps 3g-4g virtual addresses to the 0-1g locations of physical addresses. However, if the address on the peripheral is above 1G, for example, a PCI card is assigned to an address above 1G, you need to call Ioremap to re-establish the mapping between the physical address (bus address) and the virtual address. This mapping process is as follows: In the __ioremap function of the ioremap.c file, the physical address of the future map is first checked, that is, the 640k-1m address cannot be remap (for historical reasons, the physical address 640k to 1M space is reserved to the graphics card), Normal RAM can not be mapped again. Then call Get_vm_area to obtain the available virtual address, then the root of the virtual address and the physical address to map to modify the page table, then the kernel can use this virtual address to access the mapped physical address.

Http://bbs.chinaunix.net/thread-3554853-1-1.html

What situation with cacheable, under what circumstances must non-cacheable.

The CPU can help you maintain good RAM consistency, that is, the CPU or DMA the RAM when the other will know and make the appropriate action, then use Cachable, because the performance is good.
CPU and DMA each tube of each, that is non-cachable, because saves toss.

The for x86 should be cachable because the architecture has guaranteed consistency

I think this is not a question of consistency. Ioremap's memory are written directly to device in order of instruction.
If it's cacheable, suppose we
Write REG1
Write REG2
If it is cacheable, the value will be cache in the CPU cache, the two values written to the memeory order is uncertain.
Cache consistency only guarantees the consistency of the values in the cache and memory, x86 is guaranteed by hardware. If the value in the cache is new, the memory is old. So the other CPU, or device want access to the value of the memory, then cache consistency ensures that they will be unique to the latest value.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.