Thank you so much, it seems to solve the issue but now i have another issue: it seems that the compiler is complaining about undefined reference to one array that i created (test)
ps: the error is in the Fix_2bit_error_RAM_data function
My code:
#include "stl_sram_ecc.h"
#include "pin_mux.h"
#include <stdio.h>
/*******************************************************************************
* Local function prototypes
*******************************************************************************/
static void ERM_init(void);
static void Generate_noncorrectable_ECC_error(void);
static void Generate_1bit_ECC_error(void);
static void Fix_1bit_error_RAM_data(void);
static void Fix_2bit_error_RAM_data(void);
static void Increment_MCSRR0_to_next_instruction(void);
static void ClearMCSR(void);
static void ClearMSR_EE(void);
static void SetMSR_ME(void);
void ERM_combined_isr(void);
//void Machine_check_handler(void);
void stl_sram_ecc (void);
/*******************************************************************************
* Local functions
*******************************************************************************/
/* debugging variables */
uint32_t ERM_2bit_RAM_err_handler_pass_count = 0;
uint32_t ERM_1bit_RAM_err_handler_pass_count = 0;
uint32_t IVOR1_handler_pass_count = 0;
#define PORT PTD
#define LED 21
static uint32_t test[2] __attribute__ ((aligned (8))) =
{
0xBABADEDA,
0xABBAABBA
};
/*******************************************************************************
Function Name : ERM_combined_isr
Engineer : b05111
Date : Sep-16-2015
Parameters :
Modifies :
Returns :
Notes : Handles 2-bit ECC RAM error
Issues :
*******************************************************************************/
void ERM_combined_isr(void)
{
/******** 1. disable EIM if error was injected ********/
if (EIM->EIMCR)
{
EIM->EIMCR = 0; // global error injection
}
/******** 2. examine source of ECC error ********/
// Multi-bit errors catched by PRAMC_0 module
if (ERM->SR0 & ERM_SR0_2b_PRAMC_0)
{
//printf("Multi-bit RAM ECC error found at address");
//printf("0x%08X\r\n" ,ERM->EARn[ERM_chnl_PRAMC_0].EAR);
Fix_2bit_error_RAM_data();
ERM_2bit_RAM_err_handler_pass_count++;
}
// Single-bit errors catched by PRAMC_0 module
else if (ERM->SR0 & ERM_SR0_1b_PRAMC_0)
{
//printf("Single-bit RAM ECC error found at address ");
//printf("0x%08X\r\n" ,ERM->EARn[ERM_chnl_PRAMC_0].EAR);
Fix_1bit_error_RAM_data();
ERM_1bit_RAM_err_handler_pass_count++;
}
// Multi-bit errors catched by Core_0 data read
else if (ERM->SR1 & ERM_SR1_2b_Core0_data)
{
//printf("Multi-bit ECC error found during Core0 data read at address");
//printf("0x%08X\r\n" ,ERM->EARn[ERM_chnl_Core0_data].EAR);
Fix_2bit_error_RAM_data();
ERM_2bit_RAM_err_handler_pass_count++;
}
// Single-bit errors catched by Core_0 data read
else if (ERM->SR1 & ERM_SR1_1b_Core0_data)
{
//printf("Single-bit ECC error found during Core0 data read at address");
//printf("0x%08X\r\n" ,ERM->EARn[ERM_chnl_Core0_data].EAR);
Fix_1bit_error_RAM_data();
ERM_1bit_RAM_err_handler_pass_count++;
}
// All others multi-bit errors
else if (( ERM->SR0 & ERM_SR0_2b_all) ||
( ERM->SR1 & ERM_SR1_2b_all) ||
( ERM->SR2 & ERM_SR2_2b_all) )
{
//printf("Multi-bit ECC error found\r\n");
//printf("ERM_SR0 is 0x%08X\r\n" ,ERM->SR0);
//printf("ERM_SR1 is 0x%08X\r\n" ,ERM->SR1);
//printf("ERM_SR2 is 0x%08X\r\n" ,ERM->SR2);
}
// All others single-bit errors
else if (( ERM->SR0 & ERM_SR0_1b_all) ||
( ERM->SR1 & ERM_SR1_1b_all) ||
( ERM->SR2 & ERM_SR2_1b_all) )
{
//printf("Single-bit ECC error found\r\n");
//printf("ERM_SR0 is 0x%08X\r\n" ,ERM->SR0);
//printf("ERM_SR1 is 0x%08X\r\n" ,ERM->SR1);
//printf("ERM_SR2 is 0x%08X\r\n" ,ERM->SR2);
}
/******** 3. clear particular ERM_SR flag ********/
// in this example we negate all flags to negate interrupt request
ERM->SR0 = 0xFFFFFFFF;
ERM->SR1 = 0xFFFFFFFF;
ERM->SR2 = 0xFFFFFFFF;
}
/*******************************************************************************
Function Name : Machine_check_handler
Engineer : b05111
Date : Sep-16-2015
Parameters :
Modifies :
Returns :
Notes : Function handles Machine_check_handler
*******************************************************************************/
//__interrupt
void IVOR1_Exception_Handler(void)
{
/* If error was injected, disable EIM */
if (EIM->EIMCR)
{
EIM->EIMCR = 0; // global error injection
}
ERM_combined_isr();
Increment_MCSRR0_to_next_instruction();
ClearMCSR();
IVOR1_handler_pass_count++;
}
/*******************************************************************************
Function Name : Increment_MCSRR0_to_next_instruction
Engineer : b05111
Date : Sep-16-2015
Parameters :
Modifies :
Returns :
Notes : - based on algorithm described in AN4648
- applicable for IVOR1 (stores address to MCSRR0)
Issues :
*******************************************************************************/
#if VLE_IS_ON // for VLE code
static void Increment_MCSRR0_to_next_instruction(void)
{
__asm(
"mfmcsrr0 %r5;"
/* determine opcode @ MCSRR0 */
"se_lhz %r4,0(%r5);"
/* check bit 31,28 only*/
"e_andi. %r3,%r4,0x9000;"
"e_cmpli 0x0,%r3,0x1000;"
"e_bne __machine_check_adjust_for_16bit_opcode;"
/* 0xx1 => 32 bit*/
"se_addi %r5,2;"
"__machine_check_adjust_for_16bit_opcode:;"
/* all others just 16 bit long*/
"se_addi %r5,2;"
/* save adjusted return address*/
"mtmcsrr0 %r5;"
);
}
#else //BookE
static void Increment_MCSRR0_to_next_instruction(void)
{
__asm (
/* MCSRR0->r5 */
mfmcsrr0 %r5;
/* for BookE, all instructions are 32 bit long */
se_addi %r5,4;
/* save adjusted return address*/
mtmcsrr0 %r5;
);
}
#endif
/*******************************************************************************
Function Name : ClearMCSR
Engineer : b05111
Date : Sep-16-2015
Parameters :
Modifies :
Returns :
Notes : When MSR[ME] is set, error flags must be cleared to prevent
machine check exception to recall.
Issues :
*******************************************************************************/
static void ClearMCSR(void)
{
__asm (
/* load mask */
"e_lis %r4, 0xFFFF\n"
"se_subi %r4, 0x0001\n"
/* Clear MCSR */
"mtmcsr %r4\n"
);
}
/*******************************************************************************
Function Name : ClearMSR_EE
Engineer : b05111
Date : Sep-16-2015
Parameters :
Modifies :
Returns :
Notes : Negates the MSR[EE].
Issues :
*******************************************************************************/
static void ClearMSR_EE(void)
{
__asm (
/* read spr MSR */
"mfmsr %r3\n"
/* load mask to negate the EE bit */
"e_lis %r4, 0xFFFF\n"
"e_add16i %r4, %r4, 0x7FFF\n"
/* clear EE bit */
"se_and %r3, %r4\n"
/* write back to MSR */
"mtmsr %r3\n"
);
}
/*******************************************************************************
Function Name : SetMSR_ME
Engineer : b05111
Date : Sep-16-2015
Parameters :
Modifies :
Returns :
Notes : Asserts the MSR[ME].
Issues :
*******************************************************************************/
static void SetMSR_ME(void)
{
__asm (
/* read spr MSR */
"mfmsr %r3\n"
/* load mask to assert the ME bit */
"e_lis %r4, 0x0000\n"
"e_add16i %r4, %r4, 0x1000\n"
/* set ME bit */
"se_or %r3, %r4\n"
/* write back to MSR */
"mtmsr %r3\n"
);
}
/*******************************************************************************
Function Name : Fix_2bit_error_RAM_data
Engineer : b05111
Date : Sep-16-2015
Parameters :
Modifies :
Returns :
Notes : fixes the wrong data with a 64-bit write
data pattern could possibly to be loaded from some backup
Issues : stmw rS,D(rA) stores all GPR register above rS =>
=> r30 and r31 must to be used
*******************************************************************************/
static void Fix_2bit_error_RAM_data(void)
{
__asm (
/* load the address of the wrong data */
"e_lis %r3,test@h\n"
"e_or2i %r3,test@l\n"
/* r30 and r31 are non-volatile regs, must be stored */
"se_mr %r4,%r30\n"
"se_mr %r5,%r31\n"
/* load data pattern to GPR30 and GPR31 */
"e_lis %r30,0xfeed\n"
"e_or2i %r30,0xface\n"
"e_lis %r31,0xcafe\n"
"e_or2i %r31,0xbeef\n"
/* write GPR30 and 31 to SRAM as one 64bit access */
"e_stmw %r30,0(%r3)\n"
/* restore r30 and r31 */
"se_mr %r30, %r4\n"
"se_mr %r31, %r5\n"
);
}
/*******************************************************************************
Function Name : Fix_1bit_error_RAM_data
Engineer : b05111
Date : Sep-16-2015
Parameters :
Modifies :
Returns :
Notes :
Issues :
*******************************************************************************/
static void Fix_1bit_error_RAM_data(void)
{
static uint32_t test_temporary[2];
/* read and write back to physically correct 1-bit error */
test_temporary[0] = test[0];
test_temporary[1] = test[1];
test[0] = test_temporary[0];
test[1] = test_temporary[1];
}
/*******************************************************************************
Function Name : ERM_init
Engineer : b05111
Date : Sep-16-2015
Parameters :
Modifies :
Returns :
Notes :
Issues :
*******************************************************************************/
static void ERM_init(void)
{
/* enable reporting for ERM channel 0 and 14 */
ERM->CR0 = ERM_CR0_2b_PRAMC_0 |
ERM_CR0_2b_PRAMC_1 |
ERM_CR0_1b_PRAMC_0 |
ERM_CR0_1b_PRAMC_1 ;
ERM->CR1 = ERM_CR1_2b_Core0_instr |
ERM_CR1_2b_Core0_data |
ERM_CR1_1b_Core0_instr |
ERM_CR1_1b_Core0_data ;
}
/*******************************************************************************
Function Name : Generate_noncorrectable_ECC_error
Engineer : b05111
Date : Sep-16-2015
Parameters :
Modifies :
Returns :
Notes : generates 2-bit ECC error in RAM
Issues :
*******************************************************************************/
static void Generate_noncorrectable_ECC_error(void)
{
register uint32_t test_read = 0;
//printf("ECC 2b error injected into RAM\r\n");
/* invert 2 LSB bits to create non-correctable data error */
EIM->EICHDn[EIM_chnl_PRAMC_0].WORD1 = 0x00000003;
/* PRAMC_0 channel error injection enable */
EIM->EICHEN = EIM_EICHEN_PRAMC_0;
/* global error injection enable */
EIM->EIMCR = 1;
/* error caused by read (it should set MCSR[MAV, LD, BUS_DRERR]) */
test_read = test[0];
}
/*******************************************************************************
Function Name : Generate_1bit_ECC_error
Engineer : b05111
Date : Sep-16-2015
Parameters :
Modifies :
Returns :
Notes : generates 1-bit ECC error in RAM using the ECSM_EEGR register
Issues :
*******************************************************************************/
static void Generate_1bit_ECC_error(void)
{
register uint32_t test_read = 0;
//printf("ECC 1b error injected into RAM\r\n");
/* invert 1 LSB bits to create correctable data error */
EIM->EICHDn[EIM_chnl_PRAMC_0].WORD1 = 0x00000001;
/* PRAMC_0 channel error injection enable */
EIM->EICHEN = EIM_EICHEN_PRAMC_0;
/* global error injection enable */
EIM->EIMCR = 1;
/* error caused by read */
test_read = test[0];
}
/*******************************************************************************
* Global functions
*******************************************************************************/
void stl_sram_ecc (void)
{
uint32_t counter = 0;
//printf("ECC error injection example\r\n");
INTC_Init();
ERM_init();
SetMSR_ME();
//ClearMSR_EE();
/**************************************************************************/
/* */
/* Choose which ECC error is supposed to be injected ! */
/* */
/**************************************************************************/
#if 1
Generate_noncorrectable_ECC_error();
#else
Generate_1bit_ECC_error();
#endif
if(ERM_1bit_RAM_err_handler_pass_count > 0)
{
while(1)
{
/* Insert a small delay to make the blinking visible */
delay(720000);
/* Toggle output value LED1 */
PINS_DRV_TogglePins(PORT, (1 << LED));
}
}
}