libraries/memoryaccess/hwbreak.cia
changeset 0 7f656887cf89
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libraries/memoryaccess/hwbreak.cia	Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,223 @@
+// 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