diff -r 000000000000 -r 7f656887cf89 libraries/memoryaccess/hwbreak.cia --- /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 +#include + +#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