{"action":"created","issue":{"url":"https://api.github.com/repos/mbedmicro/pyOCD/issues/91","labels_url":"https://api.github.com/repos/mbedmicro/pyOCD/issues/91/labels{/name}","comments_url":"https://api.github.com/repos/mbedmicro/pyOCD/issues/91/comments","events_url":"https://api.github.com/repos/mbedmicro/pyOCD/issues/91/events","html_url":"https://github.com/mbedmicro/pyOCD/pull/91","id":53862059,"number":91,"title":"Enable read/write of FPU registers from GDB","user":{"login":"adamgreen","id":1060664,"avatar_url":"https://avatars.githubusercontent.com/u/1060664?v=3","gravatar_id":"","url":"https://api.github.com/users/adamgreen","html_url":"https://github.com/adamgreen","followers_url":"https://api.github.com/users/adamgreen/followers","following_url":"https://api.github.com/users/adamgreen/following{/other_user}","gists_url":"https://api.github.com/users/adamgreen/gists{/gist_id}","starred_url":"https://api.github.com/users/adamgreen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adamgreen/subscriptions","organizations_url":"https://api.github.com/users/adamgreen/orgs","repos_url":"https://api.github.com/users/adamgreen/repos","events_url":"https://api.github.com/users/adamgreen/events{/privacy}","received_events_url":"https://api.github.com/users/adamgreen/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-01-09T12:14:28Z","updated_at":"2015-01-10T20:48:11Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/mbedmicro/pyOCD/pulls/91","html_url":"https://github.com/mbedmicro/pyOCD/pull/91","diff_url":"https://github.com/mbedmicro/pyOCD/pull/91.diff","patch_url":"https://github.com/mbedmicro/pyOCD/pull/91.patch"},"body":"The CortexM class already had readCoreRegister() and\r\nwriteCoreRegister() methods which should have been able to read/write\r\nthe FPU registers along with all of the other core ARM registers.  It\r\nturns out that this functionality was broken since the indices for the\r\nFPU registers in the CORE_REGISTER map weren't defined correctly.  For\r\nexample the index for s0 should have been 64 instead of 128.\r\n\r\nEven once those read/write API were working correctly, more changes\r\nwere required to actually inform GDB when a device has FPU registers\r\nand then support reading and writing of them:\r\n* When a device has a FPU, the getTargetXML() should return different\r\n  XML which includes the FPU registers.  This lets GDB know what\r\n  registers are available on the device.\r\n* I modified the GDBServer class to now support both the 'g' and 'G'\r\n  command requests.  Previously it just supported the 'g' command which\r\n  allows reading all of the registers described by the target XML at\r\n  one time.  The 'G' command goes in the other direction and allows GDB\r\n  to update the contents of all registers in one command.  Now that\r\n  the 'g' register command is supported, it is possible to remove the\r\n  slightly redundant 'p' command.  This command reads one register at a\r\n  time.  GDB doesn't even issue the 'p', read register command if 'g'\r\n  functions correctly and returns all of the device's registers.\r\n  Previously GDB would use it to compensate for the fact that the 'g'\r\n  command wasn't returning the value of the XPSR register.\r\n* Previously the 'g', read registers command, was mostly implemented in\r\n  the GDBServer class.  I pushed most of the implementation of both the\r\n  'g' and 'G' command handlers down into the CortexM target class since\r\n  it is the class which actually has knowledge of what registers should\r\n  be passed back and forth with GDB for a particular device.  Previously\r\n  the GDBServer code was reaching directly into the CortexM module to\r\n  pull its CORE_REGISTER list.  The GDBServer getRegisters() and\r\n  setRegisters() methods now just call the target's\r\n  getRegisterContext() and setRegisterContext() methods.\r\n* I added new readCoreRegisterRaw() and writeCoreRegisterRaw() methods in\r\n  the CortexM class to complement the existing readCoreRegister() and\r\n  writeCoreRegister() methods.  These new methods do most of what the\r\n  existing methods did except that they always return the register\r\n  values as 32-bit integers.  The original implementations would pack/\r\n  unpack floating point register values.  GDB wants them in the raw\r\n  format and it will be responsible for this packing/unpacking.  I\r\n  simplified readCoreRegister() and writeCoreRegister() methods to just\r\n  perform the necessary float packing/unpacking and then use the new\r\n  *Raw() methods to perform the rest of the work.\r\n* I also extracted some duplicate code out into the\r\n  registerNameToIndex() method in CortexM class."},"comment":{"url":"https://api.github.com/repos/mbedmicro/pyOCD/issues/comments/69471342","html_url":"https://github.com/mbedmicro/pyOCD/pull/91#issuecomment-69471342","issue_url":"https://api.github.com/repos/mbedmicro/pyOCD/issues/91","id":69471342,"user":{"login":"adamgreen","id":1060664,"avatar_url":"https://avatars.githubusercontent.com/u/1060664?v=3","gravatar_id":"","url":"https://api.github.com/users/adamgreen","html_url":"https://github.com/adamgreen","followers_url":"https://api.github.com/users/adamgreen/followers","following_url":"https://api.github.com/users/adamgreen/following{/other_user}","gists_url":"https://api.github.com/users/adamgreen/gists{/gist_id}","starred_url":"https://api.github.com/users/adamgreen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adamgreen/subscriptions","organizations_url":"https://api.github.com/users/adamgreen/orgs","repos_url":"https://api.github.com/users/adamgreen/repos","events_url":"https://api.github.com/users/adamgreen/events{/privacy}","received_events_url":"https://api.github.com/users/adamgreen/received_events","type":"User","site_admin":false},"created_at":"2015-01-10T20:48:11Z","updated_at":"2015-01-10T20:48:11Z","body":"Thanks for trying it out.  It's weird that it fails like that.  The only thing different is that the g packet response now returns the XPSR as well.  Can you try making one change to see if it helps with your version of GDB:\r\n\r\n```diff\r\ndiff --git a/pyOCD/target/cortex_m.py b/pyOCD/target/cortex_m.py\r\nindex da02d40..8f7fcb3 100644\r\n--- a/pyOCD/target/cortex_m.py\r\n+++ b/pyOCD/target/cortex_m.py\r\n@@ -267,7 +267,7 @@ class CortexM(Target):\r\n         <reg name=\"sp\" bitsize=\"32\" type=\"data_ptr\"/>\r\n         <reg name=\"lr\" bitsize=\"32\"/>\r\n         <reg name=\"pc\" bitsize=\"32\" type=\"code_ptr\"/>\r\n-        <reg name=\"xpsr\" bitsize=\"32\" regnum=\"16\"/>\r\n+        <reg name=\"xpsr\" bitsize=\"32\" regnum=\"25\"/>\r\n     </feature>\r\n </target>\r\n \"\"\"\r\n@@ -291,7 +291,7 @@ class CortexM(Target):\r\n         <reg name=\"sp\" bitsize=\"32\" type=\"data_ptr\"/>\r\n         <reg name=\"lr\" bitsize=\"32\"/>\r\n         <reg name=\"pc\" bitsize=\"32\" type=\"code_ptr\"/>\r\n-        <reg name=\"xpsr\" bitsize=\"32\" regnum=\"16\"/>\r\n+        <reg name=\"xpsr\" bitsize=\"32\" regnum=\"25\"/>\r\n     </feature>\r\n     <feature name=\"org.gnu.gdb.arm.vfp\">\r\n         <reg name=\"d0\" bitsize=\"64\" type=\"ieee_double\"/>\r\n```\r\n\r\nI am more used to seeing 25 as the regnum for xpsr but it was already set to 16 before so I left it."}}