Hello Julien, thank you for your answer and sorry for the delay.
2017-06-14 14:26 GMT+02:00 Julien Grall <julien.gr...@arm.com>: > > > On 06/12/2017 10:34 AM, Florian Jakobsmeier wrote: > >> Dear all, >> > > Hello Florian, > > > I don't have much experience with the debug registers, I have CCed some > folks who may have looked at it. > > as part of my Bachelor's Thesis I'm trying to implement a single-stepping >> functionality for Xen on ARMv7. My problem with this is, that I'm not able >> to trigger a Hardware Breakpoint, which is configured to use Instruction >> Address Mismatch and route the exception to Xen. >> > > You are looking at single-stepping for guest, right? > > Yes I'm trying to implement guest single stepping. > >> I took the x86 single_step implementation as a reference. To test my >> implementation I extended the given "xen-access" tool test, in order to >> forward the SS request from xen-access.c to ./xen/arch/arm/monitor.c to the >> "arch_monitor_domctl_event" function (just like the x86 implementation) >> >> There, I set the necessary registers according to the ARM Architectur >> Manual (ARM DDI 0406C-b). My basic idea is to perform the following steps >> (in this order): >> 1) Configure the system to route debug exceptions to Hyp Mode >> 2) Initialize one breakpoint for Address Mismatching in Non-Secure PL1/PL0 >> 3) Define the "to be compared" address as "~0x3" (which is all 1s except >> Bit[1:0]) >> 4) Set the MDBGen to 1 in order to enable Monitor Debug Mode >> >> To check whether or not my values are set in the registers I print every >> value before and after manipulation to ensure that my values are adopted. >> To access the registers I used the already defines Makros (DBGBCR0), but >> for testing reasons I work with the general definition (e.g. >> WRITE_SYSREG(#VALUE,p14,0,c0,c0,5) for DBGBCR0 ). >> >> Preparation: >> >> I ensured that the DBGen Signal is High, I checked the Debug Version >> which is v7.1 (read from the DBGAUTHSTATUS). I also made sure that the >> underlying system supports sufficient breakpoints. >> >> These are the values I set in the different registers (in this order >> again). Every bit that I don't mention is set to 0 >> >> - HDCR.{TDRA,TDOSA,TDA,TDE = 1} >> which enables routing to Hyp. According to the ARM ARM setting >> TDRA,TDOSA,TDA is required when setting TDE >> >> - DBGBCR0.{BT=0b0100, SSC=0b01, PMC=0b11, E=0b1}= 0x404007 >> this should enable unlinked Address Musmatch, for Non-Secure PL0 > >> - DBGBVR0.{IA = ~0x3} >> which sets every bit to 1 (this address should never be reached as it is >> mismatched) >> >> - DBGDSCREXT.{MDBGen=1} >> which enables Monitor Debug Mode >> >> >> With the value set in HVBAR (hyp_traps_vector in >> /xen/arch/arm/arm32/entry.S) the generated HypTrap (HypTrap instead of >> PrefetchAbort because of the routing) should be handled in >> do_trap_guest_sync. In this method the "hsr.ec <http://hsr.ec>" Bits >> should indicate a PrefetchAbort exception (hsr.ec <http://hsr.ec>=0x20) >> whenever the Breakpoint triggers. >> >> I added a simple if statement to print a string when such a exception was >> thrown. >> >> Unfortunately these prints are never generated, which indicates that >> either I'm searching for the exception handling on the wrong location or my >> breakpoints are not correctly configured. >> >> To check if my configuration is wrong, I also tried the KDB configuration >> for the DBGBCR (which is DBGBCR=0x4001E7 as far as I understood). But this >> changed nothing in the behaviour. >> >> As Hardware I tested my code with an Arndale as well as a Odroid XU board >> (Exynos 5250). >> >> It would be great if anyone, who has experience with the ARM >> architecture, could help me in finding the missing information that is >> required to successfully set up an address mismatch breakpoint and >> succesfully route the associated exceptions to Xen. >> > > I've looked at the spec and your description seem to match it. Where do > you configure the debug registers? Is it the vm_event handler or when > returning to the guest vCPU? > > Ok thats good to hear. As mentioned, my approach is to extend the xen_access test file. Which sets the registers in the Monitor.c in /xen/xen/arch/arm (so from within the Hypervisor). Startet is this routin from DOM0. So the execution starts in /tools/tests/xen-access and gets forwarded to this function. I "trigger" this event by starting the compiled xen-access.com file from within the Dom0 But I'm not quite sure whether this is what you wanted to know. > Also, would you mind to share your code? > > Here are the important parts: This is the extended Switch-Case in monitor.c/arch_monitor_domctl_event() +++ Github/xen/xen/arch/arm/monitor.c 2017-06-19 14:40:41.156356471 +0200 @@ -28,6 +28,7 @@ struct xen_domctl_monitor_op *mop) { struct arch_domain *ad = &d->arch; bool_t requested_status = (XEN_DOMCTL_MONITOR_OP_ENABLE == mop->op); switch ( mop->event ) @@ -45,6 +46,124 @@ break; } + case XEN_DOMCTL_MONITOR_EVENT_SINGLESTEP: + { + //Set Debug to Linked Addres + //See AARM C3.3.7 Linked comparisons for [...] + + //Example on ARM ARM 2051 + + gprintk(XENLOG_ERR, "Setup HypTrap Route done\n"); + gprintk(XENLOG_ERR, "[Before] Reading HDCR: 0x%x\n", READ_SYSREG( HDCR)); + gprintk(XENLOG_ERR, "[Before] Reading DBGBCR2: 0x%x\n", READ_SYSREG( p14,0,c0,c0,5)); + gprintk(XENLOG_ERR, "[Before] Reading DBGBVR: 0x%x\n", READ_SYSREG( p14,0,c0,c0,4)); + gprintk(XENLOG_ERR, "[Before] Reading DBGDSCREXT:0x%x\n", READ_SYSREG(DBGDSCREXT)); + + + //Route Exceptions to Hypervisor + WRITE_SYSREG(READ_SYSREG(HDCR) | HDCR_TDRA|HDCR_TDOSA|HDCR_TDA|HDCR_TDE, HDCR) + + + //DBGBCR2 = (p14,0,c0,c2,5)== Unliked Address Mismatch: 0b0100==0x404007 + //(linked: 0b0101) -> + //PCM: Bit 1,2 -> Value=0b11 -> PL0/PL1 + //HCM: Bit 13 -> Value=0b00 -> No HypMode Trap + //SSC: Bit 14/15 -> Value 0b01 -> NonSecure only + //BAS: ARM + Address + BAS=0b0000 -> Mismatch Hit (2047) + // Res mask BT LBN SSC HCM SBZP BAS RES PMC E + // 000 00000 0101 0011 01 0 0000 0000 00 11 1 = 0x534007 + // 000 00000 0100 0000 01 0 0000 0000 00 11 1 = 0x404007 + // 000 00000 0100 0000 00 0 0000 1111 00 11 1 = 0x4001E7 (DBG SingleStep) + + //initalize BP + WRITE_SYSREG(0x404007, p14,0,c0,c0,5); + + + + //BVR: Breakpoint value register + // TODO: 1³² or 0³² as BVR1 Address? + // Instruction Address Res + // 111111111111111111111111111111 00 + //DBGBVR0 = p14,0,c0,c2,4 + + WRITE_SYSREG(~0x3,p14,0,c0,c0,4); + + //DBGDSCR = Enable Invasive Debug + Monitor Mode + //MDBGen[15] = 1 + //HDBGen[14] = 0 + //MOE[5:2] = 0b0001 + //DBGack[10] = 1 DebugAcknowledge -> forced BP to give signal (Read as UNpredigtable) + //0000 0000 0000 0000 0100 1000 00 0001 00 = 0x8004 (mit DBGACK=0x4404) + // 0010 0000 0100 0100 0000 00 0001 10 + + WRITE_SYSREG(0x8000,DBGDSCREXT); + //Enable BP by setting DBGBCR0.E = 1 + WRITE_SYSREG(READ_SYSREG(p14,0,c0,c0,5) | 1,p14,0,c0,c0,5 ); + isb(); + gprintk(XENLOG_ERR, "[After] Reading DBGAUTHSTATUS:0x%x\n", READ_SYSREG(p14, 0, c7, c14, 6)); + gprintk(XENLOG_ERR, "[After] Reading HDCR: 0x%x\n", READ_SYSREG( HDCR)); + gprintk(XENLOG_ERR, "[After] Reading DBGBCR2: 0x%x\n", READ_SYSREG( p14,0,c0,c0,5)); + //gprintk(XENLOG_ERR, "[After] Reading DBGBCR3: 0x%x\n", READ_SYSREG( p14,0,c0,c3,5)); + gprintk(XENLOG_ERR, "[After] Reading DBGBVR: 0x%x\n", READ_SYSREG( p14,0,c0,c0,4)); + gprintk(XENLOG_ERR, "[After] Reading DBGDSCREXT:0x%x\n", READ_SYSREG(DBGDSCREXT)); + gprintk(XENLOG_ERR, "[After] Reading DBGDIDR: 0x%x\n", READ_SYSREG(DBGDIDR)); + + + + return 0; + } Greetings and thank you again for your help Florian
_______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel