libraries/memoryaccess/hwbreak.cia
author Tom Sutcliffe <thomas.sutcliffe@accenture.com>
Sat, 31 Jul 2010 19:07:57 +0100
changeset 23 092bcc217d9d
parent 0 7f656887cf89
permissions -rw-r--r--
Tidied iocli exports, build macro tweaks. Removed 4 overloads of CCommandBase::RunCommand[L] that are no longer used at all, and changed one more to not be exported as it's only used internally to iocli.dll. fixed builds on platforms that don't support btrace or any form of tracing.

// hwbreak.cia
// 
// Copyright (c) 2010 Accenture. All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
// 
// Initial Contributors:
// Accenture - Initial contribution
//
#include <fshell/common.mmh>
#include <u32std.h>

#define READ_BCR(cond, n, resultreg) asm("MRC"#cond" p14,0,"#resultreg",c0,c"#n",5")
#define WRITE_BCR(n, valuereg) asm("MCR p14,0,"#valuereg",c0,c"#n",5")
#define WRITE_BVR(n, valuereg) asm("MCR p14,0,"#valuereg",c0,c"#n",4")

#ifdef __GCCE__
#ifdef __NAKED__
#undef __NAKED__
#endif
#define __NAKED__ __attribute__((__naked__))
#endif

__NAKED__ void MCR_SetContextIdBrp(TInt /*aRegister*/, TUint /*aContextId*/)
	{
	asm("ldr r2, KContextIdBCR");
	
	// Use BVR 4 or 5 as appropriate
	asm("cmp r0, #4");
	asm("beq usefour");
	
	// otherwise use 5
	WRITE_BVR(5, r1);
	WRITE_BCR(5, r2);
	asm("b contextdone");
	
	asm("usefour:");
	WRITE_BVR(4, r1);
	WRITE_BCR(4, r2);
	
	asm("contextdone:");
	__JUMP(,lr);
	
	// These are according to "ARM 13.3.9. CP14 c80-c85, Breakpoint Control Registers (BCR)"
	asm("KContextIdBCR:");
	asm(".word 0x003001E7");
	}

__NAKED__ TUint MRC_ReadBcr(TInt /*aRegister*/)
	{
	// Switch on aRegister
	asm("cmp r0, #0");
	READ_BCR(eq, 0, r0);
	__JUMP(eq, lr);

	asm("cmp r0, #1");
	READ_BCR(eq, 1, r0);
	__JUMP(eq, lr);

	asm("cmp r0, #2");
	READ_BCR(eq, 2, r0);
	__JUMP(eq, lr);

	asm("cmp r0, #3");
	READ_BCR(eq, 3, r0);
	__JUMP(eq, lr);

	asm("cmp r0, #4");
	READ_BCR(eq, 4, r0);
	__JUMP(eq, lr);

	asm("cmp r0, #5");
	READ_BCR(eq, 5, r0);
	__JUMP(eq, lr);
	
	// Shouldn't get here, compiler shutter-upper
#ifdef __GCCE__
	return 0;
#else
	__JUMP(, lr);
#endif
	}
	
__NAKED__ void MCR_SetBreakpointPair(TInt /*aRegister*/, TUint /*aBvrValue*/, TUint /*aBcrValue*/ )
	{
	// Switch on aRegister
	asm("cmp r0, #0");
	asm("beq zero");
	asm("cmp r0, #1");
	asm("beq one");
	asm("cmp r0, #2");
	asm("beq two");
	asm("cmp r0, #3");
	asm("beq three");
	
	// If we reach here it's an error...
	asm("b done");
	
	asm("zero:");
	WRITE_BVR(0, r1);
	WRITE_BCR(0, r2);
	asm("b done");
	
	asm("one:");
	WRITE_BVR(1, r1);
	WRITE_BCR(1, r2);
	asm("b done");
	
	asm("two:");
	WRITE_BVR(2, r1);
	WRITE_BCR(2, r2);
	asm("b done");
	
	asm("three:");
	WRITE_BVR(3, r1);
	WRITE_BCR(4, r2);
	asm("b done");
	
	asm("done:");
	__JUMP(,lr);
	}

__NAKED__ TUint32 GetDscr()
	{
	asm("MRC p14,0,r0,c0,c1,0");
	__JUMP(,lr);
	}
	
__NAKED__ TUint32 GetDrar()
	{
	// Read Debug ROM Address Register
	asm("MRC p14, 0, r0, c1, c0, 0");
	__JUMP(,lr);
	}

__NAKED__ TUint32 GetDsar()
	{
	// Read Debug Self Address Offset Register
	asm("MRC p14, 0, r0, c2, c0, 0");
	__JUMP(,lr);
	}

__NAKED__ void MCR_SetDscr(TUint32 /*aVal*/)
	{
	asm("MCR p14,0,r0,c0,c1,0");
	__JUMP(,lr);
	}

__NAKED__ TUint32 GetContextId()
	{
	asm("MRC p15, 0, r0, c13, c0, 1");
	__JUMP(,lr);
	}

__NAKED__ void Dsb()
	{
	asm("Dsb:");
	// Data Sync Barrier
	// From the various definitions of ARM_DSBxx in cpudefs.h
#if defined(FSHELL_ARM11XX_SUPPORT)
	asm("mcr p15, 0, r0, c7, c10, 4 ")
#elif defined(FSHELL_ARM_MEM_MAPPED_DEBUG)
	asm("nop"); // Shut up complaints about branches to non-code symbols
	asm(".word %a0" : : "i" ((TInt)(0xf57ff04f)));
#endif
	__JUMP(,lr);
	}

__NAKED__ void Isb()
	{
	asm("Isb:");
	// Instruction Sync Barrier
	// From the various definitions of ARM_ISBxx in cpudefs.h

#if defined(FSHELL_ARM11XX_SUPPORT)
	asm("mcr p15, 0, r0, c7, c5, 4 ")
#elif defined(FSHELL_ARM_MEM_MAPPED_DEBUG)
	asm("nop"); // Shut up complaints about branches to non-code symbols
	asm(".word %a0" : : "i" ((TInt)(0xf57ff06f)));
#endif
	__JUMP(,lr);
	}

__NAKED__ void Imb()
	{
	// Instruction Memory Barrier
	asm("push {r14}");
	asm("bl Dsb");
	asm("bl Isb");
	asm("pop {r14}");
	__JUMP(,lr);
	}


#if 0
__NAKED__ void SetIvaBrp(TUint /*aAddress*/, TBool /*aUseContextIdFive*/, TInt /*aRegister*/ )
	{
	asm("cmp r1, #0");
	// r3 gets the BCR value
	asm("ldreq r3, KIvaBcrLinkedToFour");
	asm("ldrne r3, KIvaBcrLinkedToFive");
	asm("b DoSetIvaBrp"); // DoSetIvaBrp handles the return
	
	asm("KIvaBcrLinkedToFour:");
	asm(".word 0x001401E5");
	asm("KIvaBcrLinkedToFive:");
	asm(".word 0x001501E5");
	}	

__NAKED__ void UnsetBrp(TInt /*aRegister*/)
	{
	asm("mov r2, r0");
	asm("mov r1, #0");
	asm("mov r0, #0");
	asm("ldr r3, KIvaBcrDisabled");
	asm("b DoSetIvaBrp");
	
	asm("KIvaBcrDisabled:");
	asm(".word 0x001401E4");
	}
#endif