⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 l1jtag.c

📁 TM1300/PNX1300系列DSP(主要用于视频处理)的自动boot程序
💻 C
字号:
/*
 *  +-------------------------------------------------------------------+
 *  | Copyright (c) 1995-2000 TriMedia Technologies Inc.                |
 *  |                                                                   |
 *  | This software  is furnished under a license  and may only be used |
 *  | and copied in accordance with the terms  and conditions of such a |
 *  | license  and with  the inclusion of this  copyright notice.  This |
 *  | software or any other copies of this software may not be provided |
 *  | or otherwise  made available  to any other person.  The ownership |
 *  | and title of this software is not transferred.                    |
 *  |                                                                   |
 *  | The information  in this software  is subject  to change  without |
 *  | any  prior notice  and should not be construed as a commitment by |
 *  | TriMedia Technologies.                                            |
 *  |                                                                   |
 *  | This  code  and  information  is  provided  "as is"  without  any |
 *  | warranty of any kind,  either expressed or implied, including but |
 *  | not limited  to the implied warranties  of merchantability and/or |
 *  | fitness for any particular purpose.                               |
 *  +-------------------------------------------------------------------+
 *
 *  Module name              : l1jtag.c
 *
 *  Module type              : IMPLEMENTATION
 *
 *  Title                    : L1 boot code
 *
 *  Description              : L1 boot code. Copies L2 boot code via JTAG,
 *                             outputs MMIO_BASE, DRAM_BASE, DRAM_LIMIT, and
 *                             DRAM_CACHEABLE_LIMIT before L2 load starts
 *
 *  Last update              : March 22, 1999
 *			       Added pragmas TCS_unroll=0 and TCS_no_graft
 *			       to keep the code size below 2K
 */

#include <tm1/mmio.h>

/*
 * NOTES on the CPU32 macro:
 *
 * If you are building an EEPROM for the TM1310 (a.k.a. CPU32/TM32) chip
 * you need to add the following tmcc compiler option:
 *	-DCPU32
 * to the L1_CFLAGS makefile macro in either Makefile.Unix or Makefile.Win;
 * so that the proper JTAG Control registers are used for reading/writing
 * the JTAG Data registers.
 */

#if defined(CPU32)
#define  JTAG_CTL_2		(0x10380C)
#endif

/*
 * Downloader Symbols
 */
extern          UInt32	_clock_freq_init[];
extern          UInt32	_begin_stack_init[];
extern volatile UInt32	_MMIO_base_init[];

/*
 * Macros
 */
#define CACHE_BL_SIZE		64

#if defined(CPU32)
#define OFULL			0x1
#define IFULL			0x1
#define SLEEPLESS		0x2
#else
#define OFULL			0x1
#define IFULL			0x2
#define SLEEPLESS		0x4
#endif

/*
 * Used by tmdbg. DO NOT ALTER THESE MACROS!!!
 *
 *	0x12340000 - version 1 of the L1 boot code, sends the magic number only
 *	0x12340002 - version 2 of the L1 boot code, sends sdram info as well
 *	0x12340003 - version 3 of the L1 boot code, similar to version 2, but for CPU32/TM1310
 */
#if defined(CPU32)
#define START_L2_LOAD		0x12340003
#else
#define START_L2_LOAD		0x12340002
#endif
#define JUMP_TO_L2_CODE		0x56780000

/*
 * Globals
 */
UInt32 _clock_freq		= (UInt32)_clock_freq_init;
volatile UInt32 *_MMIO_base	= (volatile UInt32 *)_MMIO_base_init;

custom_op void dcb(long, void *);
custom_op void iclr(void);


/*
 * DO NOT do the loop unrolling optimization, otherwise
 * the code size will expand to beyond the 2K EEPROM limit.
 */
#pragma TCS_unroll=0


/*
 * copyback_dcache (UInt32 addr, int nbytes)
 *   1. addr must be cache aligned.
 *      This function flushes nbytes starting at addr to memory.
 *
 * L1 boot code copies L2 boot code from some device
 * This needs to be flushed to memory before jumping to the
 * L2 load address
 *
 */
static void
copyback_dcache(UInt32 addr, UInt32 n)
{
  UInt32 i;

  for (i = 0; i < n; i = i + CACHE_BL_SIZE) {
    dcb(0, (void *)(addr + i));
  }
}


/*
 * NOTE:
 *    iclr() is in a separate function to ensure that it is
 *    in a dtree by itself.
 */
static void
clear_icache(void)
{
  iclr();
}


static void
wait_for_ifull(void)
{
  UInt32 state;

  do {
#if defined(CPU32)
    state = MMIO(JTAG_CTL_2);
#else
    state = MMIO(JTAG_CTL);
#endif
  } while ((state & IFULL) == 0);
}


/*
 *  This function loads L2 code via JTAG, it returns the
 *  load address of L2 Boot code.
 *
 *  l2_code_size: output parameter, set to L2 code size.
 *
 */
static UInt32
load_l2_via_jtag(UInt32 * l2_code_size)
{
#pragma	TCS_no_graft
  /*
   * 1. Indicate readiness to transfer of L2 code via jtag.
   * 2. Transfer MMIO_BASE, DRAM_BASE, DRAM_LIMIT, and
   *    DRAM_CACHEABLE_LIMIT before L2 download starts.
   */

  MMIO(JTAG_DATA_IN)	= 0;
  MMIO(JTAG_DATA_OUT)	= START_L2_LOAD;
  MMIO(JTAG_CTL)	= (OFULL | SLEEPLESS);
#if defined(CPU32)
  MMIO(JTAG_CTL_2)	= 0;
#endif

  wait_for_ifull();
  MMIO(JTAG_DATA_OUT)	= MMIO(MMIO_BASE);
  MMIO(JTAG_CTL)	= (OFULL | SLEEPLESS);
#if defined(CPU32)
  MMIO(JTAG_CTL_2)	= 0;
#endif

  wait_for_ifull();
  MMIO(JTAG_DATA_OUT)	= MMIO(DRAM_BASE);
  MMIO(JTAG_CTL)	= (OFULL | SLEEPLESS);
#if defined(CPU32)
  MMIO(JTAG_CTL_2)	= 0;
#endif

  wait_for_ifull();
  MMIO(JTAG_DATA_OUT)	= MMIO(DRAM_LIMIT);
  MMIO(JTAG_CTL)	= (OFULL | SLEEPLESS);
#if defined(CPU32)
  MMIO(JTAG_CTL_2)	= 0;
#endif

  wait_for_ifull();
  MMIO(JTAG_DATA_OUT)	= MMIO(DRAM_CACHEABLE_LIMIT);
  MMIO(JTAG_CTL)	= (OFULL | SLEEPLESS);
#if defined(CPU32)
  MMIO(JTAG_CTL_2)	= 0;
#endif

  while (1) {

    Byte * load_addr;
    UInt32 tmp, cksum;
    UInt32 l2_load_addr;
    /*
     * bug502098: code_size needs to be signed so that the download
     *		  while-loop would exit when code_size is NOT a
     *		  multiple of 4.  This is possible with the new tmld.
     */
    Int32 code_size;

    /*
     * First piece of data: l2 load address
     */
    wait_for_ifull();

    /*
     * Get L2 load address
     */
    l2_load_addr	= (UInt32)MMIO(JTAG_DATA_IN);
    load_addr		= (Byte *)l2_load_addr;
    MMIO(JTAG_CTL)	= SLEEPLESS;
#if defined(CPU32)
    MMIO(JTAG_CTL_2)	= 0;
#endif

    /*
     * Second piece of data: l2 code size in bytes
     */
    wait_for_ifull();

    /*
     * Get L2 code size
     */
    *l2_code_size = code_size = MMIO(JTAG_DATA_IN);
    MMIO(JTAG_CTL)	= SLEEPLESS;
#if defined(CPU32)
    MMIO(JTAG_CTL_2)	= 0;
#endif

    cksum = 0;

    while (code_size > 0) {

      Byte byte;

      wait_for_ifull();
      tmp = MMIO(JTAG_DATA_IN);
      MMIO(JTAG_DATA_OUT) = code_size;
      MMIO(JTAG_CTL)	= SLEEPLESS;
#if defined(CPU32)
      MMIO(JTAG_CTL_2)	= 0;
#endif

      byte = (Byte)(tmp & 0xff);
      cksum += byte;
      *load_addr++ = byte;

      byte = (Byte)((tmp >> 8) & 0xff);
      cksum += byte;
      *load_addr++ = byte;

      byte = (Byte)((tmp >> 16) & 0xff);
      cksum += byte;
      *load_addr++ = byte;

      byte = (Byte)((tmp >> 24) & 0xff);
      cksum += byte;
      *load_addr++ = byte;

      code_size -= 4;
    }

    /*
     * finished l2 load
     */
    cksum |= 0x1;
    MMIO(JTAG_DATA_OUT)	= cksum;
    MMIO(JTAG_CTL)	= (OFULL | SLEEPLESS);
#if defined(CPU32)
    MMIO(JTAG_CTL_2)	= 0;
#endif

    /*
     * wait for next action. Another load or jump to l2_load_addr
     */
    wait_for_ifull();
    tmp = MMIO(JTAG_DATA_IN);
    MMIO(JTAG_CTL)	= SLEEPLESS;
#if defined(CPU32)
    MMIO(JTAG_CTL_2)	= 0;
#endif

    if (tmp == JUMP_TO_L2_CODE)
      return l2_load_addr;

  } /* while (1) */

}


/*
 * Copies L2 code via JTAG to SDRAM
 */
UInt32
L1main()
{
#pragma	TCS_no_graft
  UInt32 l2_code_size;
  UInt32 l2_load_address;

#if defined(USING_PCI_INTERNAL_CLOSK)
  /*
   * enable the following code when the board does not have an
   * external PCI clock.
   */
  MMIO(XIO_CTL) = 0x3;
#endif

  l2_load_address = load_l2_via_jtag(&l2_code_size);

  /*
   * flush data cache
   */
  copyback_dcache(l2_load_address, l2_code_size);

  /*
   * clear any interrupts
   */
  MMIO(ICLEAR) = 0xffffffff;
  clear_icache();

  /*
   * Return from L1main() causes L2 code to be executed.
   */
  return l2_load_address;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -