First of all, i am sorry that i could not get the exact point of your question.
So, i will give my thought for two cases.

1) Do the memory mapped I/O for a pass-thru region of AMCC from the kernel space 
    including RT-tasks.

    After converting the physical address into the virtual address in the kernel space 
using ioremap(),
    the kernel device driver or the RT-tasks can access the region.

1) Do the memory mapped I/O for a pass-thru region of AMCC from the user space.

     In this case, i think the code you attached should work well.
     Or, the application program in the user space can get the physical address and 
size of 
     the pass-thru region by a IOCTL call which is processed by the kernel device 
driver, 
     and then just remap it to the user space using the mmap function 
     with the opened file descriptor of "/dev/mem".

Bye.

----- Original Message ----- 
From: "Jens Lauer" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Tuesday, May 09, 2000 8:06 PM
Subject: [rtl] convert driver from NonRT to RT


> Hi RTer,
> 
> I have a problem regarding converting a drivers code from NonRT to RT
> (RTL/RTAI). The application I have will not have any value if not
> working in realtime so I have no choice ....
> 
> The driver is for a amcc PCI controller and maps one (or up to 4) pass
> thru regions of the amcc provided memory on the pci addon board to the
> user application following this scheme:
> 
> a) in the drivers code there will the processing of the mmap prepared as
> follow:
> 
> static void
> amcc_s5933_pt_setup (struct amcc_s5933 *dev, u32 badr, int number)
> {
>     u32         mask;
> 
>     /* we only support memory mapped PT regions */
> 
>     if (badr & PCI_BASE_ADDRESS_SPACE_IO)
>         {
>         pr_debug ("amcc: pt: PassThru region %d  IO-mapped", number);
>         return;
>         }
>     else
>         {
>         pr_debug ("amcc: pt: PassThru region %d  mem-mapped", number);
>         }
>         
>     /* get configuration */
> 
>     cli ();
>     /*
>     * writing all 1 to PCI_BASE_ADDR_x
>     * reading the in this register set value (set by Controller)  
>     * writing back the old value from init 
>     */
>     pcibios_write_config_dword (dev->bus, dev->function, badrs[number],
> ~0);
>     pcibios_read_config_dword (dev->bus, dev->function, badrs[number],
> &mask);
>     pcibios_write_config_dword (dev->bus, dev->function, badrs[number],
> badr);
>     sti ();
> 
> 
>     pr_debug ("amcc: pt: %d - mask %08lx, currValue %08lx\n", number,
>               mask, badr);
> 
>    /* extract data 
>     * in this way we get the size(-1) of the PCI region
>     */
> 
>     mask &= PCI_BASE_ADDRESS_MEM_MASK;
> 
>     dev->ptnum++;
> 
>     (dev->pts[number - 1]).size = (~mask) + 1;
>     (dev->pts[number - 1]).phys_addr = (badr &
> PCI_BASE_ADDRESS_MEM_MASK);
>     (dev->pts[number - 1]).virt_addr = ioremap ((dev->pts[number -
> 1]).phys_addr,
>                                             (dev->pts[number -
> 1]).size);
> 
>     pr_debug ("amcc: PassThru: PTNo[%d] - Size: %d, PhysAddr: %08lx,
> VirtAddr: %08lx\n", (number - 1),
>               (dev->pts[number - 1]).size,
>               (dev->pts[number - 1]).phys_addr,
>               (dev->pts[number - 1]).virt_addr);
> }
> 
> 
> 
> b) then the mmap is part of struct file_ops
> static int amcc_s5933_mmap ( struct file *file, struct vm_area_struct
> *vma )
> {
> 
> int AREA = 0;
>     unsigned long offset = vma->vm_offset;
> 
>     /* very simple for the moment - only pts[AREA] */
> 
>     switch(MINOR(file->f_dentry->d_inode->i_rdev))
>         {
>         case
> AMCC_PT1_MMAP_MINOR:
>                 {
>                 pr_debug("amcc: MINOR 1 -- first PT Area\n");
>                 AREA = 0;
>                 }
>                 break;
>         case AMCC_PT2_MMAP_MINOR:
>                 {
>                 pr_debug("amcc: MINOR 2 -- second PT Area\n");
>                 AREA = 1;
>                 }
>                 break;
>         case
> AMCC_PT3_MMAP_MINOR:
>                 {
>                 pr_debug("amcc: MINOR 3 -- third PT Area\n");
>                 AREA = 3;
>                 }
>                 break;
>         case AMCC_PT4_MMAP_MINOR:
>                 {
>                 pr_debug("amcc: MINOR 4 -- forth PT Area\n");
>                 AREA = 4;
>                 }
>                 break;
>                 
>         } file://switch
> 
> 
>     pr_debug ("amcc: mmap: start: %08lx, end: %08lx, offset: %08lx,
> flags: %08lx\n",
>               vma->vm_start, vma->vm_end, vma->vm_offset,
> vma->vm_flags);
> 
>     /* check dimensions */
> 
>     if ((vma->vm_end - vma->vm_start + vma->vm_offset) >
> amcc_dev.pts[AREA].size)
>         return -EINVAL;
> 
> 
>     /* get real address */
> 
>     vma->vm_offset += amcc_dev.pts[AREA].phys_addr;
>     if (vma->vm_offset & ~PAGE_MASK)
>         return -ENXIO;
> 
>     /* map pages */
> 
> 
> 
> if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC))
>         {
>         pgprot_val(vma->vm_page_prot) =
> pgprot_noncached(pgprot_val(vma->vm_page_prot));
>         vma->vm_flags |= VM_IO;
>         pr_debug("pgprot_noncached ...");
>         }
> 
> 
> if ((vma->vm_offset) & (PAGE_SIZE-1))
>         {
>         pr_debug("amcc: pages not aligned\n");
>         return -ENXIO;
>         }
>         
> if ((vma->vm_end - vma->vm_start) > (0x20000 - vma->vm_offset))
>         {
>         pr_debug("amcc: PT too big !!!\n");
>         return -EINVAL;
>         }       
> 
>           
> // remapping    | virtuell address | physical address | size |
> protection */
> if (remap_page_range (vma->vm_start, vma->vm_offset,(vma->vm_end -
> vma->vm_start), vma->vm_page_prot))
>         {
>         return -EAGAIN;
>         }
> else
>         {
>         pr_debug("vma->vm_start(virtaddr): %08lx
> vma->vm_offset(physaddr):
> %08lx\n(vma->vm_end - vma->vm_start)(size): %08lx 
> vma->vm_page_prot(protection): %08lx\n)", 
>         vma->vm_start, vma->vm_offset,(vma->vm_end - vma->vm_start),
> vma->vm_page_prot);
>         }
> 
> /*
>     vma->vm_inode = inode;
>     inode->i_count++;
> */
> 
> return 0;
> }
> 
> c) the app uses the mmap in this manner:
> 
>  pt = (__u32 *) mmap (Start, 0x20000, (PROT_READ | PROT_WRITE),
> MAP_SHARED,
>     amcc_fd, (off_t) 0L); // 128KByte  mapped
> 
> 
> Now the question: if I will have to do the handling of the memory 
> formerly mapped in user spaced in my module now, what will I have to do?
> I am not the original autor of the modules code and have only some
> overview.
> 
> 
> 
> 
> -- 
> Jens Lauer
> TU Chemnitz /Germany
> 09107 Chemnitz
> Fakultaet fuer Elektrotechnik und Informationstechnik
> Lehrstuhl Elektrische Maschinen und Antriebe (Prof. Hofmann)
> 
> Tel +49 (0)371 531 3379
> Fax +49 (0)371 531 3324 
> [EMAIL PROTECTED]
> -- [rtl] ---
> To unsubscribe:
> echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
> echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
> ---
> For more information on Real-Time Linux see:
> http://www.rtlinux.org/rtlinux/
> 
-- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
---
For more information on Real-Time Linux see:
http://www.rtlinux.org/rtlinux/

Reply via email to