■QuestionsI'm trying to bare-metal debug on a Cortex-A55.I want to perform simple memory read/write, but if the program size becomes large enough, the program hangs up. When I connected the DS-5 and checked the operation, I found that the branch instruction to a certain function was undefined. Why is this happening?
■ Disassembled code exampleHere is a disassembled code example. Here is an example where I want to call a function called accesss_test2().
As shown below, the program branch destination is undefined. Stepping through this instruction hangs up.
If I remove a few lines of source code, accesss_test2() is called without issue. Even if you refer to the disassembled code, the branch instruction is inserted correctly.
■ Conditions・The only difference in the C source code between when the accesss_test2() function can be correctly branched and when it can't is whether or not there are a few lines of simple memory read/write processing within the accesss_test2() function. The whole function is less than 120 lines.
・The build environment uses the following project stored in the installation directory of DS-5 v5.29.3. startup_Cortex-A55_Cortex-A75
・Compiler is "Arm Compiler 6 (DS-5 built-in)".
・scatter.scat and startup.S are not edited.
I will add what I have learned from continuing research.
If you change OPT_LEVEL in makefile, the phenomenon will change a little. The above phenomenon was caused by setting OPT_LEVEL ?= 1, but if you change it to OPT_LEVEL ?= 3, it will hang even if the amount of source code that was not a problem with OPT_LEVEL ?= 1. In order to get OPT_LEVEL ?= 3 to work properly, we need to reduce a few more lines of C source code.
Also, it seems that the program area seen from the Cortex-A55 has been rewritten to 0xDEADBEEF when the TCR_EL1 register is changed, rather than being unable to link normally.
The source code I am running is below. The main purpose is to change the physical address to 4GB, and the TCR_EL1 setting is changed in MainApp (void).
r = (0b00LL << 37) |
(0b010LL << 32) |
(0b00LL << 30) |
(0b00LL << 28) |
(0b00LL << 26) |
(0b00LL << 24) |
(0b1LL << 23) |
(00LL << 16) |
(0b00LL << 14) |
(0b10LL << 12) |
(0b01LL << 10) |
(0b01LL << 8) |
(0b0LL << 7) |
(24LL << 0);
asm volatile ("msr TCR_EL1, %0" : : "r" (r));
asm volatile ("isb") ;
When stepping in instruction step mode, the data in the program area seems to be rewritten to 0xDEADBEEF immediately after executing the following disassembled instruction "msr tcr_el1, x8".
100 asm volatile ("msr TCR_EL1, %0" : : "r" (r));
000000008000287c: mov x8, #0x2518 // #9496
0000000080002880: movk x8, #0x80, lsl #16
0000000080002884: movk x8, #0x2, lsl #32
0000000080002888: msr tcr_el1, x8
101 asm volatile ("isb") ;
I don't know if the memory area has really been rewritten to 0xDEADBEEF, or if it just looks like it from the Cortex-A55.
MemoryView just before executing "msr tcr_el1, x8" is as follows.
MemoryView immediately after executing "msr tcr_el1, x8" is as follows.
I suspect a mistake in setting the TCR_EL1 register, and am reviewing the settings, but I still don't know what caused it. Also, I cannot understand that the phenomenon differs depending on the program size. It's a very small program, am I running out of stack or heap size?
Thank you for your reading and cooperation. This issue has been resolved on its own, so I'm closing it.
The cause was a bad setting destination address in the MMU table.
I needed to change the physical address size to 1TB (40bits), so I needed to change the MMU setting, but startup_Cortex-A55_Cortex-A75(DS-5 v5.29.3.) didn't include the MMU setting code, so I coded it myself.
At that time, since TTB0_L2_PERIPH (the setting destination address of the MMU table) was set to a fixed value, when the program size increased, the correct start address shifted 4 KB later. After modifying TTB0_L2_PERIPH to be obtained from the Image file, it became possible to follow changes in program size.
Thank you for coming back to share the solution you found.