SEMA4 on Linux userspace

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

SEMA4 on Linux userspace

跳至解决方案
3,120 次查看
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.  

标签 (1)
0 项奖励
回复
1 解答
3,090 次查看
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 项奖励
回复
11 回复数
2,460 次查看
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 项奖励
回复
2,397 次查看
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");
    }
}

 

 

 

 

2,300 次查看
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 项奖励
回复
2,295 次查看
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 项奖励
回复
3,112 次查看
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 项奖励
回复
3,109 次查看
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 项奖励
回复
3,091 次查看
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 项奖励
回复
3,078 次查看
joanxie
NXP TechSupport
NXP TechSupport

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

 

0 项奖励
回复
3,075 次查看
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 项奖励
回复
3,071 次查看
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

 

3,068 次查看
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 项奖励
回复