/****************************************************************************
/*  F i l e   D a t a                                                        
/*                                                                           
/*  Module       : BootStrap                                                   
/*  C.I. No.     :                                                           
/*  $Revision: 1.1.1.1 $
/*  $Date: 2006/04/25 09:00:20 $
/*  Belonging to :                                                           
/*               :                                                           
/*  $RCSfile: promload.c,v $
/*  Program Type :                                                           
/*  Sub-modules  :                                                           
/*                                                                           
/****************************************************************************
/*  S W   D e v e l o p m e n t   E n v i r o n m e n t                      
/*                                                                           
/*  Host system  :                                                           
/*  SW Compiler  :                                                           
/*  Author Daniele Cortesi $
/*               :                                                           
/****************************************************************************
/*  U p d a t i n g                                                          
/*  10/07/20000  -  Created                                                                        
/*
/*  $Log: promload.c,v $
/*  Revision 1.1.1.1  2006/04/25 09:00:20  kusanagi
/*  These program extract in an XML format the info contained into the ROOT files generated by YODA from the PAMELA data. To visualize the XML files in a more human readable format a collection of XSL files are given in the Data subfolder.
/*
/*  Revision 1.1.1.1  2003/08/04 09:40:21  sebastiani
/*  Imported sources laben rel. 19.06.2003 integrated with pam2
/*
/*  Revision 1.5  2002/07/25 09:24:46  zulia
/*  FM PROM - Configurated version
/*
/*  Revision 1.4  2002/07/16 07:12:50  zulia
/*  setup for 4MB
/*
/*  Revision 1.3  2002/05/09 08:16:34  zulia
/*  *  acceptance release
/*
/*                                                                           
/*****************************************************************************/


/*****************************************************************************/
/*  Copyright (C) 2000  LABEN  all rights reserved                           */
/*****************************************************************************/


/*============================= Include File ================================*/

#include <src/BootStrap/Boot/la695eEos.h>
#include <src/BootStrap/Boot/la695e.h>

/*****************************************************************************/
/*============================= Local define ================================*/

/** GPI data Register (to see if the test connector is connected) **/
#define GPI_DAT_REG        0xac
/** Pin 0 of GPI (If ==0x08 TEST CONNECTOR connected) **/
#define TEST_PIN           0x08

#define	USR	           0xe8/4
#define TXA	           0xe0/4
#define ERSR	           0xb0/4

#define	SECMAX	           32
#define	SECNAME	           16

typedef struct sectype {
    unsigned int    paddr;
    unsigned int    raddr;
    unsigned int    len;
    unsigned int    comp;
    unsigned char   name[SECNAME];
}tt;


extern char     filename[];
extern struct sectype sections[];
extern int      prot;

void
putsx(s)
    unsigned char  *s;
{
    volatile unsigned int *mec = (unsigned int *) 0x1f80000;

    while (s[0] != 0) {
	while ((mec[USR] & 4) == 0);
	mec[TXA] = *s;
	s++;
    }
}

memprotect(start, end)
    unsigned int    start, end;
{
    int             sbr, ser;
    volatile unsigned int *mec = (unsigned int *) 0x1f80000;

    mec[0x24 / 4] = ((end & 0x007fffff) >> 2);
    mec[0x20 / 4] = ((start & 0x007fffff) >> 2) | 0x01800000;
}

