- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am trying to generate the correctable alarm0[6] in SMU (for example: CPU0 SRAM PCACHE/PSPR single-bit correctable). but it was not generating, the code snippet is below--
Regards-
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
According to the 10.4.5.5 Alarm Debug Registers in the user manual the snapshot is taken when reset is executed by the SMU or transition to FAULT and there is nothing about NMI request which you configured by seting SMU_AG0CFx . Check flag SCU_TRAPSTAT.B.SMUT
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, Shambhu.
Your code about ALM0[6] configuration parts looks right.Could you read status of the alarm status register(AG0) and check if the status of ALM0[6] is set.
Additional , i wonder to know how do you inject the fault of single-bit correctable.
Best regards,
Lane YE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi LaneYE,
Thanks for your reply.
I have tried injecting error by --
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, Shambhu
After fault injection. Is there any error bits set.Please check ECCD.CERR,ECCD.UCERR,ECCD.MERR.
Additional , some MTU registers need to be configured to propagate CE/UCE/ME to alarm.
Hints: 13.3.5.1.7 Writing to a Single Memory Location
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi LaneYE,
Thanks for your suggestion!
I have configured according the figure that you had shared --
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, Shambhu,
>>The first QA, please search "MCi_ALMSRCS" register in page 13-40
>>The second QA, please reference Infineon-AURIX_TC39x-UserManual-v01_00-EN.pdf and finds SSH instance of CPU0DSPR
Best regards,
Lane YE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi LaneYE,
Thanks for your suggestions!
but I am using TC23X processor not the TC39X. Please suggest me according to TC23X.
Regards-
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It should be like this:
Mc = (Ifx_MC *) ((uint32) &MODULE_MC0 + ((uint32) 0x100 * (uint32) 14));
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Waldi,
Thanks for the suggestion.
Actually 100 was mistakenly written in place of 0x100. sorry for that. as I am already using (uint32)&MODULE_MC1 - (uint32)&MODULE_MC0 which is 0x100.
Reset happens after the function inject_memory_error(MC_NUMBER_DSPR0, 0);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please take a look at the (9.6.1.3) MEMSTAT Implementation from the user manual. CPU0DSAIU is reserved. You probably have inifinite loop there. I think you can remove it completely. Please update your function inject_memory_error for further analysis.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Waldi,
Thanks for your precious suggestions. You are very right about the MEMSTAT.
I have removed the loop after enabling/disabling the MTU_MEMTEST0.B.CPU0DSEN. still I got the reset.
Please suggest on this.
For reference I have sharing the code for inject_memory_error--
Regards-
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you really want to know the exact reason, please read CPU_Trap_Recognition_1_KIT_TC275_LK-TR It could be an asynchronus trap and if it is, the source is before the line you might think it is. Read CPU0_DEADD register.
MCONTROL must have Res4 = 4. MCONTROL reset value is 4008h. Try this:
Mc->MCONTROL.U = (uint16) (((0x10 & IFX_MC_MCONTROL_RES4_MSK) << IFX_MC_MCONTROL_RES4_OFF)
| ((0x1 & IFX_MC_MCONTROL_DIR_MSK) << IFX_MC_MCONTROL_DIR_OFF)
| ((0x1 & IFX_MC_MCONTROL_START_MSK) << IFX_MC_MCONTROL_START_OFF));
Mc->MCONTROL.U = (uint16) (((0x10 & IFX_MC_MCONTROL_RES4_MSK) << IFX_MC_MCONTROL_RES4_OFF)
| ((0x1 & IFX_MC_MCONTROL_DIR_MSK) << IFX_MC_MCONTROL_DIR_OFF));
Isn't the address in the RANGE register too high? How are you going to trigger the ALM0[10]? What address are you going to read?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Waldi,
I have tried with the configuration you suggested, but still the same behavior.
range register now I have configured is: Mc->RANGE.U = (0 << 15) | (0xFF << 7) | (0x0 << 0);
Is this correct?
Also, I trigger theALM0[10] alarm by --
p = (unsigned long *)0x70002044;
*(p + 1) = 4;
p = (unsigned long *)0x70002044;
Regards-
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
To inject an error you need to write data with error to single DSPR location. By default it is zero and ECC is set. That is why Mc->RDBFL[0].U = 0x0001 is enough. The error is there but first the ECCMAP must be set to test mode where only data bits are mapped to RDBFLx. What is the value of SramEccTst_SingleBitErrPtrn[x]? Maybe you are doing it in different way.
Try this. Before write:
Mc->ECCS.U = (uint16) ((0x01 & IFX_MC_ECCS_ECCMAP_MSK) << IFX_MC_ECCS_ECCMAP_OFF); //test mode - data only
After write (MBIST done):
Mc->ECCS.U = (uint16) (((0x1 & IFX_MC_ECCS_TRE_MSK) << IFX_MC_ECCS_TRE_OFF)
| ((0x1 & IFX_MC_ECCS_ECE_MSK) << IFX_MC_ECCS_ECE_OFF)
| ((0x1 & IFX_MC_ECCS_AENE_MSK) << IFX_MC_ECCS_AENE_OFF)
| ((0x1 & IFX_MC_ECCS_UENE_MSK) << IFX_MC_ECCS_UENE_OFF)
| ((0x1 & IFX_MC_ECCS_CENE_MSK) << IFX_MC_ECCS_CENE_OFF)); //all on
Please read 9.4.4.6 Writing to a Single Memory Location in the user manual.
The RANGE works in different way (and why do you have there << 7). When RAEN is 0 (CONFIG0 = 0x1000) it holds memory location and for DSPR the value under address ADDR *16 will be changed i.e. if ADDR is 0x1000 check 0x70010000 to trigger an error, if ADDR is 0x1001 check 0x70010010
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Waldi,
I have tried with your suggestions but still issues.
I think to post the whole code here so that you can review once what I am doing ----
int main(void) {
volatile unsigned long *p;
hw_mainInit();
uint16_t endinitSfty_pw = IfxScuWdt_getSafetyWatchdogPassword();
IfxScuWdt_clearSafetyEndinit(endinitSfty_pw);
SMU_KEYS.U = (uint32_t)0x000000BC;
SMU_AG0CF0.U = (1 << 10);
SMU_AG0CF1.U = (0 << 10);
SMU_AG0CF2.U = (1 << 10);
SMU_KEYS.U = (uint32_t)0x00000000;
IfxScuWdt_setSafetyEndinit(endinitSfty_pw);
enable_trap();
SMU_CMD.U = (unsigned int)0x00000000U;
for (int i = 0; i < 10000; i++) {
} // kill some time
inject_dspr_error();
p = (unsigned long *)0x70002040;
*(p + 1) = 4;
p = (unsigned long *)0x70002040;
while(1)
{}
}
void inject_dspr_error(void) {
uint16_t endinitSfty_pw = IfxScuWdt_getSafetyWatchdogPassword();
IfxScuWdt_clearSafetyEndinit(endinitSfty_pw);
uint16_t passwd = IfxScuWdt_getCpuWatchdogPassword();
IfxScuWdt_clearCpuEndinit(passwd);
MTU_CLC.B.DISR = 0U;
while (MTU_CLC.B.DISS)
;
IfxScuWdt_setCpuEndinit(passwd);
MTU_MEMTEST0.B.CPU0DSEN = 1U; // Enable MTU for DSPR0
inject_memory_error(14);
MTU_MEMTEST0.B.CPU0DSEN = 0U; // Disable MTU for DSPR0
IfxScuWdt_setSafetyEndinit(endinitSfty_pw);
}
void inject_memory_error(const uint32 mc_number) {
uint32 ResultLoopCount;
Ifx_MC *Mc;
Mc = (Ifx_MC *)((uint32)&MODULE_MC0 + ((uint32)0x100* (uint32)mc_number));
Mc->ECCS.U = (uint16)((0x01 & IFX_MC_ECCS_ECCMAP_MSK) << IFX_MC_ECCS_ECCMAP_OFF);
Mc->RDBFL[0].U = 0x0001;
Mc->ECCS.U = (uint16)(((0x1 & IFX_MC_ECCS_TRE_MSK) << IFX_MC_ECCS_TRE_OFF) |
((0x1 & IFX_MC_ECCS_ECE_MSK) << IFX_MC_ECCS_ECE_OFF) |
((0x1 & IFX_MC_ECCS_AENE_MSK) << IFX_MC_ECCS_AENE_OFF) |
((0x1 & IFX_MC_ECCS_UENE_MSK) << IFX_MC_ECCS_UENE_OFF) |
((0x1 & IFX_MC_ECCS_CENE_MSK) << IFX_MC_ECCS_CENE_OFF)); //all on
/* Configure writing of single memory address: */
Mc->CONFIG0.U =
(uint16)(((uint32)SRAM_CONFIG0_NUMACCS_1 << (uint32)12u) | ((uint32)SRAM_CONFIG0_ACCSTYPE_WR << (uint32)0u));
Mc->CONFIG1.U = 0U;
Mc->RANGE.U = 0x0204;
Mc->MCONTROL.U = (uint16)(((0x10 & IFX_MC_MCONTROL_RES4_MSK) << IFX_MC_MCONTROL_RES4_OFF) |
((0x1 & IFX_MC_MCONTROL_DIR_MSK) << IFX_MC_MCONTROL_DIR_OFF) |
((0x1 & IFX_MC_MCONTROL_START_MSK) << IFX_MC_MCONTROL_START_OFF));
Mc->MCONTROL.U = (uint16)(((0x10 & IFX_MC_MCONTROL_RES4_MSK) << IFX_MC_MCONTROL_RES4_OFF) |
((0x1 & IFX_MC_MCONTROL_DIR_MSK) << IFX_MC_MCONTROL_DIR_OFF));
for (ResultLoopCount = 0U; ResultLoopCount < 50; ResultLoopCount++) {
__asm("nop");
}
}
Regards-
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try this:
p = (unsigned long *) 0x70002040;
uint32_t a;
a = *p;
With this:
static inline __attribute__((always_inline)) void inject_dspr_error (void)
{
IfxScuWdt_clearCpuEndinitInline(&MODULE_SCU.WDTCPU[0], IfxScuWdt_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[0]));
MTU_CLC.U = 0U;
IfxScuWdt_setCpuEndinitInline(&MODULE_SCU.WDTCPU[0], IfxScuWdt_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[0]));
IfxScuWdt_clearSafetyEndinitInline(IfxScuWdt_getSafetyWatchdogPasswordInline());
MTU_MEMTEST0.B.CPU0DSEN = 1U; // Enable MTU for DSPR0
inject_memory_error(14);
MTU_MEMTEST0.B.CPU0DSEN = 0U; // Disable MTU for DSPR0
IfxScuWdt_setSafetyEndinitInline(IfxScuWdt_getSafetyWatchdogPasswordInline());
}
static inline __attribute__((always_inline)) void inject_memory_error (const uint32 mc_number)
{
uint32 ResultLoopCount;
switch (mc_number)
{
case 14 :
MODULE_MC14.ECCS.U = (uint16) ((0x01 & IFX_MC_ECCS_ECCMAP_MSK) << IFX_MC_ECCS_ECCMAP_OFF);
MODULE_MC14.RDBFL[0].U = SramEccTst_SingleBitErrPtrn[0];
MODULE_MC14.RDBFL[1].U = SramEccTst_SingleBitErrPtrn[1];
MODULE_MC14.RDBFL[2].U = SramEccTst_SingleBitErrPtrn[2];
MODULE_MC14.RDBFL[3].U = SramEccTst_SingleBitErrPtrn[3];
MODULE_MC14.RDBFL[4].U = SramEccTst_SingleBitErrPtrn[4];
MODULE_MC14.RDBFL[5].U = SramEccTst_SingleBitErrPtrn[5];
MODULE_MC14.RDBFL[6].U = SramEccTst_SingleBitErrPtrn[6];
MODULE_MC14.RDBFL[7].U = SramEccTst_SingleBitErrPtrn[7];
MODULE_MC14.RDBFL[8].U = SramEccTst_SingleBitErrPtrn[8];
MODULE_MC14.RDBFL[9].U = SramEccTst_SingleBitErrPtrn[9];
MODULE_MC14.RDBFL[10].U = SramEccTst_SingleBitErrPtrn[10];
MODULE_MC14.RANGE.U = 0x0204;
/* Configure writing of single memory address: */
MODULE_MC14.CONFIG0.U = (uint16) (((0x0 & IFX_MC_CONFIG0_ACCSTYPE_MSK) << IFX_MC_CONFIG0_ACCSTYPE_OFF)
| ((1 & IFX_MC_CONFIG0_NUMACCS_MSK) << IFX_MC_CONFIG0_NUMACCS_OFF));
MODULE_MC14.CONFIG1.U = 0U;
MODULE_MC14.MCONTROL.U = (uint16) (((0x10 & IFX_MC_MCONTROL_RES4_MSK) << IFX_MC_MCONTROL_RES4_OFF)
| ((0x1 & IFX_MC_MCONTROL_DIR_MSK) << IFX_MC_MCONTROL_DIR_OFF)
| ((0x1 & IFX_MC_MCONTROL_START_MSK) << IFX_MC_MCONTROL_START_OFF));
MODULE_MC14.MCONTROL.U = (uint16) (((0x10 & IFX_MC_MCONTROL_RES4_MSK) << IFX_MC_MCONTROL_RES4_OFF)
| ((0x1 & IFX_MC_MCONTROL_DIR_MSK) << IFX_MC_MCONTROL_DIR_OFF));
for (ResultLoopCount = 0U; ResultLoopCount < 50; ResultLoopCount++)
{
__asm("nop");
}
MODULE_MC14.ECCS.U = (uint16) (((0x1 & IFX_MC_ECCS_TRE_MSK) << IFX_MC_ECCS_TRE_OFF)
| ((0x1 & IFX_MC_ECCS_ECE_MSK) << IFX_MC_ECCS_ECE_OFF)
| ((0x1 & IFX_MC_ECCS_AENE_MSK) << IFX_MC_ECCS_AENE_OFF)
| ((0x1 & IFX_MC_ECCS_UENE_MSK) << IFX_MC_ECCS_UENE_OFF)
| ((0x1 & IFX_MC_ECCS_CENE_MSK) << IFX_MC_ECCS_CENE_OFF)); //all on
break;
default :
break;
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Waldi,
still no alarm generated. I have tried every possible scenario but wondering what is the missing step or thing in the code.
Regards-
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please check if this function will return true value:
boolean IsDsprCorrectableError(void)
{
Ifx_MC *mc = (Ifx_MC *)(0xF0061000U + 0x100 * 14);
return (mc->ECCD.B.CERR == 1);
}
What is inside enable_trap function?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Waldi,
enable_trap(): I am only enabling the SMU error as below --
uint16_t endinitSfty_pw = IfxScuWdt_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[0]);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There shoudn't be a trap while reading mc->ECCD.B.CERR if the MTU module is enabled. Could you check CPU0_DEADD register when the trap is generated.
You can also use something like this to check if SMU knows about DSPR correctable error:
boolean IsSmuAg0Sf10Raised(void)
{
return (SMU_AG0.B.SF10 == 1);
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Waldi,
I have checked all the registers. No register has any fault.
Regards-
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try something simple and forget about SMU configuration for now:
volatile unsigned long *p;
for (uint32 i = 0; i < 16; ++i) {
*((uint8 *)(0x70002040 + i)) = 0x00;
}
__nop();
inject_dspr_error();
__nop(); // check if MC14_ECCD = 0x7C00
p = (unsigned long *) 0x70002040;
uint32_t a;
a = *p;
__nop(); // check if MC14_ECCD = 0x7C23
if( IsDsprCorrectableError() )
{
__nop();
__nop();
__nop();
}
if ( IsSmuAg0Sf10Raised() )
{
__nop();
__nop();
__nop();
}
Check MC14_ECCD values
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Waldi,
Thanks for suggestion!
yes it works as you have suggested. like the value of MC14_ECCD comes 0x7C23 (means correctable errors) come but the exact alarm alm0[10] is not being generated (I think because we haven't configured the same?).
But I have configured the alm0[10] then I tried, I got SMU_AG0.B.SF10 as 1 means alm0[10]. but the SMU_AD0.B.DF10 still 0 and in the code, we check the SMU_AD0.B.DF10 for DSPR correctable error. please suggest how to get the values in SMU_ADx...
Regards-
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
According to the 10.4.5.5 Alarm Debug Registers in the user manual the snapshot is taken when reset is executed by the SMU or transition to FAULT and there is nothing about NMI request which you configured by seting SMU_AG0CFx . Check flag SCU_TRAPSTAT.B.SMUT
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks a lot Waldi for your help!
Regards-