On Wed, 2005-03-30 at 17:43, Stefano Gafforelli wrote:
> Hi,
> we are trying to use rtai_shm on arm-pxa255.
> When we load this module we obtain:
> rtai_shm: Unknown symbol kvirt_to_pa
> "insmod: error inserting 'rtai_shm.ko': -1 Unknown symbol in module"
>
> any suggestions?
Shared memory is not supported by RTAI/ARM at the moment, but I have a
patch (is attached) that might work with 2.6, it was developed and
tested for 2.4. Please give it a try and report back if it is working.
Mike
--
Dr. Michael Neuhauser phone: +43 1 789 08 49 - 30
Firmix Software GmbH fax: +43 1 789 08 49 - 55
Vienna/Austria/Europe email: [EMAIL PROTECTED]
Embedded Linux Development and Services http://www.firmix.at/
Index: base/arch/arm/Kconfig
===================================================================
RCS file: /cvs/rtai/vulcano/base/arch/arm/Kconfig,v
retrieving revision 1.3
diff -d -u -r1.3 Kconfig
--- base/arch/arm/Kconfig 18 Mar 2005 09:32:44 -0000 1.3
+++ base/arch/arm/Kconfig 30 Mar 2005 16:36:13 -0000
@@ -287,8 +287,16 @@
default y
config RTAI_SHM
- tristate
+ tristate "Shared memory"
default n
+ help
+ This RTAI specific module allows sharing memory inter-intra
+ real-time tasks and Linux processes. In fact it can be an
+ alternative to the SYSTEM V shared memory. It may also be
+ noticed that the services are symmetrical, i.e. the same calls
+ can be used both in real-time tasks (within the kernel) and
+ Linux processes.
+ The module will be called rtai_shm.o.
config RTAI_SEM
tristate "Semaphores"
Index: base/include/asm-arm/rtai_shm.h
===================================================================
RCS file: /cvs/rtai/vulcano/base/include/asm-arm/rtai_shm.h,v
retrieving revision 1.2
diff -d -u -r1.2 rtai_shm.h
--- base/include/asm-arm/rtai_shm.h 18 Mar 2005 09:10:27 -0000 1.2
+++ base/include/asm-arm/rtai_shm.h 30 Mar 2005 16:36:13 -0000
@@ -41,20 +41,65 @@
#ifndef _RTAI_ASM_ARM_SHM_H
#define _RTAI_ASM_ARM_SHM_H
-#undef __SHM_USE_VECTOR /* not yet implemented for arm ... */
+#include <asm/pgtable.h>
-#ifdef __KERNEL__
+/* convert virtual user memory address to physical address */
+/* (virt_to_phys only works for kmalloced kernel memory) */
-#define RTAI_SHM_HANDLER shm_handler
-#define DEFINE_SHM_HANDLER
+static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
+{
+ unsigned long ret = 0UL;
+ pmd_t *pmd;
+ pte_t *ptep, pte;
-#else /* !__KERNEL__ */
+ if(!pgd_none(*pgd)) {
+ pmd = pmd_offset(pgd, adr);
+ if (!pmd_none(*pmd)) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+ ptep = pte_offset(pmd, adr);
+#else /* >= 2.6.0 */
+ ptep = pte_offset_kernel(pmd, adr);
+#endif /* < 2.6.0 */
+ pte = *ptep;
+ if(pte_present(pte)){
+ ret = (unsigned long) page_address(pte_page(pte));
+ ret |= (adr&(PAGE_SIZE-1));
+ }
+ }
+ }
+ return ret;
+}
-#ifdef __SHM_USE_VECTOR
-#include <asm/rtai_vectors.h>
-#define rtai_shmrq(srq, whatever) rtai_do_swi((srq)|(RTAI_SHM_VECTOR << 24), whatever)
-#endif
+static inline unsigned long uvirt_to_bus(unsigned long adr)
+{
+ unsigned long kva, ret;
-#endif /* __KERNEL__ */
+ kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
+ ret = virt_to_bus((void *)kva);
+
+ return ret;
+}
+
+static inline unsigned long kvirt_to_bus(unsigned long adr)
+{
+ unsigned long va, kva, ret;
+
+ va = VMALLOC_VMADDR(adr);
+ kva = uvirt_to_kva(pgd_offset_k(va), va);
+ ret = virt_to_bus((void *)kva);
+
+ return ret;
+}
+
+static inline unsigned long kvirt_to_pa(unsigned long adr)
+{
+ unsigned long va, kva, ret;
+
+ va = VMALLOC_VMADDR(adr);
+ kva = uvirt_to_kva(pgd_offset_k(va), va);
+ ret = __pa(kva);
+
+ return ret;
+}
#endif /* _RTAI_ASM_ARM_SHM_H */
Index: base/ipc/shm/kvmem.c
===================================================================
RCS file: /cvs/rtai/vulcano/base/ipc/shm/kvmem.c,v
retrieving revision 1.1
diff -d -u -r1.1 kvmem.c
--- base/ipc/shm/kvmem.c 18 Mar 2005 08:57:24 -0000 1.1
+++ base/ipc/shm/kvmem.c 30 Mar 2005 16:36:13 -0000
@@ -24,7 +24,14 @@
void *mem;
unsigned long adr;
+#ifdef CONFIG_ARM
+ /* get non-cachable RAM (ARM problem (cache is indexed by virtual
+ * addresses) */
+ if ((mem = __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM,
+ __pgprot(PAGE_KERNEL.pgprot & ~L_PTE_CACHEABLE)))) {
+#else
if ((mem = vmalloc(size))) {
+#endif
adr = (unsigned long)mem;
while (size > 0) {
mem_map_reserve(virt_to_page(__va(kvirt_to_pa(adr))));
@@ -69,7 +76,12 @@
return -EFAULT;
}
while (size > 0) {
+#ifdef CONFIG_ARM
+ if (mm_remap_page_range(vma, start, kvirt_to_pa(pos), PAGE_SIZE,
+ __pgprot(PAGE_SHARED.pgprot & ~L_PTE_CACHEABLE))) {
+#else
if (mm_remap_page_range(vma, start, kvirt_to_pa(pos), PAGE_SIZE, PAGE_SHARED)) {
+#endif
return -EAGAIN;
}
start += PAGE_SIZE;
@@ -82,6 +94,10 @@
/* allocate user space mmapable block of memory in the kernel space */
void *rkmalloc(int *memsize, int suprt)
{
+#ifdef CONFIG_ARM
+ /* can't use this, don't know how to set memory to uncached */
+ return NULL;
+#else
unsigned long mem, adr, size;
if ((mem = (unsigned long)kmalloc(*memsize, suprt))) {
@@ -94,10 +110,12 @@
}
}
return (void *)mem;
+#endif
}
void rkfree(void *mem, unsigned long size)
{
+#ifndef CONFIG_ARM
unsigned long adr;
if ((adr = (unsigned long)mem)) {
@@ -109,10 +127,14 @@
}
kfree(mem);
}
+#endif
}
/* this function will map an rkmalloc'ed memory area to user space */
int rkmmap(void *mem, unsigned long memsize, struct vm_area_struct *vma) {
+#ifdef CONFIG_ARM
+ return -EFAULT;
+#else
unsigned long pos, size, offset;
unsigned long start = vma->vm_start;
@@ -134,4 +156,5 @@
return -EAGAIN;
}
return 0;
+#endif
}