I am trying to write to the flash from a non-secure application via the fsl_iap driver. I therefore configured TrustZone and Secure AHB Controller so that the ROM_API_TREE is in non-secure memory. In the secure world, it is possible to call FLASH_Init() and then write to the flash. In the non-secure world, I get a Hardfault because of an SAU violation at address 0x13001100.
I think this is because ROM_API_TREE in fsl_iap.c is defined to
#define ROM_API_TREE ((uint32_t *)0x130010f0) // line 22 of fsl_iap.c
Which is secure memory, so assert(FLASH_API_TREE) fails, as FLASH_API_TREE points to ROM_API_TREE.
To test, I set ROM_API_TREE to non-secure memory:
#define ROM_API_TREE ((uint32_t *)0x030010f0)
Now the assert does not cause a hardfault anymore, but FLASH_API_TREE->flash_init(config); (line 136 of fsl_iap.c) does cause a hardfault. The SAU violation is now at a different address: 0x13001088. This address is before the actual ROM API.
The behaviour can be replicated easily with importing one of the TrustZone SDK examples, adding the fsl_iap driver, configuring the Secure AHB Controller to be non-secure (privileged) for the ROM area where the ROM_API_TREE is located and calling FLASH_Init(). From the secure project, this is possible, from the non-secure project, it fails.
In the user manual, I found:
"TrustZone disabled image is executed in normal mode and whole memory space is
configured as non-secure (except first 4kB of ROM). Thus, the ROM API can be used
without any limitation as on any LPC device without security extension."
This makes me think, that it should be possible to access the flash from non-secure memory also if the non-secure application runs after a secure application that configured SAU and Secure AHB Controller correct. Could you please clarify if and how it is possible to write to the flash from a non-secure application?
Thank you for your response, we can be sure that its not a version issue as the earlier versions are not stable in this matter.
Is it possible for you to send me your modifications as they are in your project. I've been trying to replicate the same behavior using the hello_world example and your instructions of replicating this, but no luck so far.
I took the hello world project, added the modifications and now have the behaviour as described in my first post. I attached the full secure and non-secure project.
If the initialization of the flash in your hello world non-secure project does work, you could also provide this projects so that I can see the differences.
Thank you for sharing your project, I am currently checking it throughly to see if there is anything evident that might help resolve this.
One section that I'd like to point out is the actual function that you call from the non secure will actually have to be in a nonsecure entry function. Similar in the way that the hello world calls the StringCompare_NSE.
This means that you can create a function for example:
__attribute__((cmse_nonsecure_entry)) void FLASH_INIT_NSE(void)
This function must be included in the veneer_table.c in the secure world side and the veneer_table.h on both secure and nonsecure worlds. Then from nonsecure world you will call FLASH_INIT_NSE. In addition,when this is done it is not necessary for the iap drivers to be in the non secure application either since the function itself is defined in the secure world. You read with detail this section in the reference manual in section 220.127.116.11.2 TrustZone enabled images.
I've also requested more information from the team that focuses on TrustZone, they will be able to shed some light on any other configurations that I might be missing.
Thank you for your patience!
Thank you for your reply!
With section 18.104.22.168.2, to me it looks like that it is not possible to access the non-secure flash directly from the normal world (instead, it is only possible via the secure world and a non-secure entry function).
The approach described in 22.214.171.124.2 however lowers the security of the overall system according to my understanding: As soon as I use non-secure entry functions, I need additional logic to validate the input parameters, i.e. to make sure that only non-secure flash shall be accessed from the normal world, as inside the entry function, secure flash is accessible too.
I implemented it now this way and it works. However, as I do not need any secure resources (as I want to access non-secure flash from non-secure software) I would be glad if there would be a direct way, without switching to the secure world at all. Should this somehow be possible, please let me know.
Well I'm glad you were able to at least work around this point for now and can continue with your application. However I now understand what you were trying to achieve. It is possible that the region of memory you are trying to acces is secured at some point.
From the above graph we can see that both SAU and IDAU have to be configured as non secure in order for it to be truly non secure. This is probably the reason as to why you are intially getting a hardfault. I will pass on your observations from your last post, since I originally thought you were trying to access a secure section of flash from the non secure.
I will keep you posted as soon as I have information.