extern int stack;
set_stack(top)
unsigned int top;
{
    asm("
    	retl
    	mov %o0, %sp
	");
}

__main()
{
}

/*****************************************************************************/
/*========================== Global Function prototype ======================*/
int  eosBoardTest (void) ;
int  eosEepromCheckSumTest (void);

/*============================ Extern Variables =============================*/
extern int  ramsize, etext, freq;
void        clean();
extern int  Decode();
extern char configmsg[];

main()
{
    unsigned char  *p;
    int             paddr, raddr, len, secnum;
    void            (*prog) ();
    int             (*func) ();
    char    	    pbuf[8192];
    volatile unsigned int *mec = (unsigned int *) 0x1f80000;

    prog = (void *) sections[0].paddr;
    putsx("\n\n\r  ERC32 boot loader v1.1\n\n\r");
    putsx(configmsg);
    putsx("\n\r");
    mmov(clean,pbuf,0x100);
    putsx("  initialising ram memory\n\r");
    func = (void *)pbuf;
    func(0x2000000,ramsize - 0x10000);
    secnum = 0;

    /**-------------------------------------------------------------
     **----   check on TEST CONNECTOR -->
     **----               if not CONNECTED load APPLICATION
     **----               else load MONITOR(section 0,1)
     **----
     **-------------------------------------------------------------
     **/

    if (mec[GPI_DAT_REG / 4] & TEST_PIN)
    {
        /** TEST CONNECTOR not connected **/
        putsx("\n\r  ************  STARTING APPLICATION  **********\n\r");

        mec[0x20 / 4] = 0;
        mec[0x24 / 4] = 0;
        mec[0x14 / 4] =0x0000001f;

        prog = (void *) RAM_START_EXE;
        //prog =(void*)0x02001000;

        raddr =EEPROM_START_EXE;
        paddr =RAM_START_EXE;
        len   =EEPROM_LEN_EXE;
        putsx("  Loading .text \n\r");
        putsx("  Loding  .data \n\r");

        func = (void *)((int)mmov + (int)pbuf - (int)clean);
        func(raddr, paddr,len);
        putsx("\n\r  End\n\r");

        *((int *) (RAM_START_EXE + 0x7e0)) = freq;
    }
    else
    {
        /** TEST CONNECTOR connected **/
        putsx("\n\r  ************* STARTING MONITOR  **************\n\r");

        while (sections[secnum].paddr)
        {
	    paddr = sections[secnum].paddr;
	    raddr = sections[secnum].raddr;
	    len = sections[secnum].len;
            putsx("  loading ");
            putsx(sections[secnum].name);
            putsx("\n\r");
            func = (void *)((int)mmov + (int)pbuf - (int)clean);
	    func(raddr, paddr,len);
	    secnum++;
        }
        if (prot)
        {
	    memprotect(sections[0].paddr + 0x1000,
	        sections[0].paddr + sections[0].len);
        }
        putsx("\n\r  End\n\r");
        *((int *) (sections[0].paddr + 0x7e0)) = freq;
    }

    putsx("\n\r  ****** Program running ******\n\r");
    prog();
}

void clean(paddr,len)
double *paddr;
int len;
{
    len >>=3;
    while (len >= 0) {
    	paddr[len] = 0;
	len--;
    }
}

mmov(raddr,paddr,len)
int *raddr, *paddr;
int len;
{
    len >>=2;
    while (len >= 0) {
    	paddr[len] = raddr[len];
	len--;
    }
}



/*****************************************************************************/
/*=================== I N T E R N A L   F U N C T I O N S  ==================*/
/*****************************************************************************
*
* eosBoardTest - test TSC695E of LA695E-CORE board
*
* This routine perform the test of TSC695E by using the testing facility
* offered by the MEC Test Control Register
*
* The routine does not use RAM
* The Interrupt Test is not done because it needs RAM
*
* RETURNS:
*       BIT_OK
*       BIT_NOK_EDAC_TEST
*       BIT_NOK_PARITY_TEST
*       BIT_NOK_INTERRUPT_TEST  never
*       BIT_NOK_ERROR_TEST
*       any OR combination of BIT_NOK_xx
*
*
*/

int eosBoardTest (void)
{
unsigned int register eosBoardTestResult;
unsigned int          tmpData;

    eosBoardTestResult =0;

    if (edacTest()!= OK)
        eosBoardTestResult |=BIT_NOK_EDAC_TEST;
/*
    if (parityTest()!= OK)
        eosBoardTestResult |=BIT_NOK_PARITY_TEST;
*/
    if (interruptTest()!= OK)
        eosBoardTestResult |=BIT_NOK_INTERRUPT_TEST ;

    if (errorTest()!= OK)
        eosBoardTestResult |=BIT_NOK_ERROR_TEST;

    return (eosBoardTestResult);

}

/*******************************************************************************
*
* edacTest - test EDAC functionalities   
*
*
*/

int edacTest (void)
    {
    if (edacSefTest() != OK)
        return (NOK) ;
    if (edacDefTest() != OK)
        return (NOK);
    if (edacNoErrorTest() != OK)
        return (NOK);
    return(OK) ;
    }

/*******************************************************************************
*
* edacSefTest -   test the EDAC capability to detect and correct a single error
*
* RETURNS:
*	OK
*	NOK
*/

asm("
	.text
	.global _edacSefTest



_edacSefTest:
	save					! New window
		
 
        ! Enable traps
        mov     %psr, %l0                       ! %l0 saved psr
        or      %l0, 0x20, %l1                  ! psr.et=1
        mov     %l1, %psr
        nop
        nop
        nop
 
        ! EDAC enable
        ! set to 1 rec bit (14) of MemoryConfigurationRegister
        set    0x01f80010, %l1
        ld      [%l1], %l2
        set     0x00004000, %l3
        or      %l2, %l3, %l2
        st      %l2, [%l1]
 
        ! clear interrupt level 6 EDAC SEF
        ! set to 1 bit 6 of InterruptClearRegister */
        set     0x01f80050, %l1
        set     0x00000040, %l2
        st      %l2, [%l1]
 
        ! initialise test locations
	! GM
        set     0x02000000, %l1       ! first RAM valid address 
        st      %g0, [%l1]
        set     0x023ffffc, %l2       ! last RAM valid address (4MB)
        st      %g0, [%l2]
 
        set     0x01f800d0, %l2                 ! %l2 TestControlRegister
        set     2, %l3                          ! %l3 loop counter                                                                 

 
SEF_LOOP:
 
        ! Set EDAC test bits in TestControlRegister
        ! et = 1        meaning EDAC test enabled
        ! cb = 0010000  check bit of pattern 0x0 with 1 bit failed
        !               (cb correct is 0010100)
        ld      [%l2] , %l4
        set     0x00020010, %l5
        or      %l4 , %l5 , %l4
        st      %l4 , [%l2]
 
        ! store test value in test location
        clr     %l4
        st      %l4 , [%l1]
 
        ! Set ET =0 in TestControlRegister
        ld      [%l2] , %l4
        set     0x00020000, %l5
        andn    %l4 , %l5 , %l4
        st      %l4 , [%l2]
 
        ! read back test location
        ld      [%l1] , %l4
 
        ! If read back value is not the written value i.e. 0 then jump
        cmp     %l4, 0
        bne     SEF_LOOP_TEST
        nop
   
SEF_INPT_PEND_TEST:
        ! test if intp level 6 is pending
        set    0x01f80048, %l5               ! InterruptPendingRegister
        ld      [%l5], %l5
        andcc   %l5, 0x40, %l5                  ! 0x40 mask for int lev 6
        bnz     SEF_OK
        nop
 
SEF_LOOP_TEST:
	! dove e' implementato la scansione della memoria ???????
        set     0x023ffffc, %l1             ! %l1 last RAM valid address (4MB)
        subcc   %l3, 1, %l3
        bnz     SEF_LOOP
        nop
 
SEF_FAIL :
        mov     1, %i0                          ! i0 = 1 -> NOK
        ba      SEF_END
        nop
 
SEF_OK :
        mov     0, %i0                          ! i0 = 0 -> OK
 
SEF_END :
        ! restore psr
        mov     %l0, %psr
        nop
        nop
        nop
 
        ret
        restore
        nop                                                                                                                        

") ;


 
    
/*******************************************************************************
*
* edacDefTest - test the EDAC capability to detect a double error   
*
* RETURNS: 
*	OK
*	NOK
*
*/

asm("
	.text
	.global _edacDefTest

_edacDefTest:

	save					! New window
	set	0x02000010, %l6			!TBD for debug

	! Enable traps
	mov	%psr, %l0			! %l0 saved psr
	or	%l0, 0x20, %l1			! psr.et=1
	mov	%l1, %psr
	nop
	nop
	nop
!	st	%l1, [%l6]			!TBD for debug
	
	! sethi	%hi(TRAP_TABLE_TEST), %l6       ! Sets trap table for test
      	! mov	%l6, %tbr

	! EDAC enable
	! set to 1 rec bit (14) of MemoryConfigurationRegister
	set	0x01f80010, %l1
	ld	[%l1], %l2
	set	0x00004000, %l3
	or	%l2, %l3, %l2
	st	%l2, [%l1]
!	st	%l2, [%l6]			!TBD for debug
	
        ! Mask IU Error Mode in SystemControlRegister
        ! set to 1 iuemmsk bit 5
	set	0x01f80000, %l1
	ld	[%l1], %l2
	or	%l2, 0x20, %l2
	st	%l2, [%l1]
!	st	%l2, [%l6]			!TBD for debug

	set	0x01f800d0, %l2			! %l2 TestControlRegister	
	set	2, %l3				! %l3 loop counter
	set	0x01f800a0, %l7			! %l7 SystemFaultStatusRegister	

        ! initialise test locations
	! GM
        set     0x02000000, %l1                 ! first RAM valid address
        st      %g0, [%l1]
	! end GM

DEF_LOOP:
	! Set EDAC test bits in TestControlRegister
	! et= 1        meaning EDAC test enabled
	! cb= 0000000  check bit of pattern 0x00000000 with two bits failed TBD
	!              (cb correct is 0010100) 
	ld	[%l2] , %l4
	set	0x0002007f, %l5			
	andn	%l4 , %l5 , %l4			! clear et and cb
	set	0x00020000, %l5
	or	%l4 , %l5 , %l4			! set cb
	st	%l4 , [%l2]
!	st	%l4, [%l6]			!TBD for debug
	
	! store test value in test location
	clr	%l4
	st	%l4 , [%l1]
!	st	%l4, [%l6]			!TBD for debug
	
	! Set et=0 and cb=0 in TestControlRegister
	ld	[%l2] , %l4
	set	0x0002007f, %l5
	andn	%l4 , %l5 , %l4
	st	%l4 , [%l2]
!	st	%l4, [%l6]			!TBD for debug

	! read back test location
	ld	[%l1] , %l4
	nop
	nop
		
	!Double Error Should have been detected
	!Read System Fault Status register
	ld	[%l7] , %l4
!	st	%l4, [%l6]			!TBD for debug
	and	%l4, 0x7c, %l4			! GM was 0x78
	cmp	%l4, 0x3c			! GM was 0x38
	be	DEF_OK
	nop
	
DEF_LOOP_TEST :
	set	0x023ffffc, %l1			! last RAM valid address (4MB)
	subcc	%l3, 1, %l3
	bnz	DEF_LOOP
	nop
			
DEF_FAIL :
	mov	1, %i0				! i0 = 1 -> NOK
	ba	DEF_END
	nop

DEF_OK :
	mov	0x7c, %l4			! 18-sep-01 GM reset System Fault Status register
	st      %l4, [%l7]			!  ""       GM 

	mov	0, %i0				! i0 = 0 -> OK	
	
DEF_END :

	! sethi	%hi(TRAP_TABLE), %l6            ! Restores default trap table
       	! mov	%l6, %tbr

	! restore psr
	mov	%l0, %psr
	nop
	nop
	nop

	ret
	restore
	nop	

") ;


/*******************************************************************************
*
* edacNoErrorTest -   test the EDAC behaviour in case of no error
*
* RETURNS: 
*	OK
*	NOK
*/

asm("
	.text
	.global _edacNoErrorTest

_edacNoErrorTest:
	save					! New window
	set	0x02000010, %l6			!TBD for debug

	! Enable traps
	mov	%psr, %l0			! %l0 saved psr
	or	%l0, 0x20, %l1			! psr.et=1
	mov	%l1, %psr

	! EDAC enable
	! set to 1 rec bit (14) of MemoryConfigurationRegister
	set	0x01f80010, %l1
	ld	[%l1], %l2
	set	0x00004000, %l3
	or	%l2, %l3, %l2
	st	%l2, [%l1]

	! clear interrupt level 6 EDAC SEF
	! set to 1 bit 6 of InterruptClearRegister
	set	0x01f80050, %l1
	set	0x00000040, %l2
	st	%l2, [%l1]

	set	0x01f80048, %l2			! %l2 InterruptPendingRegister	
	set	2, %l3				! %l3 loop counter

        ! initialise test locations
	! GM
        set     0x02000000, %l1                 ! first RAM valid address
    !    st      %g0, [%l1] !GP 13-12-01 executed after
	! end GM

NOERROR_LOOP:
	! store test value in test location	
	clr	%l4	
	st	%l4 , [%l1]
	nop
	nop

	! read back
	ld	[%l1] , %l5

	! compare written value with the read back one	
	cmp	%l4 , %l5
	bne	NOERROR_LOOP_TEST
	nop

NOERROR_INTP_PEND_TEST:
	ld	[%l2], %l5
	st	%l5, [%l6]			!TBD for debug
	andcc	%l5, 0x40, %l5			! 0x40 mask for int lev 6
	bz	NOERROR_OK
	nop

NOERROR_LOOP_TEST:
	set	0x023ffffc, %l1			! last RAM valid address (4MB)
	subcc	%l3, 1, %l3
	bnz	NOERROR_LOOP
	nop
	
NOERROR_FAIL :
	mov	1, %i0				! i0 = 1 -> NOK
	ba	NOERROR_END
	nop
	
NOERROR_OK :
	mov	0, %i0				! i0 = 0 -> OK
	
	
NOERROR_END :
	! restore psr
	mov	%l0, %psr
	nop
	nop
	nop
	
	ret
	restore
	nop	

");
  

/**************************************************************************
*
* edacTh -
*
* RETURNS
*
*/

asm("
	.text
	.global _edacTh

_edacTh:
	
	jmp	%l2			! Jump to nPC
	rett	%l2 + 4
	nop
") ;


/*******************************************************************************
*
* interruptTest   -   interrupt test 
*
* DESCRIPTION
* Saves interrupts status, switches to the test trap table, sets interrupt test 
* mode and uses the IFR to force interrupts. The routine checks if the asynchronous 
* trap routine starts.
* Finally restores interrupt status, the previous trap table (default) and returns the 
* result OK (0) or NOK (1). The bootstrap log record is updated in builtInTest. 
*
*/
    
asm("
	.text
	.global _interruptTest

_interruptTest:
 	save					! New window

	! enable traps
	mov	%psr, %l0			! %l0 saved psr
	and     %l0, 0xfffff0ff, %l1            ! Clear pil bits: enable all traps
	or	%l1, 0x20, %l1			! psr.et=1
	mov	%l1, %psr
	nop
	nop
	nop
	
	set     0x01f80044, %l3
	set     0x01f, %l1
        st      %l1,[%l3]			! Set all ext INT to edge
	
	! save IMR
	set	0x01f8004c, %l3			! %l3 InterruptMaskReg
	ld	[%l3], %l7			! saves interrupt mask reg to on l3
 
 	! change TBR 
	! sethi	%hi(TRAP_TABLE_TEST), %l4       ! trap table for test
	! mov	%l4, %tbr
 
 	! enable write on IFR
 	set	0x01f800d0, %l3			! %l3 TestControlReg
        ld      [%l3], %l5			! TestControlReg value
        set     0x00080000, %l6			! it bit = 1
        or      %l5, %l6, %l5 			! sets et bit
        st      %l5, [%l3]			! updates TestControlReg
        
        ! loop for the actual int test 	tr
        mov 	%g0, %o0			! resets the result flag		
	set	0x7ffe, %l4			! bit mask for IMR
	set	0x8000, %l5			! bit mask for IFR
	mov	%l4, %l6			! aux bit mask for IMR (0x7ffe)

 INT_CHECK_LOOP:
 	set	0x01f8004c, %l3			! %l3 InterruptMaskRegister
        st 	%l4, [%l3]			! unmask the i-th int to test
	set	0x01f80054, %l3			! %l3 InterruptForceRegister   	
        st 	%l5, [%l3]			! force i-th interrupt   
        nop     
        nop     
        nop     
        nop     
        nop     
        nop     
        nop     
        nop     
        nop     
        nop     
        nop     
        nop     
        srl	%l5, 1, %l5			! new mask for the next int (IFR)
        not	%l5, %l4			
        and	%l4, %l6, %l4			! new mask for the next int (IMR)
        subcc	%l5, 1, %g0			! compare end of loop
	bnz	INT_CHECK_LOOP
	nop                     

        ! result test
        set	0xfffe, %l5			
        subcc	%o0, %l5, %g0			! if %o0 == 0xfffe, test OK, else NOK
        be	INT_OK
        nop
    
 INT_FAIL:
   	mov	1, %i0				! i0 = 1 -> NOK
	ba	INT_END
	nop
 INT_OK:
        mov	0, %i0				! i0 = 0 -> OK		
				
 INT_END:
 	! clear any pending int
        set	0x01f80050, %l3			! %l3 InterruptClearRegister
        set	0xfffe, %l5
        st      %l5, [%l3] 			! resets ICR (0xfffe)
 
 	! restore int mask reg status
 	set	0x01f8004c, %l3			! %l3 InterruptMaskRegister
	st	%l7, [%l3]			! restores interrupt mask reg to on l3
 
	! disable write on IFR
        set	0x01f800d0, %l3			! %l3 TestControlRegister
        ld      [%l3] , %l5			! TCR value
        set     0x0016007f, %l6			! et bit = 0
        and     %l5 , %l6 , %l5 		! resets et bit
        st      %l5 , [%l3]			! updates the TCR
 
 	! restore trap table
        ! sethi	%hi(TRAP_TABLE), %l4       	! default trap table
	! mov	%l4, %tbr

	! restore psr
	mov	%l0, %psr
	nop
	nop
	nop

	ret
	restore
	nop	

");

/*******************************************************************************
*
* intpTh -
*
* RETURNS
*
*/

asm("
	.text
	.global _intpTh

_intpTh:
	rd 	%tbr, %l3 		! rdtbr trap table reg

	! prepare int index
	srl	%l3, 4, %l3 
	and	%l3, 0x000000ff, %l3
	sub	%l3, 16, %l3
	
	set	0x00000001, %l4
	sll	%l4, %l3, %l4		! set i-th int bit
	or	%i0, %l4, %i0		! output paramenter
		
	jmp	%l2			! Jump to nPC
	rett	%l2 + 4
	nop
") ;




/*******************************************************************************
*
* errorTest -  test the capability of TSC695E to detect errors
*
* DESCRIPTION:
*	phylosophy : by enabling ewe bit in TestControlRegister, an error could be
*	simulated by setting to 1 the followings bits in Error&ResetStatusRegister,
*		iuem
*		iuhe
*		syshe
*		(fpuhe=1 causes nothing according to fig.13 DataSheetRevE TBD)
*	The check is done by verifing that int lev 1 ("Masked hardware errors") is 
*	pending.
*	So first int lev 1 shall be masked then the simulated errors shall be masked
*	in SystemControlRegister setting to 1 the bits
*		iuemmsk
*		iuhemmsk
*		syshemsk
* RETURNS:
*	OK
*	NOK
*
*/
asm("
	.text
	.global _errorTest

_errorTest:
	save					! New window
	
	! save InterruptMaskRegister
	set	0x01f8004c, %l0
	ld	[%l0], %l0			! %l0 InterruptMaskRegister

	! save SystemControlRegister
	set	0x01f80000, %l1
	ld	[%l1], %l1			! %l1 SystemControlRegister
	
	! clear Pending Interrupt
	set	0x01f80050, %l2
	set	0xfffe, %l3
	st	%l3, [%l2]
	
	! mask all int levs
	set	0x01f8004c, %l2
	set	0x00007ffe, %l3			
	st	%l3, [%l2]
	
	! Enable Error Write (ewe bit20) in TestControlRegister
	! ewe= 1        meaning Write to Error&ResetStatusRegister enabled
	set	0x01f800d0, %l2
	!set	0x00010000, %l3 GP 15-10-01
	set	0x00100000, %l3!GP 10-12-01 si dovrebbe fare un OR non un set  
	st	%l3, [%l2]



	        !****************** 1) IU Error Mode *********************
		! In SystemControlRegister mask the error which is going to be injected
		! IU Error Mode
		set	0x01f80000, %l2
		set	0x20, %l3		! iuemmsk bit (bit 5)
		or	%l1, %l3, %l3
		st	%l3, [%l2]
	
		! inject IU error
		! set to 1 bit 0 iuem in Error&ResetStatusRegister
		set	0x01f800b0, %l2
		set	0x1, %l3		! iuem bit (bit 0)!GP 10-12-01 si dovrebbe fare un OR non un set  
		st	%l3, [%l2]
	
		! int lev 1 should be pending
		! set	0x01f80050, %l2
		set	0x01f80048, %l2
		ld	[%l2], %l2
		andcc	%l2, 2, %l2
		bz	ERROR_FAIL
		nop
	
		! Rollback Error&ResetStatusRegister
		set	0x01f800b0, %l2
		set	0x0, %l3
		st	%l3, [%l2]

		! clear int lev 1 pending
		set	0x01f80050, %l2
		set	0x2, %l3
		st	%l3, [%l2]





	        !****************** 2) IU HW Error *********************
		! restore initial value of  SystemControlRegister
		set	0x01f80000, %l2
		st	%l1, [%l2]
	
		! In SystemControlRegister mask the error which is going to be injected
		! IU HW Error
		set	0x01f80000, %l2
		set	0x80, %l3			! iuhemmsk bit (bit 7)
		or	%l1, %l3, %l3
		st	%l3, [%l2]
	
		! inject IU HW error
		! set to 1 bit 0 iuhe in Error&ResetStatusRegister
		set	0x01f800b0, %l2
		set	0x2, %l3			! iuhe bit (bit 1)
		st	%l3, [%l2]
	
		! int lev 1 should be pending
		! set	0x01f80050, %l2
		set	0x01f80048, %l2
		ld	[%l2], %l2
		andcc	%l2, 2, %l2
		bz	ERROR_FAIL
		nop
		
		! Rollback Error&ResetStatusRegister
		set	0x01f800b0, %l2
		set	0x0, %l3
		st	%l3, [%l2]

		! clear int lev 1 pending
		set	0x01f80050, %l2
		set	0x2, %l3
		st	%l3, [%l2]
	




	        !****************** 3) SYStem HW Error *********************
		! restore initial value of  SystemControlRegister
		set	0x01f80000, %l2
		st	%l1, [%l2]
	
		! In SystemControlRegister mask the error which is going to be injected
		! SYStem HW Error
		set	0x01f80000, %l2
		set	0x2000, %l3			! syshemsk bit (bit 13)
		or	%l1, %l3, %l3
		st	%l3, [%l2]
	
	        ! inject SYSstem HW error
		! set to 1 bit 0 syshe in Error&ResetStatusRegister
		set	0x01f800b0, %l2
		set	0x20, %l3			! syshe bit (bit 5)
		st	%l3, [%l2]
	
		! int lev 1 should be pending
		! set	0x01f80050, %l2
		set	0x01f80048, %l2
		ld	[%l2], %l2
		andcc	%l2, 2, %l2
		bz	ERROR_FAIL
		nop
	
		! Rollback Error&ResetStatusRegister
		set	0x01f800b0, %l2
		set	0x0, %l3
		st	%l3, [%l2]

!		nop	
!		nop	
!		nop	
!		nop	
!		nop	
!		nop	
!		nop	
!		nop	


ERROR_OK:
	mov	0, %i0				! i0 = 0 -> OK
	ba	ERROR_END
	nop
	
ERROR_FAIL:
	mov	1, %i0				! i0 = 1 -> NOK

ERROR_END:
	! clear int lev 1 pending
	set	0x01f80050, %l2
	set	0x2, %l3
	st	%l3, [%l2]

	! Disable Error Write (ewe bit20) in TestControlRegister
	! ewe= 0
	set	0x01f800d0, %l1
	clr	%l2
	st	%l2, [%l1]

	! restore InterruptMaskRegister
	set	0x01f8004c, %l2
	st	%l0, [%l2]

	! restore SystemControlRegister
	set	0x01f80000, %l2
	st	%l1, [%l2]

!        nop	
!        nop	
	ret
!        nop	
!        nop	
	restore
        nop	
!        nop	

");


/******************************************************************************
*
* eosEepromCheckSumTest - perform the CRC test on EEPROM of LA695E-CORE board
*
*
* RETURNS:
*       EEPROM_TEST_OK
*       EEPROM_TEST_NOK
*
*/

int eosEepromCheckSumTest (void)
{

unsigned short crc;
unsigned int   lenApp;
unsigned short crcApp;
unsigned int*  pEE;
unsigned char  ch;
unsigned int   temp;
unsigned int   status;
int            i;

    lenApp =EEPROM_LEN_EXE;
    crcApp =*((unsigned int*)(EEPROM_START_EXE + EEPROM_LEN_EXE - 4));
    pEE =(unsigned int*)(EEPROM_START_EXE);
    for (i=0, crc=0xffff; i< lenApp-8; i += 4,pEE++ )
    {
        temp =*pEE;
        ch  =(unsigned char)((temp>>24) & 0x000000ff);
        crc =crcComp(&ch,crc);
        ch  =(unsigned char)((temp>>16) & 0x000000ff);
        crc =crcComp(&ch,crc);
        ch  =(unsigned char)((temp>>8) & 0x000000ff);
        crc =crcComp(&ch,crc);
        ch  =(unsigned char)(temp & 0x000000ff);
        crc =crcComp(&ch,crc);
    }

    if (crc == crcApp)
    {
        status =EEPROM_TEST_OK;
    }
    else
    {
        status =EEPROM_TEST_NOK;
    }
    return(status);

}


/*****************************************************************************/
/* @Function: PD_ifcrcComp                                                   */
/* @Purpose :                                                                */
/*  This function calculates the CRC.                                        */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* @@                                                                        */
/*****************************************************************************/
unsigned short crcComp (unsigned char* adrs, unsigned short Crc)
{
unsigned int Crc16Value;

    Crc16Value =Crc;
    // Calculating the CRC16 by using a LookUp table
    Crc16Value = (unsigned int)(Crc16Value << 8) ^
                 (unsigned int)(Crc_lookup[ (unsigned int) ( ((Crc16Value >> 8) &
                  0xFF) ^ *adrs) ]);
    return ((unsigned short)Crc16Value);

}
