Find the answer to your Linux question:
Results 1 to 8 of 8
First of all I wasn't entirely sure where to post this so feel free to move this thread. Allright, here goes. I have a Freescale i.MX27 processor. This processor has ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Apr 2010
    Posts
    4

    Memory problems


    First of all I wasn't entirely sure where to post this so feel free to move this thread.

    Allright, here goes. I have a Freescale i.MX27 processor. This processor has a built-in video processor that shares memory with the CPU for configuration and data exchange. The problem lies in accessing the shared configuration registers.

    A userspace library calls a custom mmap implementation of the kernelspace driver.
    The kernel's mmap looks like this:

    Code:
    static int vpu_map_hwregs(struct file *fp, struct vm_area_struct *vm)
    {
    	unsigned long pfn;
    	
    	vm->vm_flags |= VM_IO | VM_RESERVED;
    	vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot);
    	pfn = (MX27_VPU_BASE_ADDR >> PAGE_SHIFT);	
    	
    	__raw_writel(0x1, IO_ADDRESS(MX27_VPU_BASE_ADDR));
    	pr_debug("Going to start testread the PC at address %lx, got value %x \n", 
    			IO_ADDRESS(MX27_VPU_BASE_ADDR) + 0x18, __raw_readl(IO_ADDRESS(MX27_VPU_BASE_ADDR + 0x18))); 
    	
    	__raw_writel(0x0, IO_ADDRESS(MX27_VPU_BASE_ADDR));
    
    	pr_debug("size=0x%x,  page no.=0x%x\n",
    		 (int)(vm->vm_end - vm->vm_start), (int)pfn);
    
    	return remap_pfn_range(vm, vm->vm_start, pfn, (vm->vm_end - vm->vm_start),
    			       vm->vm_page_prot) ? -EAGAIN : 0;
    }
    The reads and writes in this debug code work perfectly.

    The mmap function in userspace:

    Code:
    RetCode vpu_Init(void *cb) {
    ...
    	vpu_reg_base = (unsigned long)mmap(NULL, BIT_REG_MARGIN,
    					   PROT_READ | PROT_WRITE,
    					   MAP_SHARED, vpu_fd, 0);
    
    	VpuReadReg(0x18);
    ...
    }
    
    inline unsigned long *reg_map(unsigned long offset)
    {
    	return (unsigned long *)(offset + (unsigned long)vpu_reg_base);
    }
    
    unsigned long VpuReadReg(unsigned long addr)
    {
    	unsigned long *reg_addr = reg_map(addr);
    	return *(volatile unsigned long *)reg_addr;
    }
    But this code results in:
    Code:
    Unhandled fault: external abort on non-linefetch (0x008) at 0x4001f018
    I've been stuk on this for more then a week now ! I really hope someone here is able to help me!

  2. #2
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    Posts
    11,452
    What is the value of BIT_REG_MARGIN that you are using with mmap() for the pagesize argument? What is the page size of this processor? Also, please show your code for opening the file descriptor vpu_fd. Finally, are you sure the base address is 0?
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  3. #3
    Just Joined!
    Join Date
    Apr 2010
    Posts
    4
    BIT_REG_MARGIN is one page and the page size is 0x1000.

    BIT_REG_MARGIN is declared as:
    Code:
    #define BIT_REG_MARGIN			((size_t) sysconf (_SC_PAGESIZE))
    The code for opening the file discriptor is right before the mmap call:

    Code:
    vpu_fd = open("/dev/mxc_vpu", O_RDWR);
    	if (vpu_fd < 0) {
    		printf("Can't open /dev/mxc_vpu\n");
    		return -1;
    	}
    
    vpu_reg_base = ( …………
    With base address do you mean the offset field I have in the mmap call?
    Yes, the register i'm trying to access starts at MX27_VPU_BASE_ADDR.

    The physical base address of the VPU is 0x10023000.

  4. #4
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    Posts
    11,452
    Quote Originally Posted by raymondvdr View Post
    BIT_REG_MARGIN is one page and the page size is 0x1000.

    BIT_REG_MARGIN is declared as:
    Code:
    #define BIT_REG_MARGIN			((size_t) sysconf (_SC_PAGESIZE))
    The code for opening the file discriptor is right before the mmap call:

    Code:
    vpu_fd = open("/dev/mxc_vpu", O_RDWR);
    	if (vpu_fd < 0) {
    		printf("Can't open /dev/mxc_vpu\n");
    		return -1;
    	}
    
    vpu_reg_base = ( 
    With base address do you mean the offset field I have in the mmap call?
    Yes, the register i'm trying to access starts at MX27_VPU_BASE_ADDR.

    The physical base address of the VPU is 0x10023000.
    Then I suggest you try this:
    Code:
           void* vpu_reg_base = 0;
           off_t vpu_base = 0x10023000;
    	vpu_reg_base = mmap(0, getpagesize(),
    					   PROT_READ | PROT_WRITE,
    					   MAP_SHARED, vpu_fd, vpu_base);
    
    .
    .
    .
    inline unsigned long *reg_map(unsigned long offset)
    {
    	return (unsigned long *)(offset + vpu_reg_base);
    }
    .
    .
    .
    There may be other issues, but this is as far as I have time to review and analyze your code at this point.
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  5. #5
    Just Joined!
    Join Date
    Apr 2010
    Posts
    4
    Really appreciate your help!
    I tried your suggestion but the problem remains the same...

    Code:
    Unhandled fault: external abort on non-linefetch (0x008) at 0x4001f018
    If it helps, I'm using a driver from Freescale found here:
    freescale.com/webapp/sps/site/prod_summary.jsp?code=IMX27_CODECS.
    I've attached the driver and library source files I'm using.
    It looks like the driver was originally built against the 2.6.29 kernel, I'm using the 2.6.33 kernel. Do you know if anything significant change relating to memory that might cause this driver breaking?
    Attached Files Attached Files

  6. #6
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    Posts
    11,452
    There were significant differences between 2.6 kernels starting with the 2.6.30 or 31 version - not sure which honestly. You should be able to find out from The Linux Kernel Archives. That could definitely affect your driver. Sorry, but I really don't have time right now to dig into the driver and code internals. Just got up w/ too little sleep and need to go get breakfast/coffee/dressed...
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  7. #7
    Just Joined!
    Join Date
    Apr 2010
    Posts
    4
    Well, good morning then!
    Haha, I'm honored to have a higher priority than getting breakfast/coffee/dressed !

    I can't seem to find anything in these patch sets that could cause this driver to break. Then again I don't have a lot of linux experience. Am I missing something obvious??

    If you could find some time to take a look at my code again that would be very much appreciated.

  8. #8
    Just Joined!
    Join Date
    Aug 2010
    Posts
    1

    Post Thomas

    goodmorning.. I am also facing the same issue.Can u give me some hints if you are able to solve the issue?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •