📄 testjtagdll.c
字号:
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include "testjtagdll.h"
#include "TMDownLoader.h"
#define TALK_TIME 20
/* JTAG card's base address (optional) set this appropritely to your system */
/* if your JTAG card doesn't require user to specify any base address just
/* work with this default value (0x140) and not use it in actual implementation of
/* initlialize function of your Wrapper JTAG DLL */
#define BASE_ADDRESS 0x140
#define is_ofull(ctl) ((ctl) & 1)
#define is_ifull(ctl) ((ctl) & 2)
#define MAX_TARGETS 16
#define JT_TEST_BUS 0
#define false 0
#define true 1
typedef VOID (CALLBACK* INITIALIZE)(LONG, USHORT);
typedef VOID (CALLBACK* RESET)(LONG);
typedef VOID (CALLBACK* SCANIR)(LONG, ULONG, UCHAR *, ULONG, UCHAR *);
typedef VOID (CALLBACK* SCANDR)(LONG, ULONG, UCHAR *, ULONG, UCHAR *);
typedef VOID (CALLBACK* SCANDRFAST)(LONG, ULONG, UCHAR *, ULONG, UCHAR);
typedef struct {
ulong tm1_freq; /* 100 MHz default */
ulong tbc_base;
uchar connected;
uchar l1_ready;
uchar loaded;
uchar running;
} jtag_dsp_info;
int GetMMIOandSDRAMAddressesFromEEPROMBootCode(long);
char * PrepareTheRelocatedMemoryImage(long, char *, int *);
int DownLoadMemoryImageToTarget(long, char *, unsigned long);
void StartTalkingToTarget(long);
void scan_jtag_data_out(long, unsigned long , unsigned char *, unsigned char *);
unsigned char read_jtag_control(long, unsigned long );
void scan_jtag_control(long, unsigned long, unsigned char *, unsigned char *);
int jtag_reset(long);
/* Handles to DLL exported functions */
INITIALIZE initBoard;
RESET resetBoard;
SCANIR scanInstructionReg;
SCANDR scanDataReg;
SCANDRFAST scanDataRegFast;
/* Globals */
// Handle to DLL
HINSTANCE hDLL;
TargetInfo targetInfo[MAX_TARGETS];
static jtag_dsp_info jtdsp_info[MAX_TARGETS];
static TMDwnLdr_SharedSectionTab_Handle mp_shared_sections = NULL;
static Address mp_MMIO_addr_array[MAX_TARGETS];
#define jtdsp_tm1_freq(i) jtdsp_info[i].tm1_freq
#define jtdsp_board_ptr(i) jtdsp_info[i].board_ptr
#define jtdsp_tbc_base(i) jtdsp_info[i].tbc_base
#define jtdsp_connected(i) jtdsp_info[i].connected
#define jtdsp_l1_ready(i) jtdsp_info[i].l1_ready
#define jtdsp_loaded(i) jtdsp_info[i].loaded
#define jtdsp_running(i) jtdsp_info[i].running
int main(int argc, char * argv[])
{
int pindx = 0;
int loadSize;
char *imageHandle;
if ( (argc < 2 ) || (argv[1] == NULL) || (argv[2] == NULL) ) {
printf("Usage : jtagexample <dllname>.dll and <path>/jtag.out \n");
return 1;
}
printf("Loading %s...\n", argv[1]);
hDLL = LoadLibrary(argv[1]);
if (hDLL != NULL)
{
printf("Loaded %s \n\n", argv[1]);
initBoard = (INITIALIZE)GetProcAddress(hDLL,"tmJtagInitBoard");
resetBoard = (RESET)GetProcAddress(hDLL,"tmJtagResetBoard");
scanInstructionReg = (SCANIR)GetProcAddress(hDLL,"tmJtagScanInstructionRegister");
scanDataReg = (SCANDR)GetProcAddress(hDLL,"tmJtagScanDataRegister");
if (!initBoard || !resetBoard || !scanInstructionReg || !scanDataReg)
{
// handle the error
printf("%s fails to comply to tmdbg's JTAG API\n");
FreeLibrary(hDLL);
return 2;
}
else
{
printf("Please press the RESET button on your standalone system\n");
puts("Press ENTER to continue");
getchar();
initBoard(pindx, BASE_ADDRESS);
jtag_reset(pindx);
GetMMIOandSDRAMAddressesFromEEPROMBootCode(pindx);
imageHandle = PrepareTheRelocatedMemoryImage(pindx, argv[2], &loadSize);
if (imageHandle == NULL) {
puts("Could not prepare memory image");
return -1;
}
DownLoadMemoryImageToTarget(pindx, imageHandle, loadSize);
StartTalkingToTarget(pindx);
}
}
else {
printf("Failed to Load %s - File not found\n", argv[1]);
printf("Please make sure that you typed names correctly or \nthe files are in your path\n");
}
FreeLibrary(hDLL);
return 0;
}
int GetMMIOandSDRAMAddressesFromEEPROMBootCode(long pindx)
{
int i, j;
/*
* Very first scan seems to transfer out junk. Do a couple of scans
*/
i = 0;
scan_jtag_data_out(pindx, JT_TEST_BUS, (uchar *)(&i), (uchar *)(&j));
scan_jtag_data_out(pindx, JT_TEST_BUS, (uchar *)(&i), (uchar *)(&j));
/*
* scan out JTAG_DATA_OUT and check if it is the START_L2_LOAD magic number
*/
if (jtdsp_l1_ready(pindx) == false) {
int status = 0;
int time_out = 80;
/*
* This is the VERY FIRST jtag scan that we are doing and we want to see:
* 1. what kind of JTAG interface (Viper or TM1000), and
* 2. if the target is ready to download, or
* 3. if the target has been loaded already by some other means.
*/
while (time_out > 0) {
uchar ctl;
ctl = read_jtag_control(pindx, JT_TEST_BUS);
if (is_ofull(ctl)) {
ulong dummy = 0;
scan_jtag_data_out(pindx, JT_TEST_BUS, (uchar *)&dummy, (uchar *)&status);
if (status == START_L2_LOAD_V0 ||
status == START_L2_LOAD_V1 ||
status == START_L2_LOAD_V2) {
uchar dummy_byte;
uchar ofull_clear;
ofull_clear = JTAG_OFULL_BIT | JTAG_NOSLEEP_BIT;
scan_jtag_control(pindx, JT_TEST_BUS, &ofull_clear, &dummy_byte);
}
break;
}
}
time_out--;
if (time_out == 0) {
printf("target not ready for L2 load; timed out\n");
return 3;
}
jtdsp_l1_ready(pindx) = true;
printf("target ready for application download\n\n");
if (status == START_L2_LOAD_V1 ||
status == START_L2_LOAD_V2) {
ulong addr = 0;
/*
* get MMIO_BASE, SDRAM_BASE, SDRAM_LIMIT and CACHEABLE_LIMIT
* in that order, from target. These override what the user
* may have specified in command line.
*
* Dont care what we scan into JTAG_DATA_IN register.
* Just need to set the ifull bit in this case.
*/
/* first MMIO_BASE */
jtag_fast_write_n_bytes(pindx, (uchar *)&addr, 4);
jtag_read_n_bytes(pindx, (uchar *)&addr, 4, false);
targetInfo[pindx].MMIObaseAddr = addr;
printf("MMIO base Address = 0x%08x\n", addr);
/* next DRAM_BASE */
jtag_fast_write_n_bytes(pindx, (uchar *)&addr, 4);
jtag_read_n_bytes(pindx, (uchar *)&addr, 4, false);
targetInfo[pindx].SDRAMbaseAddr = addr;
printf("SDRAM base Address = 0x%08x\n", addr);
/* next DRAM_LIMIT */
jtag_fast_write_n_bytes(pindx, (uchar *)&addr, 4);
jtag_read_n_bytes(pindx, (uchar *)&addr, 4, false);
targetInfo[pindx].DRAMLimit = addr - targetInfo[pindx].SDRAMbaseAddr;
printf("DRAM Limit = 0x%08x\n", addr);
/* next DRAM_CACHEABLE_LIMIT */
jtag_fast_write_n_bytes(pindx, (uchar *)&addr, 4);
jtag_read_n_bytes(pindx, (uchar *)&addr, 4, false);
targetInfo[pindx].CacheableLimit = addr;
printf("Cacheable Limit = 0x%08x\n", addr);
}
else {
printf("Unknown Monitor version 0x%08x\n", ((status & 0xFF) > 1));
}
/*
* sanity check load address.
* L1 monitor is loaded at SDRAM BASE and it takes up L1_CODE_SIZE bytes
*/
if (targetInfo[pindx].LoadAddr == UNINIT_LOAD_ADDR) {
/*
* user did not specify a load address, so we'll use the default
*/
targetInfo[pindx].LoadAddr = targetInfo[pindx].SDRAMbaseAddr + L1_CODE_SIZE;
}
else if (targetInfo[pindx].LoadAddr < targetInfo[pindx].SDRAMbaseAddr + L1_CODE_SIZE) {
printf("\nLoad Address = 0x%08x\n",targetInfo[pindx].LoadAddr);
printf("DRAM base = 0x%08x\n",targetInfo[pindx].SDRAMbaseAddr);
printf("L1 Code size = 0x%08x\n", L1_CODE_SIZE);
targetInfo[pindx].LoadAddr = targetInfo[pindx].SDRAMbaseAddr + L1_CODE_SIZE;
}
printf("Adjusted Load Address = 0x%08x\n" ,targetInfo[pindx].LoadAddr );
}
return 0;
};
char * PrepareTheRelocatedMemoryImage(long pindx, char * filename, int *loadsize)
{
TMDwnLdr_Object_Handle of_handle;
char * mibuf;
int of_image_size;
int of_image_align;
int status;
long used;
*loadsize = 0;
status = TMDwnLdr_load_object_from_file(filename, NULL/*mp_shared_sections*/, &of_handle);
if (status != TMDwnLdr_OK) {
printf("TMDwnLdr_load_object_from_file Err = %s\n", TMDwnLdr_get_last_error(status));
mibuf = NULL;
TMDwnLdr_unload_object(of_handle);
return NULL;
}
/*
* in case of Windows target, we need to patch the TMManShared symbol
*/
status = TMDwnLdr_resolve_symbol(of_handle, "_TMManShared",
0xffffffff
/* DSPInternalInfo.TMManSharedPhysicalAddress */);
if (status != TMDwnLdr_OK) {
/* ignore any error */
}
status = TMDwnLdr_get_image_size(of_handle, &of_image_size, &of_image_align);
if (status != TMDwnLdr_OK) {
printf("TMDwnLdr_get_image_size Err = %d\n", TMDwnLdr_get_last_error(status));
mibuf = NULL;
TMDwnLdr_unload_object(of_handle);
return NULL;
}
used = targetInfo[pindx].LoadAddr - targetInfo[pindx].SDRAMbaseAddr;
if (of_image_size + 1024 > (targetInfo[pindx].DRAMLimit - used)) {
printf("file too big - can not be downloaded", targetInfo[pindx].LoadAddr, of_image_size);
mibuf = NULL;
TMDwnLdr_unload_object(of_handle);
return NULL;
}
jtdsp_tm1_freq(pindx) = 100000000;
mp_MMIO_addr_array[pindx] = targetInfo[pindx].MMIObaseAddr;
status = TMDwnLdr_multiproc_relocate(of_handle,
tmNoHost,
mp_MMIO_addr_array,
pindx,
1,
jtdsp_tm1_freq(pindx),
(Address)targetInfo[pindx].LoadAddr,
targetInfo[pindx].DRAMLimit - used,
TMDwnLdr_LeaveCachingToDownloader);
if (status != TMDwnLdr_OK) {
printf("TMDwnLdr_multiproc_relocate Err = %s\n", TMDwnLdr_get_last_error(status));
mibuf = NULL;
TMDwnLdr_unload_object(of_handle);
return NULL;
}
of_image_size = ROUND_TO_4(of_image_size);
mibuf = (char *)malloc(of_image_size);
if (mibuf == NULL ){
printf("Insufficient memory available\n");
exit(0);
}
status = TMDwnLdr_get_memory_image(of_handle, mibuf);
if (status != TMDwnLdr_OK) {
printf("TMDwnLdr_get_memory_image Err =%d\n", TMDwnLdr_get_last_error(status));
free(mibuf);
*loadsize = 0;
mibuf = NULL;
}
else {
/*
* the MALLOC'ed space will be freed by the caller after download
* Just set the load size here
*/
*loadsize = of_image_size;
}
TMDwnLdr_unload_object(of_handle);
return mibuf;
};
int DownLoadMemoryImageToTarget(long pindx, char * imageHandle, ulong loadSize)
{
#define Chunk_Size (32 * 1024)
ulong cksum, target_cksum;
long loadsize_save;
long time_out;
char * image_buf;
uchar * file_buffer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -