From ae0c720396ea87d57dc5c9b54873b829896ff5e7 Mon Sep 17 00:00:00 2001 From: CNLohr <lohr85@gmail.com> Date: Wed, 21 Jun 2023 04:22:54 -0400 Subject: [PATCH] Closes #160 - Add `monitor reset` command. --- minichlink/microgdbstub.h | 38 ++++++++++++++++++++++---------------- minichlink/minichgdb.c | 6 ++++++ minichlink/minichlink.exe | Bin 94720 -> 95232 bytes 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/minichlink/microgdbstub.h b/minichlink/microgdbstub.h index 5042131..3912903 100644 --- a/minichlink/microgdbstub.h +++ b/minichlink/microgdbstub.h @@ -29,6 +29,7 @@ void RVDebugExec( void * dev, int halt_reset_or_resume ); int RVReadMem( void * dev, uint32_t memaddy, uint8_t * payload, int len ); int RVHandleBreakpoint( void * dev, int set, uint32_t address ); int RVWriteRAM(void * dev, uint32_t memaddy, uint32_t length, uint8_t * payload ); +void RVCommandResetPart( void * dev ); void RVHandleDisconnect( void * dev ); void RVHandleGDBBreakRequest( void * dev ); void RVHandleKillRequest( void * dev ); @@ -61,7 +62,7 @@ typedef struct pollfd { SOCKET fd; SHORT events; SHORT revents; }; #define POLLIN 0x0001 #define POLLERR 0x008 #define POLLHUP 0x010 -int WSAAPI WSAPoll(struct pollfd * fdArray, ULONG fds, INT timeout ); +int WSAAPI WSAPoll(struct pollfd * fdArray, ULONG fds, INT timeout ); #endif #define poll WSAPoll #define socklen_t uint32_t @@ -171,22 +172,27 @@ void HandleGDBPacket( void * dev, char * data, int len ) { case 'q': if( StringMatch( data, "Attached" ) ) - SendReplyFull( "1" ); //Attached to an existing process. + SendReplyFull( "1" ); //Attached to an existing process. else if( StringMatch( data, "Supported" ) ) - SendReplyFull( "PacketSize=f000;qXfer:memory-map:read+" ); + SendReplyFull( "PacketSize=f000;qXfer:memory-map:read+" ); else if( StringMatch( data, "C") ) // Get Current Thread ID. (Can't be -1 or 0. Those are special) - SendReplyFull( "QC1" ); + SendReplyFull( "QC1" ); else if( StringMatch( data, "fThreadInfo" ) ) // Query all active thread IDs (Can't be 0 or 1) SendReplyFull( "m1" ); else if( StringMatch( data, "sThreadInfo" ) ) // Query all active thread IDs, continued - SendReplyFull( "l" ); + SendReplyFull( "l" ); + else if( StringMatch( data, "Rcmd,7265736574" ) ) // "monitor reset" + { + RVCommandResetPart( dev ); // Force reset + SendReplyFull( "+" ); + } else if( StringMatch( data, "Xfer:memory-map" ) ) { int mslen = strlen( MICROGDBSTUB_MEMORY_MAP ) + 32; char map[mslen]; struct InternalState * iss = (struct InternalState*)(((struct ProgrammerStructBase*)dev)->internal); snprintf( map, mslen, MICROGDBSTUB_MEMORY_MAP, iss->flash_size, iss->sector_size, iss->ram_size ); - SendReplyFull( map ); + SendReplyFull( map ); } else { @@ -620,16 +626,16 @@ int MicroGDBStubStartup( void * dev ) { #if defined( WIN32 ) || defined( _WIN32 ) { - WORD wVersionRequested; - WSADATA wsaData; - int err; - wVersionRequested = MAKEWORD(2, 2); - - err = WSAStartup(wVersionRequested, &wsaData); - if (err != 0) { - fprintf( stderr, "WSAStartup failed with error: %d\n", err); - return 1; - } + WORD wVersionRequested; + WSADATA wsaData; + int err; + wVersionRequested = MAKEWORD(2, 2); + + err = WSAStartup(wVersionRequested, &wsaData); + if (err != 0) { + fprintf( stderr, "WSAStartup failed with error: %d\n", err); + return 1; + } } #endif diff --git a/minichlink/minichgdb.c b/minichlink/minichgdb.c index 60fc13c..7cce3e2 100644 --- a/minichlink/minichgdb.c +++ b/minichlink/minichgdb.c @@ -71,6 +71,12 @@ void RVCommandEpilogue( void * dev ) MCF.WriteReg32( dev, DMDATA0, 0 ); } +void RVCommandResetPart( void * dev ) +{ + MCF.HaltMode( dev, HALT_MODE_HALT_AND_RESET ); + RVCommandPrologue( dev ); +} + void RVNetConnect( void * dev ) { // ??? Should we actually halt? diff --git a/minichlink/minichlink.exe b/minichlink/minichlink.exe index 13cd21c366c018e72ce7e745f3f92e9b0f8eb547..d2f7ed592a3b99d1e9577fdabf36a0e83aba03f9 100644 GIT binary patch delta 10842 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 delta 10810 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 -- GitLab