cpusim.h 7.09 KB
#if defined(LANGUAGE_C) || defined(LANGUAGE_C_PLUS_PLUS)
#include <stdlib.h>
#endif
#include <regdef.h>
#include <asm.h>
#include <R4300.h>
#include <PR/bcp.h>
#include <PR/bbdebug.h>

#define BACKDOOR_PRINT		0x046fffe0
#define BACKDOOR_MODULE		0x046fffe4
#define BACKDOOR_EXIT		0x046ffffa
#define BACKDOOR_POWER		0x046ffffc

/* runtime stack in internal sram */
#define STACK_TOP		PHYS_TO_K1(INTERNAL_RAM_END-16)
#define EXCEPTION_INDIRECT	PHYS_TO_K1(INTERNAL_RAM_END-12)

#ifdef DBG_JTAG
inline void dbg_jtag_message(char *s);
#endif

#if defined(LANGUAGE_C) || defined(LANGUAGE_C_PLUS_PLUS)
static inline void test_preamble(void) {
    __asm__ __volatile__ ("li	$29, %0\n" : : "M"(STACK_TOP));
#ifndef DBG_JTAG
    IO_WRITE(PI_GPIO_REG, (PI_GPIO_POWER_BIT<<PI_GPIO_ENABLE_SHIFT)|PI_GPIO_POWER_BIT);
#else /* Turn on error bit also */
    IO_WRITE(PI_GPIO_REG, 
            ((PI_GPIO_ERROR_BIT | PI_GPIO_POWER_BIT) <<PI_GPIO_ENABLE_SHIFT) |
            (PI_GPIO_ERROR_BIT | PI_GPIO_POWER_BIT));
    //dbg_jtag_message("Test started");
#endif
    /*IO_WRITE(PI_IDE_CONFIG_REG, (IO_READ(PI_IDE_CONFIG_REG)&~PI_IDE_CONFIG_RESET));*/
    IO_WRITE(PI_IDE_CONFIG_REG, (8<<26)|(7<<21)|(2<<16)|(15<<10)|(12<<5)|1);
}

static inline void test_postamble(void) {

    IO_WRITE(PI_GPIO_REG, (PI_GPIO_POWER_BIT<<PI_GPIO_ENABLE_SHIFT)|0);
    IDE_WRITE_NB(BACKDOOR_EXIT, 1);

    for(;;) ;
}

static inline void test_ipc_postamble(void) {
    IDE_WRITE(IDE_DEBUG_DATA_LO_REG, 0xbabe);
    IDE_WRITE(IDE_DEBUG_DATA_HI_REG, 0xcafe);
    for(;;) ;
}

static inline void ipc_signal(unsigned x) {
    IDE_WRITE(IDE_DEBUG_DATA_LO_REG, x&0xffff);
    IDE_WRITE(IDE_DEBUG_DATA_HI_REG, x>>16);
}

static inline void message(const char* s) {
    while(*s) {
	IDE_WRITE_NB(BACKDOOR_PRINT, *s);
	s++;
    }
}

static inline void init_ddr(void) {
    unsigned int sysclk_period, memclk;
    int refcnt = 0x1e0;
    int trdel, twdel, tras, trp, trcdr, trfc, tcl, tcl_b;
    int bd_id;

    bd_id = IO_READ(PI_GPIO_REG);

       /* change to 96 MHz */
    sysclk_period = 10400; /*XXXblythe fix this*/
    memclk = 2000000 / sysclk_period;

    trdel = 3;
    twdel = 1;
    tras = 1;
    trp = 1;
    trcdr = 1;
    trfc = 0xE;
#ifndef PLL_BYPASS
    tcl = 3;
    tcl_b = 4;
#else
    tcl = 3;
    tcl_b = 2;
#endif
    
    IO_WRITE(RI_NMODE_REG, RI_NMODE_CMD_PRECHARGE_ALL);
    IO_READ(RI_NMODE_REG);

    IO_WRITE(RI_NMODE_REG, RI_NMODE_EX|RI_NMODE_EX_DRIVE_STR_HALF);
    IO_READ(RI_NMODE_REG);

    IO_WRITE(RI_NMODE_REG,  RI_NMODE_MX_RESET_DLL 
				| RI_NMODE_MX_BURST_ILV 
				| RI_NMODE_MX_BURST_LEN_4 
				| RI_NMODE_MX_CL(tcl));
    IO_READ(RI_NMODE_REG);

    IO_WRITE(RI_NMODE_REG, RI_NMODE_CMD_PRECHARGE_ALL);
    IO_READ(RI_NMODE_REG);
    
    IO_WRITE(RI_NMODE_REG, RI_NMODE_CMD_AUTO_REFRESH);
    IO_READ(RI_NMODE_REG);
    
    IO_WRITE(RI_NMODE_REG, RI_NMODE_CMD_AUTO_REFRESH);
    IO_READ(RI_NMODE_REG);
    
    IO_WRITE(RI_NMODE_REG, RI_NMODE_MX_BURST_ILV|
			   RI_NMODE_MX_BURST_LEN_4|
			   RI_NMODE_MX_CL(tcl));
    IO_READ(RI_NMODE_REG);

    IO_WRITE(RI_DDR_CONFIG_REG, (trdel<<RI_DDR_CONFIG_TRDEL_SHIFT)|
				(twdel<<RI_DDR_CONFIG_TWDEL_SHIFT)|
				(tras<<RI_DDR_CONFIG_TRAS_SHIFT)|
				(trp<<RI_DDR_CONFIG_TRP_SHIFT)|
				(trcdr<<RI_DDR_CONFIG_TRCD_SHIFT)|
				(trfc<<RI_DDR_CONFIG_TRFC_SHIFT)|
				(tcl_b<<RI_DDR_CONFIG_TCL_SHIFT));
    IO_READ(RI_NREFRESH_REG);
    
    IO_WRITE(RI_AUTO_PRE_CHG_REG, 1);
    IO_READ(RI_AUTO_PRE_CHG_REG);

#ifndef PLL_BYPASS
    IO_WRITE(RI_STROBE_REV_REG, 1);
    IO_READ(RI_NREFRESH_REG);
    
    IO_WRITE(RI_STROBE_REV_REG, 1);
#endif

    for (tcl =0; tcl < 100; tcl++)
	IO_READ(RI_NREFRESH_REG);
    
    IO_WRITE(RI_NREFRESH_REG, RI_NREFRESH_ENABLE | refcnt);
    IO_READ(RI_NREFRESH_REG);
}

