From: Dominic R. <Dom...@gm...> - 2015-04-26 11:52:56
|
Hi List, I made some more progress with regard to LPC18xx reset handling. I asked NXP, and they provided instructions how to handle the reset within 12 hours - great support! I'm still having some doubts how user expectations could be matched best, which is why I'm writing down some thoughts about LPC18xx reset handling, maybe some of you have some recommendations. I originally started with git master at commit 3d0b46b2c4029ba98f08ff55e57e611df25549ee, using the sample configuration from tcl/board/lpc1850_spifi_generic.cfg for a MCB1800 with a LPC1857 on a ARM-USB-OCD-H. I added two flash bank lines for the internal flash of the LPC1857 (LPC18x0 are flashless parts, LPC18x2|3|5|7 have internal flash). Currently the SPIFI flash bank works only if the processor tried to boot from SPIFI - presumably there's some initialization missing, I'll look into that later. Reset is rather complicated on the LPC18xx, because it features various boot sources, contains a ROM that runs on every boot, and has some quirks if reset via SYSRESETREQ or SRST. With the default setup, OpenOCD tries to reset your processor using SYSRESETREQ. That actually works, if you have a valid image in the internal flash ("valid" is determined by having a checksum in offset 0x1c of the vector table). It fails however if you have no valid image in internal flash, or if you wanted to boot from external flash, or if the processor is configured to run its ISP protocol on a UART. In all these cases, a simple "reset" will leave the processor in a state where you can't even halt anymore. "reset halt" will work, unless the processor is configured to boot from external flash, but if you let it run from there in the boot ROM, the processor will lock up again. Using reset with "srst_only" reliably resets the processor, but you need change #2721 for OpenOCD to resync, and you can't "reset halt" or "reset init". As far as I can tell "srst_only" will always be limited, because it seems to reset some/all of the debug logic, but that's a different topic. The SYSRESETREQ resets most of the processor peripherals (which is good), but doesn't reset some control registers. Because the boot ROM runs on every POR I believe it should run on a debugger-reset as well. That means prior to triggering SYSRESETREQ, you should write 0x10400000 to M3MEMMAP, to map the boot ROM to 0x0. With that mapping a SYSRESETREQ with reset vector-catch works and reliably halts the processor at the first instruction of the boot ROM. If you let it run from there (which is what also happens on a normal "reset" without halt), the processor quickly locks up because it accesses some undocumented peripheral that had been locked-down by the previous run of the boot code (control registers weren't reset, and that lock down is handled by control registers). You can reenable that locked down register, but then the ROM hard-faults when accessing yet another undocumented peripheral address. According to NXP one should skip over that access (using a breakpoint) and reset the control register again. If you did all that, you get past the boot ROM and it jumps to your user code. If you wanted to halt at the entry of your user code, you need to know where the ROM decides the processor should boot from. For that I've used a watchpoint on a write to the M3MEMMAP register. At that point you can halt the processor at the reset entry point, no matter if it's in internal or external flash. I've attached a WIP configuration that implements above procedure. This has a few shortcomings: - it depends on the ROM version. I got the necessary addresses for other versions from NXP, and I think I could locate the sequence that needs skipping on a different ROM version as well, but that needs manual work. - it requires the use of hardware breakpoints and watchpoints. might be problematic if the user set too many already on the telnet interface for example. GDB shouldn't be much of a problem, because GDB removes breakpoints when halted. - reset halt/init need to know where to stop, and that's difficult to decide: - user expectation might be to halt at the first instruction of the ROM, but if you continued from there, the processor would lock up - if the processor enters ISP mode (because of an "force ISP" signal) or because there's no valid image in internal flash, and the ISP is configured for UART or USB boot, there is no "user reset entry point", because the processor remains in the boot code Questions: - what state should the processor be in after "reset halt" (or before the reset-init script? Is it okay to stop at the user's reset entry point, with all of the ROM already executed? - should that be made configurable, e.g. provide the ROM-workaround-handler, but don't enable it by default, or allow it to be disabled? - would a "reset halt" or "reset init" while the processor is forced to remain in ISP mode (no valid flash image) that takes ~1 second to time-out be ok? that way we could simply wait for the ROM to write M3MEMMAP, and if the processor doesn't halt at that watchpoint after ~1s we halt where ever we are a user could instead disable the workaround handler, use reset halt/init, and manually put the processor in any state he likes, without running the ROM - the reset procedure is quite "noisy" - are there commands available to the reset handler that are more quiet? Best Regards, Dominic |