-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Accessing GPIO from TA in Raspberry Pi 3 #1496
Comments
Do the GPIO stuff in a pseudo-TA (EL1), where you can access the hardware registers. The pseudo-TA can then be invoked from a client app or a user TA.
|
Hello @jforissier Thank you for your response. I don't have any experience to access a register directly from C. Though, let me try it and get back to you with it. Also, the link below(and some other search results) mentions about accessing GPIO through direct register access. It still uses file operation as I was under the impression that the TA's can access resources in the normal world. Is there any way to do so from the TA? Or is there any other way to access the GPIO from the dynamic TA? I appreciate your help with it. |
No. A "dynamic" or "user" TA is not a regular Linux application. The runtime environment is very different (although some standard libc functions such as A pseudo-TA, however, allows hardware access. It is a bit of code that is statically linked with OP-TEE, runs in secure "kernel" mode (SEL1) and therefore may access physical addresses (hence the memory-mapped hardware registers). See also https://github.com/OP-TEE/optee_os/blob/master/documentation/optee_design.md#12-trusted-applications. For examples of pseudo-TAs, see Note that another option to control the hardware from a dynamic TA is to add a system call to the OP-TEE kernel, and invoke it from the TA. But it is not recommended because it involves extending the kernel/user interface (syscall, syscall wrapper, new function in libutee...).
No. Only indirect access is possible: as I said above, your dynamic TA may call a pseudo-TA specifically designed for that purpose, for instance. |
Thank you for clarifying about the user and pseudo TA. I wrote my first pseudo TA(I have been working with user TA only since past few months), and was able to successfully expose a dummy service to the user TA. That's one step. I looked at the I have been looking at some guides to directly access GPIO by writing your own driver: Right now all I am trying is to light up a LED from the pseudo TA. Thank you again for your assistance. |
@vchong I think this is for you ;) Would you please share your experience re. HiKey GPIO programming in OP-TEE? |
@utkarshagrawalwsu If I did my research correctly, rpi3 uses a broadcom bcm2837 soc (https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2837). It seems like there's no spec (hardware datasheet) for the 2837, but the url says that its underlying architecture is identical to bcm2836 from rpi2 model b, which is identical to bcm2835 from rpi, which brings us to https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2835/BCM2835-ARM-Peripherals.pdf. In section 6, you can see all the register addresses and values you would need to write to these registers in order to control the gpio functionalities. I'm not familiar with the bcm283x, but basically, you would need to understand how these register works, e.g. if you want to configure gpio pin number 2 to be an output pin, what value do you need to write to configure a gpio pin as output (vs input), and to which register address you need to write that value to, i.e. which bit in which register address refers to pin 2. Then you will do this in your pseudo TA using write32() and friends functions from io.h in I actually couldn't find where the gpio driver for 2835 is in https://github.com/raspberrypi/linux :(, but you can find useful reference code in http://www.airspayce.com/mikem/bcm2835/, which is a straightforward (relatively simple) implementation of the above BCM2835-ARM-Peripherals.pdf, and port the necessary functions to your pseudo TA. The code there seems to be updated to rpi2 only so I'm not sure if it's a 1:1 match to rpi3. Most probably not, so you'll have to adjust the addresses, pin numbers, etc properly to adapt it to rpi3 (e.g. in bcm2835.h), but the basic functions and framework are there. There are a lot bit manipulations (shifting, masking, etc) in the code, common to most low level programming, which is why, again, you really have to understand how the register works first before you can understand the code. It will involve a fair amount of research and reading the specs and code, especially more so if you're new to this, so please take things one step at a time. |
@utkarshagrawalwsu Once you're done with the above, to light up an LED from a GPIO software perspective, you would normally:
Steps 3-5 for the hikey platform are done in spi_test.c lines 51, 52 and 62 respectively, which was why you were referred to it earlier, but these are done through driver function calls which you might not want to worry about atm. For now, you would just use functions in io.h to write the appropriate values to the appropriate registers directly. |
@vchong thanks for doing all the research work, I'm sorry I am just realizing the OP is using rpi3 and not HiKey! Doh! ;) |
@jforissier yep, np. ;) It was good info to find out and know. |
@jforissier Thank you for introducing @vchong to the issue Hey @vchong ! I have come up with the following code to set GPIO pin 18 as output pin, and give it a high value.
The above code doesn't work though. The screen freezes for sometime and then the outputs as follows: Just as a note, I invoke two commands in the pseudo TA from the host. The first command I invoke is similar to the hello world program and it is just to make sure that the pseudo TA calls are successful. The second command actually tries to play around with the GPIO stuff. What base address should I use for the GPIO? Should it be the virtual address(0x3F000000 + 0x200000) or the physical address(0x7E200000)? |
@utkarshagrawalwsu You're welcome! Sounds like you made good progress! :) I only browsed through the spec so can't say for sure if the bits selection is right or not (although it looks ok from a quick glance). You'll have to trial and error until you find the right combinations. Off the top of my head, several things to look at.
Not sure if this is related, but is it possible to disable interrupt on the pin? I don't see any interrupt related registers for gpio, but they might be located elsewhere. There are mentions of
I wish the article explained how Dom managed to find out 0x3F200000 for rpi3, but it's not the va. It is actually the pa. 0x7E200000 is the bus address. Read Section 1, especially 1.2 and 1.3, of the spec too, not just the gpio section. The address mapping is multiple layered and hard to figure out (at least for me). I think the pa (0x3F200000) should be used, since there's no dma engines involved, but I might be wrong. If using pa, and it doesn't work (you might get a core dump), you might also to consider trying something like: and translate the base address from pa to va before using them in your functions. Something like:
Again, mostly guesswork here so you'll have to play around a bit to see what works. |
Success! The LED blinks! The
I do not have It still bothers me where
Well, the working code is as follows. Might help someone else. Two commands
Thank you so much for your patience and your help @vchong and @jforissier |
Great! You're welcome and thanks for sharing!
I think this is because it's already done in Now, if you want to go a step further and do things the 'proper' way, you would write a gpio driver for the bcm2835, and control the gpio in your pseudo TA via the driver instead of directly modifying the registers. The contribution would definitely be appreciated! |
Hello @utkarshagrawalwsu @vchong @jforissier, I was trying to access Rpi3 gpio using pta with the help of above mentioned details. I have placed my client application in optee_examples/led_blink/host/main.c
pta I have placed in optee_os/core/pta/led.c
make command : After Loading image into Raspberry Pi , tried to execute optee_examples_led_blink But getting following error. But if I invoke TEST_PSEUDO_TA from my client app then everything works fine.
boot and error logs are attached here. Please help me to proceed further. Thank You |
|
@jforissier Thanks for quick replay. I have included Still I am facing same issue. Please find symbolize.py output,
Boot Log after adding
Did I missed anything? I just wanted to turn ON an LED @GPIO18 of Rpi 3b model. And How do you find that I have an invalid virtual address? Since I'm a newbie in this area please bear with my questions. Thanks in Advance |
|
@AnishKumarAkGk hi,have you figure out this problem?i face this issue in stm32mp,thanks for you reply |
@AnishKumarAkGk io_write32(data, base_addr); you may use this function wrong( io_write32(base_addr,data)) |
Hello,
I have been trying to access the Raspberry Pi3 GPIO from TA. What would be a secure manner to do so?
I tried using the
sysfs
method mentioned in the following link:http://elinux.org/RPi_GPIO_Code_Samples#sysfs
But it requires the use of C file operations. Does OP-TEE support file operations in TA?
Thank You
The text was updated successfully, but these errors were encountered: