Failed to access UART registers from OP-TEE

Hi,

I wrote a UART device driver in OP-TEE for Jetson AGX Orin, which works in 16450 mode. I mark the register access to UART-A (0x3100000) as non-secure in the device tree of OP-TEE. I made a new set of system calls in OP-TEE to access the UART-A registers from any Trusted Applications (TA). The initialization of UART is done by Linux, since the initialization of UART-A needs BPMP software, which OP-TEE does not have.

However, when I try to access the UART-A registers through my OP-TEE based UART device driver, by performing a write/read to any UART-A register. I get the following error at CBB-Fabric saying Time-out error:

Although, when I try to use minicom after Linux has completed booting and write to the UART-A port, I have no issues. But when I use my OP-TEE based UART driver, I get this error. Also, if I try to use minicom after using OP-TEE based UART driver, I get the same TIMEOUT error, but for different registers of UART-A.

BOOT->OP-TEE UART DRIVER => (TIMEOUT ERROR)
BOOT->MINICOM => (WORKS FINE)
BOOT->OP-TEE UART DRIVER → MINICOM=> (TIMEOUT ERROR)

Am I missing any step like reseting any clocks related to UART-A? Could you please help me debug this issue.

I am using L4T 35.2, and OP-TEE version 3.19.

Regards,
Surya Teja

Hi Surya_Teja,

Are you using the devkit or custom board for AGX Orin?

Could you help to verify with latest R35.4.1?

Which register are you trying to read/write?

Hi KevinFFF,

I am using AGX Orin devkit.

Yes, I will try updating to the latest R35.4.1 and let you know.

I tried accessing the following physical addresses by adding them into the OP-TEE’s MMU at boot time (Used core_mmu_add_mapping function in OP-TEE) to get a virtual address for the UART-A base address, and then access them after Linux has completed booting using their corresponding virtual addresses with R35.2.1. The physical addresses I tried accessing are:
0x3100000 for THR, RBR.
0x3100000 + 0x3 for LCR
0x3100000 + 0x4 for MCR

Please refer to the following register for AGX Orin to check the issue is caused from wrong address.

0x3100000 for UART_THR_DLAB_0_0
0x310000C for UART_LCR_0
0x3100010 for UART_MCR_0

Hi KevinFFF,

I tried updating my board to R35.4.1 by updating to the latest Jetpack 5.1.2, and fully flashed the board. When I tried compiling the default OP-TEE sources provided with R35.4.1, without any changes, I was unable to do it and received an error message. PFA is the error I got.
unable_to_compile_optee_sources.txt (264.3 KB)

Also, when I try to use the OP-TEE versions provided with R35.3.1, and R35.2.1 with Jetpack 5.1.2, I was able to compile the sources, and flash the image on the board. But the board doesn’t boot, since it is unable to prepare TOS params.
unable_to_boot.txt (28.4 KB)

I am currently porting UART accessing PTA to R35.3.1 version of OP-TEE, and will update you soon, by trying to access the registers you suggested.

Do you use the same procedure to build OP-TEE for both R35.4.1(failed) and R35.3.1(success)?
Could you share your steps for us to verify locally?

Yes, I used the same procedure to build OP-TEE for both R35.3.1(success) and R35.4.1 (failed), with the default source code provided (i.e. without any of my custom code).

I believe it is because of a python3 module dependency (cryptography). I did try updating the module according to the instructions provided in the atf_and_optee_README.txt
After updating the module I am getting the following error.
unable_to_compile_optee_sources_2.txt (333.0 KB)

I tried accessing the register addresses (0x3100000 for UART_THR_DLAB_0_0,
0x310000C for UART_LCR_0, 0x3100010 for UART_MCR_0) from OP-TEE that you shared, but I still get the same error(TIMEOUT ERROR), with R35.3.1.

For your original issue, could you help to map UART as a secure device (not a non-secure device) and try again.

For your build issue in R35.4.1, I’m checking with internal and will get back to you once there’s any result.

I mapped the UART-A as secure device, and tried writing a character to the UART_THR_DLAB_0_0 register, but still getting the same error.

For you build issue in R35.4.1, have you run the following command to install cryptography?

pip3 install python3-cryptography

Could you help to check your cryptography version?

When I run the command “pip3 install python3-cryptography”, I get an error, as seen in the image below. But when I use the command “pip3 install cryptography”, I get the following message. FYI, I am using python3.8.

I have also installed the OP-TEE prerequisites mentioned in: Prerequisites — OP-TEE documentation documentation
When I try to install the pre-requisites using the above command, I get the following message: "python3-cryptography is already the newest version (2.8-3ubuntu0.1)”

It seems not the latest version for cryptography.
The expected version would be 40.0.1.

Could you help to remove v2.8 cryptography with the following command?

$ sudo apt remove python3-cryptography

and use the following command to install cryptography from the python public repository.

$ pip3 install python3-cryptography

I removed the python3-cryptography using the command

Then installed cryptography using the command
pip3 install cryptography, but still get the same error. Here is a screenshot of the version number

Since the following command gives an error:

Th error is:
*ERROR: Could not find a version that satisfies the requirement python3-cryptography (from versions: none)
ERROR: No matching distribution found for python3-cryptography
*

I tried using conda to try it on another version of python.

Even though the latest version of cryptography is installed using pip, I get the same error:

But coming back to the main issue, could you please point out any documents, or any other resource to identify the source of the TIMEOUT error at CBB, while accessing the UART registers. I do not think it would be resolved with the latest version of L4T35.4.1, but it might be a rather different issue.

It seems you should use pip3 instead of pip for python3-cryptography

The typical reason for bus access to fail is due to…

  • not-clocked
  • reset asserted
  • SCR/BLF/ARF settings prevent access

I did try using pip3 as well, and see the error:

If the reset is asserted, or not clocked how can I de-assert it from OP-TEE? My concern is that OP-TEE does not have BPMP related features.

It should be right to install cryptography with this command.
Please use the following command to check the version again.

$ pip3 show cryptography

Do you still have have build issue after update the cryptography to v40.x?

I’ve checked with our BPMP team, MMIO should be accessible for both TZ and non-TZ. Could you also share your UART driver in OP-TEE for further check?

I checked the version using the command:

I get the version number:

But now, I get the TypeError: public_key() missing 1 required positional argument: ‘backend’.

I was under the assumption that the clocks and reset signals would be controlled by BPMP software, and we communicate with the BPMP R5 processor using bump_atomic_send_receive command. I shall try de-asserting the reset line for UART-A by directly writing to the memory address, and let you know.

So far, I was trying to access the UART-A registers, without de-asserting the reset signal, and not setting the UART-A configuration. Since I assumed that we need to de-assert the reset signal, only at the time of initialization, not when performing UART read/write operations.

I tried de-asserting the reset line for UART-A, and got this FIREWALL_ERR, before trying to read/write to any UART register. Is there anything else that I am missing that should be done at boot time? Should I be changing the setting of SCR/BLF/ARF as you suggested? If so, can you please provide the guidelines as to how to proceed ahead.

For this firewall error, could you try to modify the following line in <Linux_for_Tegra>/bootloader/t186ref/BCT/tegra234-firewall-config-base.dtsi, and re-flash the board to apply?

        reg@5694 { /* CBB_FABRIC, CBB_CENTRAL_CBB_FIREWALL_UARTA_CAR_BLF, WRITE_CTL */
            exclusion-info = <2>;
-            value = <0x00000008>;
+            value = <0x0000000a>;
        };