Memory type assigned for mmap() of Zynq OCM

Discussion about U-Boot and the kernel.

Memory type assigned for mmap() of Zynq OCM

Postby satether » Fri Aug 01, 2014 7:35 pm

What MMU memory attributes are assigned to memory mapped using mmap() on /dev/mem: normal, device, strongly-ordered, shared, unshared, etc? My group at SLAC wants to put mutexes in the Zynq On-Chip Memory and update them using LDREX and STREX. We have a version of this that works under the real-time OS RTEMS in which we map the OCM as shared, normal, cached memory and we'd like to get the same attributes assigned under ArchLinux ARM. At the moment, we use mmap() on /dev/mem to get access to the OCM. Regular loads and stores work but STREX instructions always report a failure to store. We suspect that the problem is that the OCM is not mapped as normal memory but how can we find out for certain?

- Steve Tether
satether
 
Posts: 2
Joined: Fri Aug 01, 2014 6:19 pm

Re: Memory type assigned for mmap() of Zynq OCM

Postby satether » Mon Aug 11, 2014 12:53 am

A mapping created using /dev/mem will be uncached if it's above the top of RAM, not what we want. We had to write a driver for our own device /dev/ocm. LDREX/STREX work properly on a mapping constructed like this:
$this->bbcode_second_pass_code('', '
#define OCM_PHYSADDR 0xfffc0000UL
#define OCM_SIZE 65536UL

/* Protection bits we don't want to meddle with. */
#define PROTECTION_MASK (L_PTE_VALID | L_PTE_DIRTY | L_PTE_USER)

/* This mmap() implementation ignores the offset and flags arguments;
it always starts a shared mapping at the beginning of the OCM. The
user will still have to use the right size argument because the OS
uses it to determine how large a virtual address range to allocate
for the user's process, and that happens before this function is
called. Private mappings aren't allowed; silly COW. */
static int devocm_mmap(struct file *filp, struct vm_area_struct *vma) {
unsigned long const size = vma->vm_end - vma->vm_start;
if (size != OCM_SIZE) {
printk(KERN_WARNING "Invalid OCM size given to mmap().\n");
return -EINVAL;
}
vma->vm_page_prot = (vma->vm_page_prot & PROTECTION_MASK) | L_PTE_MT_WRITEALLOC | L_PTE_XN | L_PTE_SHARED;
if(remap_pfn_range(vma, vma->vm_start, OCM_PHYSADDR >> PAGE_SHIFT, OCM_SIZE, vma->vm_page_prot)) {
printk(KERN_WARNING "remap_pfn_range() failed for OCM.\n");
return -EAGAIN;
}
return 0;
}
')
Last edited by WarheadsSE on Mon Aug 11, 2014 12:59 am, edited 1 time in total.
Reason: Added code tags for you :)
satether
 
Posts: 2
Joined: Fri Aug 01, 2014 6:19 pm

Re: Memory type assigned for mmap() of Zynq OCM

Postby WarheadsSE » Mon Aug 11, 2014 12:58 am

Oh, good. SLAC is only using us for data acquisition, not controls. PHEW :lol:
Core Developer
Remember: Arch Linux ARM is entirely community donation supported!
WarheadsSE
Developer
 
Posts: 6807
Joined: Mon Oct 18, 2010 2:12 pm


Return to U-Boot/Kernel

Who is online

Users browsing this forum: No registered users and 5 guests