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;
} //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/