Thanks a lot Stefan! base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc and base-hw/src/core/spec/arm_v7/trustzone/mode_transition.s makes the memory sharing and register read/write between vmm and vm clearer.
Further doubts: (1)We put three print statements: (a) In os/src/server/tz_vmm/spec/imx53/main.cc, printf1 Signal s = _sig_rcv.wait_for_signal() printf3
(b) In base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc, printf2 mtc()->switch_to(reinterpret_castCpu::Context*(_state), cpu, (addr_t)&_mt_nonsecure_entry_pic, (addr_t)&_tz_client_context);
printf1 prints once. printf2 prints multiple times, followed by printf3 (we make uart secure in csu_config.h, so we hit printf3 followed by the register dumps). Why do we switch from secure to normal world so many times (indicated by multiple printf2), while _sig_rcv.wait_for_signal()? What causes a switch back from normal to secure, before the UART related abort?
(2) Every time we switch from secure to normal world, .macro _secure_to_nonsecure does mov lr, #13 mcr p15, 0, lr, c1, c1, 0 /* enable EA, FIQ, and NS bit in SCTRL */ So a csu based uart abort in normal world is expected to trap to monitor? Are you saying this behavior is something peripheral/vendor specific?
(3) We suspect that the csu based uart abort doesn't trap to monitor handler. If it came to the handler with a DABT excpetion, DFAR would be copied to r3 and saved in the memory shared with _state at .macro _nonsecure_to_secure In that case _state->dfar would give the same value, with and without the explicit read in base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc case Genode::Cpu_state::DATA_ABORT: state->dfar = Cpu::Dfar::read(); But we see without this read, _state->dfar prints all zeros, and with this read it gives a uart address. So dfar is not saved in the monitor handler, and therefore no other register would be saved. Is this understanding correct?
(4) What does Signal s = _sig_rcv.wait_for_signal(); do in os/src/server/tz_vmm/spec/imx53/main.cc? If the uart abort doesn't trap to the monitor, what raises the signal so that we come to this main.cc and execute the subsequent code like _handle_vm() that calls _vm->dump()? Is vmm doing some sort of polling to check cpu exception states in normal world?
(5) If abort doesn't trap to monitor, then only dfar and dfsr will hold the normal world relevant values, as that was the last abort? The other registers will be over-written, as normal world continued to execute, until vmm polled it? So emulating the abort causing instruction in secure world looks infeasible?
(6) Is there a way to print something from base-hw/src/core/spec/arm_v7/trustzone/mode_transition.s? Most of the actions happen here, but we are not able to trace when those macros are executed.
Thanks for your constant assistance.
Riju