#define __REG(x) "$" #x
#define __REG1(x) #x
#define getcp0reg(source)          	                        \
({ int __res;                                                   \
        __asm__ __volatile__(                                   \
	".set\tpush\n\t"					\
	".set\treorder\n\t"					\
        "mfc0\t%0,"__REG(source)"\n\t"                          \
	".set\tpop"						\
        : "=r" (__res));                                        \
        __res;})

#define setcp0reg(register,value)                		\
        __asm__ __volatile__(                                   \
        "mtc0\t%0,"__REG(register)"\n\t"			\
	"nop"							\
        : : "r" (value));

#define getreg(source)          	                        \
({ int __res;                                                   \
        __asm__ __volatile__(                                   \
	".set\tpush\n\t"					\
	".set\treorder\n\t"					\
        "move\t%0,"__REG1(source)"\n\t"                         \
	".set\tpop"						\
        : "=r" (__res));                                        \
        __res;})

#define setreg(register,value)                			\
        __asm__ __volatile__(                                   \
        "move\t"__REG1(register)",%0\n\t"			\
        : : "r" (value));

extern void initICache(void);
extern void initDCache(void);
extern void invalICache(void *addr, int nbytes);
extern void invalDCache(void *addr, int nbytes);
extern void writebackDCache(void *addr, int nbytes);

#ifndef DBG_JTAG
    #define DBG_JTAG_PASS(x)
    #define DBG_JTAG_FAIL(x)
    #define DBG_JTAG_START()
#else
    #define DBG_JTAG_PASS(x) dbg_jtag_pass(x)
    #define DBG_JTAG_FAIL(x) dbg_jtag_fail(x)
    #define DBG_JTAG_START() DBG_GPIO_ON

    #define DBG_PW_ERR_V     (PI_GPIO_ERROR_BIT | PI_GPIO_POWER_BIT)
    #define DBG_PW_ERR_EN_V  (DBG_PW_ERR_V << PI_GPIO_ENABLE_SHIFT)
    #define DBG_PW_EN_V      (PI_GPIO_POWER_BIT << PI_GPIO_ENABLE_SHIFT)
    
    #define DBG_GPIO_OFF_V   (DBG_PW_EN_V | PI_GPIO_POWER_BIT)
    #define DBG_GPIO_ON_V    (DBG_PW_ERR_EN_V | DBG_PW_ERR_V) 

    #define DBG_GPIO_ERR_OFF IO_WRITE(PI_GPIO_REG, DBG_GPIO_OFF_V)
    #define DBG_GPIO_ERR_ON  IO_WRITE(PI_GPIO_REG, DBG_GPIO_ON_V)

    #define BLINK_INTERVAL   300000000   /* 3 sec in 96MHz */ 
    #define BLINK_TIMES      20 
    #define DBG_MSG_EN       0x4A40010
    #define DBG_MSG_START    0x4A80040  
    #define DBG_MSG_LEN      0x3C0

    inline void dbg_jtag_message(char *s)
    {
        unsigned int i, data, k=0;

        IO_WRITE(DBG_MSG_EN, 1);
	while (*s) {
           data = 0;
           for (i=0; i<4; i++) {
              data <<= 8;
              if (*s) data |= *s;
              else {
                  data <<= ((3-i) << 3);  /* (3-i)*8 */
                  break;  
              }
              s++;
           }
           if (k<DBG_MSG_LEN) IO_WRITE(DBG_MSG_START+k, data);
           k += 4;
        }

        /* Make sure the last write is done */
        if (k<DBG_MSG_LEN) IO_WRITE(DBG_MSG_START+k, 0);
        IO_READ(DBG_MSG_START+k);
    }

    inline void dbg_jtag_fail(char *s)
    {
        int i, count;

        dbg_jtag_message(s);

        DBG_GPIO_ERR_OFF;
        for (i=0; i<BLINK_TIMES; i++) {
            DBG_GPIO_ERR_ON;
            count = getcp0reg(C0_COUNT);
            while ((getcp0reg(C0_COUNT) - count) < BLINK_INTERVAL); 
            DBG_GPIO_ERR_OFF;
        }
    }

    inline void dbg_jtag_pass(char *s)
    {
        dbg_jtag_message(s);
        DBG_GPIO_ERR_OFF;
    }

#endif  

#endif