Added ENotifyKeypresses and ECaptureCtrlC flags to CCommandBase.
Commands can now get keypresses and handle ctrl-C via callbacks instead of having to implement custom active objects. As part of this extended the CCommandBase extension interface to MCommandExtensionsV2 for the new virtual functions KeyPressed(TUint aKeyCode, TUint aModifiers) and CtrlCPressed(). sudo now cleans up correctly by using ECaptureCtrlC.
// 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