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

📄 device.cpp

📁 ARM核的边界扫描(JTAG)的实现,此代码在s3c2400上测试通过
💻 CPP
字号:
//////////////////////////////////////////////////////////////////////////////
// Device.cpp                                                               //
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// Includes                                                                 //
//////////////////////////////////////////////////////////////////////////////
#include "Device.h"
#include "JTAG.h"
#include <stdio.h>		// for debugging only
#include <windows.h>	// for Sleep

//////////////////////////////////////////////////////////////////////////////
// Device                                                                   //
//////////////////////////////////////////////////////////////////////////////
namespace Device
{

//////////////////////////////////////////////////////////////////////////////
// Variables                                                                //
//////////////////////////////////////////////////////////////////////////////
unsigned int deviceID = 0x0032409D;

//int commandChain[] = { 3,-1,-1,3, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, };

// autoselect chainsizes
int commandDataLength[] = { -1,-1,5,-1, -1,1,-1,1, -1,1,-1,-1, -1,-1,32,1, };
int chainLength[] = { 184,67,38,324, 40,40,-1,-1, -1,-1,-1,-1, -1,-1,-1,40, };

const char *sCommands[] =
{
	"EXTEST", "???", "SCAN_N", "SAMPLE", "RESTART", "CLAMP", "???", "HIGHZ",
	"???", "CLAMPZ", "???", "???", "INTEST", "???", "IDCODE", "BYPASS",
};

const char *sChains[] =
{
	"IBS", "DEBUG", "EICE", "EBS", "PA_TAG_RAM", "???", "ETM", "???",
	"???", "???", "???", "???", "???", "???", "???", "CP15",
};

IDChain id;
ETMChain etm;
EICEChain eice;
DebugChain debug;

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

//////////////////////////////////////////////////////////////////////////////
// GetMappedValue                                                           //
//////////////////////////////////////////////////////////////////////////////
/*unsigned int GetMappedValue(const unsigned char *ebs, const unsigned short *map, int bits)
{
	unsigned int value = 0;
	for (int bit=0; bit<bits; bit++)
	{
		value += ebs[map[bit]] << bit;
	}
	return value;
}

//////////////////////////////////////////////////////////////////////////////
// SetMappedValue                                                           //
//////////////////////////////////////////////////////////////////////////////
void SetMappedValue(unsigned char *ebs, const unsigned short *map, int bits, unsigned int data)
{
	for (int bit=0; bit<bits; bit++)
	{
		ebs[map[bit]] = data >> bit & 1;
	}
}*/

//////////////////////////////////////////////////////////////////////////////
// Reverse                                                                  //
//////////////////////////////////////////////////////////////////////////////
unsigned int Reverse(unsigned int data)
{
	unsigned int data2 = 0;
	for (int bit=31; bit>=0; bit--)
	{
		if (data>>bit&1) data2 += 1<<(31-bit);
	}
	return data2;
}

//////////////////////////////////////////////////////////////////////////////
// Restart                                                                  //
//////////////////////////////////////////////////////////////////////////////
void Restart()
{
	JTAG::Command(RESTART);
}

//////////////////////////////////////////////////////////////////////////////
// Init                                                                     //
//////////////////////////////////////////////////////////////////////////////
int Init()
{
	if (JTAG::Init()) return -1;
	if (id.Read() != deviceID) { fprintf(stderr, "Can't find device\n"); Close(); return -1; }
	return 0;
}

//////////////////////////////////////////////////////////////////////////////
// Close                                                                    //
//////////////////////////////////////////////////////////////////////////////
void Close()
{
	JTAG::Close();
}

/*
//////////////////////////////////////////////////////////////////////////////
// Sample                                                                   //
//////////////////////////////////////////////////////////////////////////////
void Sample()
{
	JTAG::Command(SAMPLE);
	JTAG::Chain(BS_CHAIN);
	JTAG::Read(ebs, BS_LENGTH);
}

//////////////////////////////////////////////////////////////////////////////
// GetAddress                                                               //
//////////////////////////////////////////////////////////////////////////////
unsigned int GetAddress()
{
	return GetMappedValue(PADDR_OUT, lengthof(PADDR_OUT));
}

//////////////////////////////////////////////////////////////////////////////
// SetAddress                                                               //
//////////////////////////////////////////////////////////////////////////////
void SetAddress(unsigned int address)
{
	SetMappedValue(PADDR_OUT, lengthof(PADDR_OUT), address);
}
*/

//////////////////////////////////////////////////////////////////////////////
// debug_halted                                                             //
//////////////////////////////////////////////////////////////////////////////
int debug_halted()
{
	printf("debug_halted\n");

	// disable interrupts
	eice.Write(EICE_DEBUG_CONTROL, EICE_DEBUG_CONTROL_INTDIS);

	// Check current DEBUG state
	if (eice.Read(EICE_DEBUG_STATUS) & EICE_DEBUG_STATUS_ITBIT)
	{
		printf("THUMB\n");
	}
	else
	{
		printf("ARM\n");
	}

	//arm_regs.mode = itbit

	// ARM...

	debug.Exec(0xe5800000, 0);			// STR r0, [r0]	- Save R0 before use
	debug.Exec(0xe1a0000f, 0);			// MOV r0, PC 	- Copy PC to R0
	debug.Exec(0xe5800000, 0);			// STR r0, [r0] - Save PC into R0
	printf("R0=%08X\n", debug.Exec(0xe1a00000, 0));			// NOP - Read out R0
	debug.Exec(0xe1a00000, 0);			// NOP
	unsigned int pc = debug.Exec(0xe1a00000, 0) - 0x18;		//  NOP	 - Read out PC & correct for delay
	printf("PC=%08X\n", pc);

	Restart();

	printf("halt ok\n");

	return 0;
}

//////////////////////////////////////////////////////////////////////////////
// debug_poll                                                               //
//////////////////////////////////////////////////////////////////////////////
int debug_poll()
{
	printf("debug_poll\n");

	if ((eice.Read(EICE_DEBUG_STATUS) & (EICE_DEBUG_STATUS_SYSCOMP | EICE_DEBUG_STATUS_DBGACK)) == (EICE_DEBUG_STATUS_SYSCOMP | EICE_DEBUG_STATUS_DBGACK))
	{
		return debug_halted();
	}
	Restart();
	printf("System running\n");
	return 0;
}

//////////////////////////////////////////////////////////////////////////////
// debug_halt                                                               //
//////////////////////////////////////////////////////////////////////////////
int debug_halt()
{
	printf("debug_halt\n");

	// set debug request bit
	printf("%08X\n", eice.Read(EICE_DEBUG_CONTROL));
	eice.Write(EICE_DEBUG_CONTROL, EICE_DEBUG_CONTROL_DBGRQ);
	printf("%08X\n", eice.Read(EICE_DEBUG_CONTROL));

	Restart();

	int temp = 0;
	while (temp++ < 10)
	{
		printf("%08X\n", eice.Read(EICE_DEBUG_STATUS));	// D  1101

		// read debug status
		if ((eice.Read(EICE_DEBUG_STATUS) & (EICE_DEBUG_STATUS_DBGACK | EICE_DEBUG_STATUS_SYSCOMP)) != (EICE_DEBUG_STATUS_DBGACK | EICE_DEBUG_STATUS_SYSCOMP))
		{
			// success, clear request
			eice.Write(EICE_DEBUG_CONTROL, 0);

			return debug_halted();
		}

		Restart();

		printf(".");
		Sleep(1);	// could be 100us
	}

	// failed, clear request
	eice.Write(EICE_DEBUG_CONTROL, 0);

	Restart();

	printf("HALT Failed\n");
	return -1;
}

//////////////////////////////////////////////////////////////////////////////
// debug_restart                                                            //
//////////////////////////////////////////////////////////////////////////////
int debug_restart(int pc)
{
	printf("debug_restart\n");

	//if (arm_regs.status == ARM_HALTED_WITH_REGS) regs_write();

	printf("Restarting at 0x%8.8X\n", pc);

	// enable interrupts
	eice.Write(EICE_DEBUG_CONTROL, 0);

	// ARM...

	debug.Exec(0xe5900000, 0);		// LDR r0, [r0]		- restore PC
	debug.Exec(0xe1a00000, 0);		// NOP
	debug.Exec(0xe1a00000, 0);		// NOP
	debug.Exec(0xe1a00000, 0, pc);	// NOP 			- scan in value for PC
	debug.Exec(0xe1a0f000, 0);		// MOV PC, r0		- put r0 into PC
	debug.Exec(0xe1a00000, 0);		// NOP
	debug.Exec(0xe1a00000, 0);		// NOP
	debug.Exec(0xe5900000, 0);		// LDR r0, [r0]		- restore R0
	debug.Exec(0xe1a00000, 0);		// NOP
	debug.Exec(0xe1a00000, 0);		// NOP
	debug.Exec(0xe1a00000, 0, 0);	// NOP			- scan in value for r0
	debug.Exec(0xe24ff014, 0);		// SUB PC, PC, #0x14	- jump back PC		(-(4+D+5S))
	debug.Exec(0xe1a00000, 1);		// Return to system speed

	Restart();

	printf("Done\n");

	return 0;
}

//////////////////////////////////////////////////////////////////////////////
// memory_poke                                                              //
//////////////////////////////////////////////////////////////////////////////
int memory_poke(unsigned int address, unsigned int data)
{
	printf("Poke 0x%8.8X, 0x%8.8X\n", address, data);
	debug.Exec(0xe8900003, 0);	// LDMIA r0, [r0, r1]	- put address and data
	debug.Exec(0xe1a00000, 0);	// NOP
	debug.Exec(0xe1a00000, 0);	// NOP
	debug.Exec(0xe1a00000, 0, address);		// NOP 			- scan in address
	debug.Exec(0xe1a00000, 0, data);	// NOP 			- scan in data
	for (int i=0; i<1; i++)
	{
		debug.Exec(0xe4801004, 0);		// STR r1, [r0], #4	- store r1 in location of r0
		debug.Exec(0xe1a00000, 1);		// Run at system speed
		Restart();
	}
	return 0;
}

//////////////////////////////////////////////////////////////////////////////
// memory_peek                                                              //
//////////////////////////////////////////////////////////////////////////////
int memory_peek(unsigned int address, unsigned int *data)
{
	debug.Exec(0xe5900000, 0);	// LDR r0, [r0]		- put address in r0
	debug.Exec(0xe1a00000, 0);	// NOP
	debug.Exec(0xe1a00000, 0);	// NOP
	debug.Exec(0xe1a00000, 0, address);	// NOP 			- scan in address
	debug.Exec(0xe4901004, 0);	// LDR r1, [r0], #4	- load r1 from location of r0
	debug.Exec(0xe1a00000, 1);	// Run at system speed
	Restart();
	debug.Exec(0xe4801004, 0);	// STR r1, [r0], #4	- output the data value
	debug.Exec(0xe1a00000, 0);	// NOP
	debug.Exec(0xe1a00000, 0);	// NOP
	debug.Exec(0xe1a00000, 0);	// NOP
	*data = debug.data;
	printf("Peek 0x%8.8X is 0x%8.8X\n", address, *data);
	return 0;
}

//////////////////////////////////////////////////////////////////////////////
// memory_write                                                             //
//////////////////////////////////////////////////////////////////////////////
int memory_write(unsigned int address, const unsigned int *data, int length)
{ 
	printf("Write Block 0x%8.8X, length 0x%8.8X\n", address, length);
	debug.Exec(0xe5900000, 0);	// LDR r0, [r0]		- put address in r0
	debug.Exec(0xe1a00000, 0);	// NOP
	debug.Exec(0xe1a00000, 0);	// NOP
	debug.Exec(0xe1a00000, 0, address);	// NOP 			- scan in address

	for (int i=0; i<length; i+=8)
	{
		debug.Exec(0xe89001fe, 0);		// LDMIA r0, [r1-r8]	- put data
		debug.Exec(0xe1a00000, 0);		// NOP
		debug.Exec(0xe1a00000, 0);		// NOP
		debug.Exec(0xe1a00000, 0, *data++);		// NOP 			- scan in data 1
		debug.Exec(0xe1a00000, 0, *data++);		// NOP 			- scan in data 2
		debug.Exec(0xe1a00000, 0, *data++);		// NOP 			- scan in data 3
		debug.Exec(0xe1a00000, 0, *data++);		// NOP 			- scan in data 4
		debug.Exec(0xe1a00000, 0, *data++);		// NOP 			- scan in data 5
		debug.Exec(0xe1a00000, 0, *data++);		// NOP 			- scan in data 6
		debug.Exec(0xe1a00000, 0, *data++);		// NOP 			- scan in data 7
		debug.Exec(0xe1a00000, 0, *data++);		// NOP 			- scan in data 8
		debug.Exec(0xe8a001fe, 0);		// STMIA r0!, {r1-r8}	- store r1 in location of r0
		debug.Exec(0xe1a00000, 1);		// Run at system speed
		Restart();
	}

	return 0;
}

//////////////////////////////////////////////////////////////////////////////
// memory_read                                                              //
//////////////////////////////////////////////////////////////////////////////
int memory_read(unsigned int  address, unsigned int *data, int length)
{
	for (int i=0; i<length; i++)
	{
		debug.Exec(0xe5900000, 0);		// LDR r0, [r0]		- put address in r0
		debug.Exec(0xe1a00000, 0);		// NOP
		debug.Exec(0xe1a00000, 0);		// NOP
		debug.Exec(0xe1a00000, 0, address);		// NOP 			- scan in address
		debug.Exec(0xe4901004, 0);		// LDR r1, [r0], #4	- load r1 from location of r0
		debug.Exec(0xe1a00000, 1);		// Run at system speed
		Restart();
		debug.Exec(0xe4801004, 0);	// STR r1, [r0], #4	- output the data value
		debug.Exec(0xe1a00000, 0);	// NOP
		debug.Exec(0xe1a00000, 0);	// NOP
		debug.Exec(0xe1a00000, 0);	// NOP
		*data = debug.data;

		printf("Peek 0x%8.8X is 0x%8.8X\n", address, *data);

		address++;
		data++;
	}

	return 0;
}

//////////////////////////////////////////////////////////////////////////////
// Test                                                                     //
//////////////////////////////////////////////////////////////////////////////
int Test()
{
	//printf("%08X\n", Reverse(0xAAAA));

//R0=000001C0
//PC=000001A8

	printf("debug_halt() = %d\n", debug_halt());

	//unsigned int data[256];
	//memory_peek(0x00000000, data);


	/*
			debug.Exec(0xe5800000, 0);			// STR r0, [r0]	- Save R0 before use
			debug.Exec(0xe1a0000f, 0);			// MOV r0, PC 	- Copy PC to R0
			debug.Exec(0xe5800000, 0);			// STR r0, [r0] - Save PC into R0
			printf("R0=%08X\n", debug.Exec(0xe1a00000, 0));			// NOP - Read out R0
			debug.Exec(0xe1a00000, 0);			// NOP
			unsigned int pc = debug.Exec(0xe1a00000, 0) - 0x18;		//  NOP	 - Read out PC & correct for delay
			printf("PC=%08X\n", pc);

	/*
	for (int i=0; i<32; i++)
	{
		printf("%3d %08X\n", i, debug.Exec(i,0));
		//printf("%3d %08X\n", i, eice.Read(i));
	}*/

	return 0;
}



//////////////////////////////////////////////////////////////////////////////
// ~Device                                                                  //
//////////////////////////////////////////////////////////////////////////////
}

⌨️ 快捷键说明

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