Hello
We have a board with a LS1046A as PCIe endpoint. Now when the CPU hangs itself we need to make a hard reset. This will also clear out the PCIe registers with BARs and MSI data. I'm now trying to save the necessary contents to restore them after the reset so the communication with the PCIe host (PC) will continue to work.
I thought of using the OCRAM but couldn't find whether this keeps the content in a hard reset or not, first tests indicate not. Is there some other area that I can use to keep data over a hard reset or do I have to keep them off-CPU, as in a NvRam or Eeprom? Is there a better way to reset the CPU? I've seen the core soft resets, but they need the cores to still be working to be executed.
Thanks
I'm now trying to issue core soft resets, however I must be missing something as nothing happens.
// set and enable interrupt 196, edge trigger
// trigger
GICD_ICFGR[]=...
GICD_ITARGETSR[]=...
// irq's are group 1
GICD_IGROUPR[]=...
GICD_IGRPMODR[]=...
// enable interrupt
GICD_ISENABLER[]=...
// enable soft reset
uint32* pEnable = (uint32*)0x01570204;
setbe32(pEnable, 0x80000000);
// set vector
uint32* pVector = (uint32*)0x01570220;
setbe32(&pVector[0], 0x80000000 >> 2);
// issue reset
uint32* pReset = (uint32*)0x01570130;
setbe32(&pReset[0], 0x80000000);
Do I need to set other registers as well? Is there somewhere an example?
I know that I need to provide a place to jump to where a WFI instruction is,
but the CPU never comes there, it just continues to work. I'm thinking that
writing to the register to issue the interrupt 196 may actually work but the
interrupt is pending somewhere. Where could I look if the interrupt is
actually issued and pending?
Thanks
Have you tried using the watchdog timer in order to reset the system ? Instead of doing a hard reset, you can configure the watchdog timer to automatically force a reset in case the cpu hangs.
Thanks. But we'd also like to be able to issue a reset even if the CPU is not hanging. And on the other hand an automatic reset would clear the state the CPU is in and therefore preventing us from examining what went wrong.
So what is missing in my code to issue a core reset on demand? Do you have an example?
Thanks
Discussing with the AE team.
Have you referred to Section 4.4.3 Core Soft Reset of LS1046A RM for your implementation ? Attaching the RM just in case. Also where are you running this code, uboot or linux ?
Got it.
Hi
Just wondering if you're still on it.
Thanks
For the sake of understanding the real issue at hand. Can you explain why would you want to do a soft reset of the core ?
I thought I already explained that in my previous posts. If we don't have communication to the CPU anymore we'd like to issue a core reset as this will bring the CPU to a defined state without clearing the PCIe registers. We don't want to use the watchdog as we'd like to examine the bad state first. And we'd also like to issue a reset even if there's no problem.
I'm slightly intrigued by your question. Is it not possible to issue the core resets as described in the manual?
I will discuss with the AE team.
It is possible to do a soft-reset. As you have seen in the RM we support soft core reset on a hardware level. However after checking internally, we got to know that the SDK doesn't have any support for it in the software for LS1048 and so it is not tested. If you still wish to pursue it, you may try and debug it on your own. Some pointers that may be helpful for you as mentioned in my previous responses:-
1. You can check - Interrupt Set-Pending Registers, GICD_ISPENDRn - It will tell you if there's a pending interrupt on the processor.
2. Also after you run your program, you can take a dump of the registers that you are writing to, to verify that the values are getting reflected after the register write operation.
3. In the code snippet that you sent :-
// enable soft reset
uint32* pEnable = (uint32*)0x01570204;
setbe32(pEnable, 0x80000000);
you can verify if this is setting the 0th bit of CORE Soft Reset Enable Register (SCFG_CORESRENCR) 0x01570204
I did some more testing. To enable I can also write 0xFFFFFFFF as the other bits are not used anyway:
uint32* pEnable = (uint32*)0x01570204;
setbe32(pEnable, 0xFFFFFFFF);
After writing all bits in the register are set. Also for actually issuing the reset only one bit its used so I can just write all of them:
uint32* pReset = (uint32*)0x01570130;
setbe32(pReset, 0xFFFFFFFF);
Still after writing this no register in the GIC area (0x01410000+) did change, not ISPEND or any other. Are there other things I can check?
Thanks