
/*
 *
 * FILE : MPC5675K_HWInit.c
 *
 * DESCRIPTION:
 *  This file contains all MPC5675K derivative needed initializations, 
 *  and all initializations for the MPC5675K boards which are supported.
 *  This includes setting up the External Bus Interface to allow access
 *  to memory on the external bus, and ensuring there is a valid entry in
 *  the MMU for the external memory access.
 */

/*----------------------------------------------------------------------------*/
/* Includes                                                                   */
/*----------------------------------------------------------------------------*/

#include "MPC5675K.h"       /* MPC55xx platform development header            */
#include "MPC5675K_HWInit.h"

#ifdef __cplusplus
extern "C" {
#endif

/*******************************************************/
/* MPC5675K derivative specific hardware initialization */
/*******************************************************/

/*----------------------------------------------------------------------------*/
/* Function declarations                                                      */
/*----------------------------------------------------------------------------*/

/* All these functions must be located in the initial 4KB memory window (.init) 
	and implemented "nofralloc" so as to not use the stack */

/* Memory initialization */
__declspec(section ".init") __asm void INIT_Derivative(void);

/* This macro allows to use C defined address with the inline assembler */
#define MAKE_HLI_COMPATIBLE(hli_name, c_expr) enum { hli_name=/*lint -e30*/((int)(c_expr)) };


/*----------------------------------------------------------------------------*/
/* Function implementations                                                   */
/*----------------------------------------------------------------------------*/

/* Symbol L2SRAM_LOCATION is defined in the application linker command file (.lcf) 
   It is defined to the start of the L2SRAM of the MPC5675K. 
*/
/*lint -esym(752, L2SRAM_LOCATION) */
extern long L2SRAM_LOCATION;  

__asm void INIT_Derivative(void) 
{
nofralloc
#ifdef LOCKSTEP_MODE
	/* until now, the code has used(set) the following registers LR, R1, R2, R13, R3, R31, R30
	 and they should not altered */
	xor  r0, r0, r0
	evmergelo r0,r0,r0

	evmergelo r1,r0,r1 //used by runtime - should preserve lower 32bits
	evmergelo r2,r0,r2 //used by runtime - should preserve lower 32bits
	evmergelo r3,r0,r3 //used by runtime - should preserve lower 32bits
	
	evmergelo r4,r0,r0
	evmergelo r5,r0,r0
	evmergelo r6,r0,r0
	evmergelo r7,r0,r0
	evmergelo r8,r0,r0
	evmergelo r9,r0,r0
	evmergelo r10,r0,r0
	evmergelo r11,r0,r0
	evmergelo r12,r0,r0
	
	evmergelo r13,r0,r13 //used by runtime - should preserve lower 32bits

	evmergelo r14,r0,r0
	evmergelo r15,r0,r0
	evmergelo r16,r0,r0
	evmergelo r17,r0,r0
	evmergelo r18,r0,r0
	evmergelo r19,r0,r0
	evmergelo r20,r0,r0
	evmergelo r21,r0,r0
	evmergelo r22,r0,r0
	evmergelo r23,r0,r0
	evmergelo r24,r0,r0
	evmergelo r25,r0,r0
	evmergelo r26,r0,r0
	evmergelo r27,r0,r0
	evmergelo r28,r0,r0
	evmergelo r29,r0,r0
	
	evmergelo r30,r0,r30 //used by runtime - should preserve lower 32bits
	evmergelo r31,r0,r31 //used by runtime - should preserve lower 32bits

	// 2.  32-bit DEAR (spr 61)
	mtspr 61,r0         //DEAR

	//3.  32-bit SPRG0-9 (spr 272-279, 604 & 605)

	mtspr 272,r0        //SPRG0-7
	mtspr 273,r0
	mtspr 274,r0
	mtspr 275,r0
	mtspr 276,r0
	mtspr 277,r0
	mtspr 278,r0
	mtspr 279,r0

	mtspr 604,r0         //SPRG8-9
	mtspr 605,r0

	//4.  32-bit USPRG0 (spr 256)

	mtspr 256,r0         //USPRG0

	//5.  32-bit SRR0 (spr 26), SRR1 (spr 27), CSRR0 (spr58), CSRR1 (spr59),
	//		DSRR0 (spr 574), DSRR1 (spr 575), MCSRR0 (spr570), MCSRR1 (spr571)

	mtspr 26,r0          //SRR0-1
	mtspr 27,r0
	mtspr 58,r0          //CSRR0-1
	mtspr 59,r0
	mtspr 570,r0         //MCSRR0-1
	mtspr 571,r0 
	mtspr 574,r0         //DSRR0-1 
	mtspr 575,r0      
    
	//6.  32-bit IVPR (spr 63)

	mtspr 63,r0          //IVPR
	mtspr 62,r0          //ESR
	mtspr 340,r0         //TCR
	mtspr 512,r0         //SPEFSCR
	mtspr 1,r0           //XER
	mtspr 256,r0         //USPRG0 
 

	//32-bit IVOR0-15 (spr 400 - 415), IVOR 32-35 (spr 528 - 531)

	mtspr 400,r0         //IVOR0-15
	mtspr 401,r0
	mtspr 402,r0
	mtspr 403,r0   
	mtspr 404,r0
	mtspr 405,r0
	mtspr 406,r0
	mtspr 407,r0
	mtspr 408,r0
	mtspr 409,r0
	mtspr 410,r0
	mtspr 411,r0
	mtspr 412,r0
	mtspr 413,r0
	mtspr 414,r0
	mtspr 415,r0

	mtspr 528,r0         //IVOR32-34 (IVOR35 not in Leopard)
	mtspr 529,r0
	mtspr 530,r0
	
	mtspr 531,r0		 //IVOR35 KOMODO ONLY

	//8.  32-bit MCAR (spr 573)

	mtspr 573,r0         //MCAR
 
	//9. 32-bit TBL, TBU (spr 284, 285)

	mtspr 284,r0         //TBL
	mtspr 285,r0         //TBU
 
	//10. 32-bit DEC, DECAR (spr 22, 54)

	mtspr 22,r0          //DEC
	mtspr 54,r0          //DECAR

	//11. 64-bit DVC1, DVC2 (spr 318, 319)
	//Note most debug registers are reset by POR so initialization is not required.

	mtspr 318,r0         //DVC1
	mtspr 319,r0         //DVC2

	//12. 32-bit DBCNT (spr 562)

	mtspr 562,r0         //DBCNT
	
	// initialize MAS0 - MAS6; actual TLB configuration done later
	mtmas0 r0
	mtmas1 r0
	mtmas2 r0
	mtmas3 r0
	mtmas4 r0
	// no MAS5
	mtmas6 r0
	
	// init ACC
	evmra r0, r4
	evmra r0, r4
	
	mtcrf 0xFF,r0 // CFR
	mtspr 9,r0 // COUNT
#endif

/////////////////////////////////////////////////////////////////////////////
	/* MMU initialization for Flash target */
	/* TLB_1 0 Flash 16MB @0x00000000 */
	lis     r3, 0x1000
    mtMAS0  r3

    lis     r4, 0xC000
    ori     r4, r4, 0x0700
    mtMAS1  r4

#if __option(vle) 
    lis     r5, 0x0000
    ori     r5, r5, 0x0020
#else
    lis     r5, 0x0000
    ori     r5, r5, 0x0000
#endif
    mtMAS2  r5

    lis     r6, 0x0000
    ori     r6, r6, 0x003f
    mtMAS3  r6

    msync
    tlbwe
    isync
    
    /* TLB_1 1 External Bus Interface (EBI) 512MB @0x20000000 */
	lis     r3, 0x1001
    mtMAS0  r3

    lis     r4, 0xC000
    ori     r4, r4, 0x0980
    mtMAS1  r4

#if __option(vle) 
    lis     r5, 0x2000
    ori     r5, r5, 0x0020
#else
    lis     r5, 0x2000
    ori     r5, r5, 0x0000
#endif
    mtMAS2  r5

    lis     r6, 0x2000
    ori     r6, r6, 0x003f
    mtMAS3  r6

    msync
    tlbwe
    isync
#ifdef LOCKSTEP_MODE
	/* TLB_1 2 Internal SRAM 512KB @0x40000000 */
   	lis     r3, 0x1002
    mtMAS0  r3

    lis     r4, 0xC000
    ori     r4, r4, 0x0480
    mtMAS1  r4

#if __option(vle) 
    lis     r5, 0x4000
    ori     r5, r5, 0x0020
#else
    lis     r5, 0x4000
    ori     r5, r5, 0x0000
#endif
    mtMAS2  r5

    lis     r6, 0x4000
    ori     r6, r6, 0x003f
    mtMAS3  r6

    msync
    tlbwe
    isync
#else
    /* TLB_1 2 Internal SRAM 256KB @0x40000000 */
   	lis     r3, 0x1002
    mtMAS0  r3

    lis     r4, 0xC000
    ori     r4, r4, 0x0400
    mtMAS1  r4

#if __option(vle) 
    lis     r5, 0x4000
    ori     r5, r5, 0x0020
#else
    lis     r5, 0x4000
    ori     r5, r5, 0x0000
#endif
    mtMAS2  r5

    lis     r6, 0x4000
    ori     r6, r6, 0x003f
    mtMAS3  r6

    msync
    tlbwe
    isync

	/* TLB_1 3 Internal SRAM(DPM) 256KB @0x50000000 */
   	lis     r3, 0x1003
    mtMAS0  r3

    lis     r4, 0xC000
    ori     r4, r4, 0x0400
    mtMAS1  r4

#if __option(vle) 
    lis     r5, 0x5000
    ori     r5, r5, 0x0020
#else
    lis     r5, 0x5000
    ori     r5, r5, 0x0000
#endif
    mtMAS2  r5

    lis     r6, 0x5000
    ori     r6, r6, 0x003f
    mtMAS3  r6

    msync
    tlbwe
    isync
#endif

    /* TLB_1 4 DRAM 512MB @0x60000000 */
   	lis     r3, 0x1004
    mtMAS0  r3

    lis     r4, 0xC000
    ori     r4, r4, 0x0980
    mtMAS1  r4

#if __option(vle) 
    lis     r5, 0x6000
    ori     r5, r5, 0x0020
#else
    lis     r5, 0x6000
    ori     r5, r5, 0x0000
#endif
    mtMAS2  r5

    lis     r6, 0x6000
    ori     r6, r6, 0x003f
    mtMAS3  r6

    msync
    tlbwe
    isync
#ifndef LOCKSTEP_MODE
    /* TLB_1 5 Peripherals(DPM) 1MB @0x8FF00000 */
   	lis     r3, 0x1005
    mtMAS0  r3

    lis     r4, 0xC000
    ori     r4, r4, 0x0500
    mtMAS1  r4

    lis     r5, 0x8FF0
    ori     r5, r5, 0x0008
    mtMAS2  r5

    lis     r6, 0x8FF0
    ori     r6, r6, 0x003f
    mtMAS3  r6

    msync
    tlbwe
    isync
#endif

    /* TLB_1 6 Peripherals 2MB @0xC3E00000 */
   	lis     r3, 0x1006
    mtMAS0  r3

    lis     r4, 0xC000
    ori     r4, r4, 0x0580
    mtMAS1  r4

    lis     r5, 0xC3E0
    ori     r5, r5, 0x0008
    mtMAS2  r5

    lis     r6, 0xC3E0
    ori     r6, r6, 0x003f
    mtMAS3  r6

    msync
    tlbwe
    isync

    /* TLB_1 7 Peripherals 2MB @0x0xFFE00000 */
   	lis     r3, 0x1007
    mtMAS0  r3

    lis     r4, 0xC000
    ori     r4, r4, 0x0580
    mtMAS1  r4

    lis     r5, 0xFFE0
    ori     r5, r5, 0x0008
    mtMAS2  r5

    lis     r6, 0xFFE0
    ori     r6, r6, 0x003f
    mtMAS3  r6

    msync
    tlbwe
    isync

/////////////////////////////////////////////////////////////////////////////	

	//watchdog disable
    lis r6,0xfff3 
    ori r6,r6,0x8010 
    li  r7,0xC520 
    stw r7,0x0(r6)
    li  r7,0xD928 
    stw r7,0x0(r6)

    lis r6,0xfff3 
    ori r6,r6,0x8000 
    lis r7,0xff00 
    ori r7,r7,0x10A 
    stw r7,0x0(r6)

    lis r11,L2SRAM_LOCATION@h /* Base address of the L2SRAM, 64-bit word aligned */
    ori r11,r11,L2SRAM_LOCATION@l
	
#ifdef LOCKSTEP_MODE
    li r12,4096 /* Loop cover low SRAM, LSM mode; 512k/4 bytes/32 GPRs = 4096 */
#else
	li r12,2048 /* Loop cover low SRAM, DPM mode; 256k/4 bytes/32 GPRs = 2048 */
#endif
    mtctr r12

    init_l2sram_loop:
        stmw r0,0(r11)        /* Write all 32 GPRs to L2SRAM */
        addi r11,r11,128      /* Inc the ram ptr; 32 GPRs * 4 bytes = 128 */
        bdnz init_l2sram_loop /* Loop for 64k of L2SRAM */

    blr
}

/*******************************************************/
/* MPC5675K boards specific hardware initializations    */
/*******************************************************/


/*----------------------------------------------------------------------------*/
/* Function declarations                                                      */
/*----------------------------------------------------------------------------*/

/* Initialize a set of contiguous PCRs */
__asm void InitPCRs(void); 

/* Initialize the SIU External Bus Interface */
__asm void __initSIUExtBusInterface(void);

/* Initialize the used EBI Chip Selects */
__asm void __initEBIChipSelects(void);


/*----------------------------------------------------------------------------*/
/* Function implementations                                                   */
/*----------------------------------------------------------------------------*/

__asm void INIT_ExternalBusAndMemory(void) 
{
nofralloc

    mflr     r28
    
    /* Initialize the SIU External Bus Interface */
    bl __initSIUExtBusInterface
    /* Initialize the used EBI Chip Selects */
    bl __initEBIChipSelects
    /* TODO: Initialize the needed MMU Table entries for external memory */
    /* bl __initMMUExternalMemory */
    
    mtlr     r28
    
    blr
}


/*----------------------------------------------------------------------------*/
/* SIU External Bus Interface                                                 */
/*----------------------------------------------------------------------------*/

/* Initialize a set of contiguous PCRs:               */
/* r3: the firts PCR to initialize                    */
/* r4: the value to write in the PCRs                 */ 
/* r5: the number of PCRs to initialize               */
__asm void InitPCRs(void) 
{
nofralloc

    mtctr r5                   /* intialize ctr with the number of PCRs to initialize */
    pcr_init_loop:
        sth r4,0(r3)           /* Write r4 to current PCR address */
        addi r3,r3, 2          /* Inc the memory ptr by 2 to point to the next PCR */
        bdnz pcr_init_loop     /* Loop for ctr PCRs */

    blr
}

/* Initialize the SIU External Bus Interface */
__asm void __initSIUExtBusInterface(void)
{ 
MAKE_HLI_COMPATIBLE(SIU_PCR0,&SIU.PCR[0].R)
MAKE_HLI_COMPATIBLE(SIU_PCR4,&SIU.PCR[4].R)
MAKE_HLI_COMPATIBLE(SIU_PCR28,&SIU.PCR[28].R)
MAKE_HLI_COMPATIBLE(SIU_PCR62,&SIU.PCR[62].R)
MAKE_HLI_COMPATIBLE(SIU_PCR64,&SIU.PCR[64].R)
MAKE_HLI_COMPATIBLE(SIU_PCR68,&SIU.PCR[68].R)
nofralloc

    mflr r27

    /*  This initializes the MPC5675K external bus
        Set up the pins
        Address bus PCR 4 - 27
        Configure address bus pins
    */
    lis r3,SIU_PCR4@h          /* First PCR Address bus is PCR 4 */
    ori r3,r3,SIU_PCR4@l
    li r5,24                   /* Loop counter to get all address bus PCR (4 to 27) -> 24 PCRs  */
    li r4, 0x0440              /* PCRs initialization value */
    bl InitPCRs

    /*  Data bus PCR 28-59
        Configure data bus pins
    */
    lis r3,SIU_PCR28@h         /* First PCR for data bus is PCR 28 */
    ori r3,r3,SIU_PCR28@l
    li r5,32                   /* Loop counter to get all data bus PCR (28-59) -> 32 PCRs  */
    li r4, 0x0440              /* PCRs initialization value */
    bl InitPCRs

    /*  Configure minimum bus control pins
        RD/WR  & BDIP PCR 62/63
    */
    lis r3,SIU_PCR62@h         /* First PCR for is PCR 62 */
    ori r3,r3,SIU_PCR62@l
    li r5,2                    /* Loop counter to get all PCR (62-63) -> 2 PCRs  */
    li r4, 0x0440              /* PCRs initialization value */
    bl InitPCRs

    /*  WE[0-4] PCR 64-67
    */
    lis r3,SIU_PCR64@h         /* First PCR for is PCR 64 */
    ori r3,r3,SIU_PCR64@l
    li r5,4                    /* Loop counter to get all PCR (64-67) -> 4 PCRs  */
    li r4, 0x0443              /* PCRs initialization value */
    bl InitPCRs

    /*  OE & TS
    */
    lis r3,SIU_PCR68@h         /* First PCR for is PCR 68 */
    ori r3,r3,SIU_PCR68@l
    li r5,2                    /* Loop counter to get all PCR (68-69) -> 2 PCRs  */
    li r4, 0x0443              /* PCRs initialization value */
    bl InitPCRs
    
    /*  Configure the chip selects
        CS[0-3]
    */
    lis r3,SIU_PCR0@h          /* First PCR for is PCR 0 */
    ori r3,r3,SIU_PCR0@l
    li r5,4                    /* Loop counter to get all PCR (0-3) -> 4 PCRs  */
    li r4, 0x0443              /* PCRs initialization value */
    bl InitPCRs
    
    mtlr r27
    
    blr
}

/*----------------------------------------------------------------------------*/
/* EBI Chip Selects                                                           */
/*----------------------------------------------------------------------------*/

/* Initialize the used EBI Chip Selects */
__asm void __initEBIChipSelects(void)
{
#if INIT_USED_BOARD==MPC5675KDEMO_AXM_0321
MAKE_HLI_COMPATIBLE(EBBI_CS0_BR,&EBI.CS[0].BR.R)
MAKE_HLI_COMPATIBLE(EBBI_CS0_OR,&EBI.CS[0].OR.R)
#endif
nofralloc

#if INIT_USED_BOARD==MPC5675KDEMO_AXM_0321
    /*  CY7C1338 512K External SRAM - 4 beat burst, 0 wait
        Set up Memory Controller CS0 @ AXM_0321_EXTERNAL_RAM
    */
    /*  EBI.CS[0].BR.R = (unsigned long)AXM_0321_EXTERNAL_RAM | 0x41UL;
    */
    lis      r3,AXM_0321_EXTERNAL_RAM@h
    addi     r0,r3,AXM_0321_EXTERNAL_RAM@l
    ori      r0,r0,0x0041    
    lis      r3,EBBI_CS0_BR@h
    ori      r3,r3,EBBI_CS0_BR@l
    stw      r0,0(r3)
    /*  EBI.CS[0].OR.R = 0xfff80000;
    */
    lis      r0,0xfff8
    lis      r3,EBBI_CS0_OR@h
    ori      r3,r3,EBBI_CS0_OR@l
    stw      r0,0(r3)    
#endif

    blr
}


#ifdef __cplusplus
}
#endif
