linux-mips
[Top] [All Lists]

Re: mmap problem another :)

To: linux-mips@linux-mips.org
Subject: Re: mmap problem another :)
From: Dmitriy Tochansky <toch@dfpost.ru>
Date: Tue, 14 Dec 2004 10:51:54 +0300
In-reply-to: <AC350838-49EF-11D9-A745-003065F9B7DC@embeddededge.com>
Organization: Special Technology Center
Original-recipient: rfc822;linux-mips@linux-mips.org
References: <20041209161207.39140f0d.toch@dfpost.ru> <AC350838-49EF-11D9-A745-003065F9B7DC@embeddededge.com>
Sender: linux-mips-bounce@linux-mips.org
On Thu, 9 Dec 2004 09:36:11 -0500
Dan Malek <dan@embeddededge.com> wrote:

> Read the memory mapping docuemntation and understand the APIs.
> All of the Linux mapping functions, whether mmap() from an application
> or in the kernel are going to align on page boundaries.
> 
> The address of 0x40002040 is going to be aligned to a page boundary,
> so you have to consider the offset into that page to the base of the
> device, plus the register offset.  The kernel mapping functions,
> like remap_page_range, are going to force the alignment because
> that is what we expect in the kernel.  An mmap() with an unaligned
> address will generate an error.
  Ok. I understand. But still havent fun. :(
Yes, Im assume that offset if pagealligned:

static int
mdrv_mmap (struct file *file, struct vm_area_struct *vma)
{
  unsigned long offset = 0;
  int ret;
  struct inode *inode;
  inode = file->f_dentry->d_inode;
  struct pci_dev *curdev = NULL;
  int minor = MINOR (inode->i_rdev);
  printk("minor = 0x%X\n",minor);
  curdev = (devs[minor]);
  unsigned long start = vma->vm_start;
  unsigned long size = (vma->vm_end - vma->vm_start);
  offset = pci_resource_start (curdev, IOMEM0);
  offset &= PAGE_MASK;
  printk("start= 0x%X offset = 0x%X size=0x%X\n",start, (unsigned int)offset, 
(unsigned int) size);
  ret = remap_page_range_high(start, offset, size, vma->vm_page_prot);
  return ret;
}

 This code, AFAIK will return me a pointer to begin of page where my ioaddr is. 
?

 Then in my testcode I compensate shift by adding it to addr:

---

#include "mdrv.h"
#include <sys/mman.h>
#include <stdio.h>
#include <fcntl.h>

#define MMAP_SIZE 0x40

int fd, fd2;

int
main ()
{

  fd = open ("/dev/mboard1", O_RDWR);

  unsigned long *x;

  x = mmap (NULL, MMAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

  printf ("mmap return: 0x%X", x);

  if (x == MAP_FAILED)
    {
      printf (" it is very bad! :(\n");
      perror ("mmap:");
      return -1;
    }

  printf (" its ok!\n");
  
  printf("x = 0x%X\n",x);

#define CONS 0
//0x2040 >> 2
  
  x += CONS;
  
  printf("x = 0x%X\n",x);
  unsigned long m = 0xEF;
  
  printf("m = 0x%X\n",m);
  
  //printf ("%p\n", x[(0x3C)>>2]); //We have to get 0xE6 here
  
  m = x[(0x40>>2)+(0x3C>>2)];
  
  printf("m = 0x%p\n", m);
  
  x -= CONS;  
  
  munmap (x, MMAP_SIZE);
  close(fd);
  
  return 0;
}

---

DEbug output shows that mmap - success. I get pointer and size = 0x1000(one 
page). Then
I try to read m from board register. BTW, if I just read apps finishing but 
when I try to output
to console(as in src) "m" programm hangs.

Have no idea what the ... is goin on. Some hints please.

<Prev in Thread] Current Thread [Next in Thread>