SEMA4 on Linux userspace

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SEMA4 on Linux userspace

Jump to solution
1,918 Views
BitBakery
Contributor III

Hi, I'd like to know if there's any examples or resources that explain how to deal with SEMA4 on Linux userspace. I want to access to the SEMA4 registers dynamically in the application. I'm using iMX8M Mini with imx-5.10.72 kernel. I tried accessing SEMA4 registers using a mmap'ed pointer, but only could read, writing to register simply froze it without errors. I'd appreciate it for any tips.    

#It seems iMX6SX has its SEMA4 Linux driver. Would it be okay to reuse it for the Mini?  

Thanks in advance.  

Labels (1)
0 Kudos
1 Solution
1,888 Views
BitBakery
Contributor III

Reply to myself. I should have accessed to SEMA4 registers using a byte pointer..! It turns out that I missed it on the reference manual. Everything works fine now. Also, I could integrate the SEMA4 driver to iMX8MM successfully.  

View solution in original post

0 Kudos
11 Replies
1,258 Views
stmatscaps
Contributor III

I'd like to revive this thread to ask how the SEMA4 driver can actually be used from Linux user space. Based on the hints provided by @BitBakery I was able to build a Yocto mickledore image for the IMX8MN-EVK board where the SEMA4 driver is enabled in the kernel.

Are there any examples how to use the SEMA4 driver from Linux userspace?

0 Kudos
1,195 Views
BitBakery
Contributor III

Hi, as far as you use SEMA4 on Linux userspace, you don't even need to enable the kernel driver. You can just access to SEMA4 registers directly via mmap'ing.

How to access SEMA4 registers

1. Find out the SEMA4 register addresses (base, gates, INE, NTF, etc). They should be on the reference manual. For example, SEMA4 base address for the iMX8MP is 0x30AC0000. 

2. MMAP the base address so that you can access it from the userspace. You can access related registers by adding proper offsets to the base address. One thing to be aware of is that each register needs to be accessed by a specific type of pointer. (u8, u16, 32, etc). It's written in the reference manual. 

* You can't lock/unlock CP1 gates from CP0, vice versa. iMX8 looks where register access coming from and protect any improper write access. 

 

Ok, here's a rough sample code how to access the register. Hope this helps to give you an idea. 

 

 

 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

#define PAGESIZE        (4096)
#define SEMA4_BASE      (0x30AC0000u)
#define SEMA4_UNLOCK    (0x0)
#define SEMA4_CP0_LOCK  (0x1)
#define SEMA4_CP1_LOCK  (0x2)

int main(void)
{
    void* pSEMA4 = NULL;
    volatile __u8 *mmPtr = NULL; 

    int fd = open("/dev/mem", O_RDWR);
    pSEMA4 = mmap(NULL, PAGESIZE, PROT_READ|PROT_WRITE,
			MAP_SHARED, fd, SEMA4_BASE);
	close(fd);
	assert(pSEMA4 != MAP_FAILED);

    // Locking SEMA4 Gate0 (CP0)
    // CP0 refers the application core, in my case it's A53. 
    mmPtr = (__u8 *)(pSEMA4 + 0x0); // Gate0 offset is 0x0
    *mmPtr = SEMA4_CP0_LOCK;
    if (*mmPtr == SEMA4_CP0_LOCK) {
        printf("SEMA4 lock success\n");
    } else {
        printf("SEMA4 lock failed : Currently locked by the other core\n");
    }

    // Unlocking
    *mmPtr = SEMA4_UNLOCK;
    if (*mmPtr == SEMA4_UNLOCK) {
        printf("SEMA4 unlock success\n");
    } else {
        printf("SEMA4 unlock failed : Currently locked by the other core\n");
    }
}

 

 

 

 

1,098 Views
stmatscaps
Contributor III

Thanks for the example, @BitBakery. This is similar to what I implemented in the meantime.

From the existing thread I had the impression that you had implemented a solution based on the driver, and I was interested how that would work. But after re-reading your messages I see now that I misunderstood that, and your example confirms my existing implementation.

0 Kudos
1,093 Views
BitBakery
Contributor III

That’s nice! Yeah, I messed around with the driver but ended up realizing didn’t need to deal with it. Cheers. 

0 Kudos
1,910 Views
joanxie
NXP TechSupport
NXP TechSupport

you can check AIPS3 memory check to find the SEMA4, they should access by user space if they are R/W, if the register is readable only, maybe you couldn't write this, and you can refer to the imx6sx as example

 

0 Kudos
1,907 Views
BitBakery
Contributor III

Thanks for your reply. The reference manual says the SEMA4 gates are R/W registers, I don't know why I can't write on them from Linux.. By the way, SEMA4 node is missing under the AIPS3 in the imx8mm device tree. Is there a specific reason for that? Would it be okay to add it manually, based on the imx6sx devicetree?

0 Kudos
1,889 Views
BitBakery
Contributor III

Reply to myself. I should have accessed to SEMA4 registers using a byte pointer..! It turns out that I missed it on the reference manual. Everything works fine now. Also, I could integrate the SEMA4 driver to iMX8MM successfully.  

0 Kudos
1,876 Views
joanxie
NXP TechSupport
NXP TechSupport

you integrate the SEMA4 according to the imx6 successfully, right?

 

0 Kudos
1,873 Views
BitBakery
Contributor III

Yes, that's correct. I added the SEMA4 node to imx8mm device tree with its corresponding register address, then added the driver(source, Kconfig & Makefile). v5.10.72 kernel probed it alright according to dmesg. Thanks.    

0 Kudos
1,869 Views
joanxie
NXP TechSupport
NXP TechSupport

thanks for sharing, imx8mm doesn't have much information about this like imx6, but I think they should be similar, good to know that it works

 

1,866 Views
BitBakery
Contributor III

Sure thing! As far as I see the reference manuals of the imx6 and 8, SEMA4 looked identical(structure, offsets, etc) 

0 Kudos