Assembly instructions for MPC5777C

cancel
Showing results for 
Search instead for 
Did you mean: 

Assembly instructions for MPC5777C

619 Views
Othmane1
Contributor II

Hi, 

I was trying to execute the code below in S32 design studio (power2.1), which was designed in green hill, which basically fix 2bit error after ram fault injection but it seems that my compiler doen't know these assembly instructions, i also placed down below the original copied code from green hill

Othmane1_0-1685345080225.png

Othmane1_1-1685345308351.png

 

0 Kudos
9 Replies

589 Views
davidtosenovjan
NXP TechSupport
NXP TechSupport

At first you need to use VLE instructions and symbol "%" must be before register marking. 

Example: 

__asm__("e_ori %r3,%r3,0x0038");

0 Kudos

578 Views
Othmane1
Contributor II

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)

Othmane1_0-1685604235963.png

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));
    }
    }
}

 

0 Kudos

568 Views
davidtosenovjan
NXP TechSupport
NXP TechSupport

Is is the reference from assembler?

0 Kudos

563 Views
Othmane1
Contributor II

Hi, sorry for the misunderstanding, but i don't know which reference you are talking about!!

0 Kudos

556 Views
davidtosenovjan
NXP TechSupport
NXP TechSupport

I mean the error message you shown saying "undefined reference". Which line it is related and whether it points to asm code.

0 Kudos

552 Views
Othmane1
Contributor II

it is referring to these lines:

        "e_lis    %r3,test@h\n"
        "e_or2i    %r3,test@l\n"
 
below is the function which includes those lines:
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"
    );
}
0 Kudos

536 Views
davidtosenovjan
NXP TechSupport
NXP TechSupport
0 Kudos

530 Views
Othmane1
Contributor II

i tried that solution but it still give me an error:

Othmane1_0-1685694618169.png

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"
);
}

0 Kudos

420 Views
davidtosenovjan
NXP TechSupport
NXP TechSupport

Yesterday I spend almost the whole day trying to solve this (also discussing with S32DS expert) trying everything possible.

In the end we agreed that there was apparently no way to achieve passing variable address to specific core register by inline assembler with using of GCC compiler. Even without direct register specification (only as general parameter %0) it did not work well, additionally in the code later you need to use explicitly r30/r31.

If you find some solution, please let us know.

Otherwise I would propose some other solutions -
- use GHS compiler in S32DS, what is possible, but you would have to pay for a license fo GHS
- to create a section in the linker command file (possibly with symbolic name for an address specified in LCF) and use it is you asm code
- or use hard-coded address

0 Kudos