This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

TZASC (TZC380) enabling sequence

Hi everyone, I am trying to correctly setup the TZASC of my IMX6q and IMX6ul boards, without blowing the fuse (I only have one board, I'd like to have it right by software before).

From what I gathered from the documentation of the TZASC and from the documentation of the board, I have to:

- enable the clocks of the TZASC (for the moment, I set all the CCGRX to 0xffffffff)

- correctly setup at least TZASC's region 0 (for the moment, Secure and Non secure have read/right access)

- setup the action to be notified of potential violations (IRQ and Exception in my case)

- Disable the bypass (by setting GPR9's bit 0 to 1 on my boards).

At this point, I still get a few 'printf's from the uart, but my kernel hangs. Did I miss something ?

Be aware that I do this from the RAM I'm trying to protect. I did a few tests by moving this code to OCRAM prior to starting my OS and the result was more or less the same, hanging.

From the documentation of the TZASC, I gathered that doing this setup from the RAM you want to protect is not the best idea, but it should work either way, with a small period of time where TZASC rights might not be enforced correctly.

In my case, I go from "By-passed" to "Not by-passed and RW for everyone" so I didn't except troubles. IMX6q's documentation seems to be more aggressive and note that this enabling *has to* be performed while the RAM is IDLE.

Does anyone can clarify the situation I am in ?

Best regards,

Vincent

Parents
  • vsiles -- put simply, if you have accesses going through to the DDR controller or being returned to the DDR controller, and you change the protections for a region you're currently executing or accessing data from, you run the risk of a transaction being started without/with protections and finishing with/without protections. In this case, the behaviour is simply undefined (or at least, implementation defined because it is up to the DDR controller, the requesting master, what lies between etc.). The general thought on the TZASC is that you would give back one of two responses (configured with the action register at 0x004) -- a straight forward DECERR to both reads and writes, or OKAY with return data of 0x00 (this is just passed back to the master from the TZASC, the DDR controller is never passed the request), and on writes deassertion of the byte strobes and data set to 0x00 -- passed to the DDR controller. Either way that can cause somewhat unpredictable corruption of data to the master or towards DDR, especially if you're doing it while DDR requests are "in flight."

    On the i.MX6 in particular, the bypass logic is what you need to be careful about. Not only do you need to make sure DDR transactions are not in flight to configure protections on regions covered by those transactions, you will also need to be absolutely sure that when you remove the bypass, you really don't want is to have the bypass logic handle a request to DDR and then, mid-transaction, have the TZASC take over. In the case of data being returned to a master, you risk locking the master mid-way through a transaction, or locking the TZASC mid-way through a transaction.

    The reason for the hang might also be a little less obvious: is the tzasc_int line wired up to the CSU? If the platform security controller detects a security violation then this might be the end of the road for your application. You can modify whether the TZASC asserts the interrupt in the TZASC, though (same action register above) and prevent that.

    It may also be that you need to disable speculative accesses in the TZASC -- the net effect of enabling them (which is the default after reset) is that when a request comes in to the TZASC, it will perform the downstream request before it checks permissions. That way the permission check and the transaction are performed asynchronously and it hides some of the added TZASC latency. The issue with that is that it may be performing accesses on it's own behalf as a result of other masters performing speculative accesses (a speculation on speculation! what a joy!), and changing the privileges "in flight" there is also the same problem. But, all in all, that's the same problem as before -- you need to make sure no traffic is going through the TZASC that would be within any of the regions that you're attempting to protect.

Reply
  • vsiles -- put simply, if you have accesses going through to the DDR controller or being returned to the DDR controller, and you change the protections for a region you're currently executing or accessing data from, you run the risk of a transaction being started without/with protections and finishing with/without protections. In this case, the behaviour is simply undefined (or at least, implementation defined because it is up to the DDR controller, the requesting master, what lies between etc.). The general thought on the TZASC is that you would give back one of two responses (configured with the action register at 0x004) -- a straight forward DECERR to both reads and writes, or OKAY with return data of 0x00 (this is just passed back to the master from the TZASC, the DDR controller is never passed the request), and on writes deassertion of the byte strobes and data set to 0x00 -- passed to the DDR controller. Either way that can cause somewhat unpredictable corruption of data to the master or towards DDR, especially if you're doing it while DDR requests are "in flight."

    On the i.MX6 in particular, the bypass logic is what you need to be careful about. Not only do you need to make sure DDR transactions are not in flight to configure protections on regions covered by those transactions, you will also need to be absolutely sure that when you remove the bypass, you really don't want is to have the bypass logic handle a request to DDR and then, mid-transaction, have the TZASC take over. In the case of data being returned to a master, you risk locking the master mid-way through a transaction, or locking the TZASC mid-way through a transaction.

    The reason for the hang might also be a little less obvious: is the tzasc_int line wired up to the CSU? If the platform security controller detects a security violation then this might be the end of the road for your application. You can modify whether the TZASC asserts the interrupt in the TZASC, though (same action register above) and prevent that.

    It may also be that you need to disable speculative accesses in the TZASC -- the net effect of enabling them (which is the default after reset) is that when a request comes in to the TZASC, it will perform the downstream request before it checks permissions. That way the permission check and the transaction are performed asynchronously and it hides some of the added TZASC latency. The issue with that is that it may be performing accesses on it's own behalf as a result of other masters performing speculative accesses (a speculation on speculation! what a joy!), and changing the privileges "in flight" there is also the same problem. But, all in all, that's the same problem as before -- you need to make sure no traffic is going through the TZASC that would be within any of the regions that you're attempting to protect.

Children