Skip to content

Commit

Permalink
Fix GDB on minichlink.
Browse files Browse the repository at this point in the history
  • Loading branch information
cnlohr committed Nov 13, 2024
1 parent f2790f9 commit dc7db24
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 38 deletions.
55 changes: 31 additions & 24 deletions minichlink/microgdbstub.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,21 @@
#ifndef _MICROGDBSTUB_H
#define _MICROGDBSTUB_H

enum HaltResetResumeType
{
HALT_TYPE_SINGLE_STEP = 9,
HALT_TYPE_CONTINUE = 2,
HALT_TYPE_CONTINUE_WITH_SIGNAL = 4,
};

// You must write these for your processor.
void RVNetPoll(void * dev );
int RVSendGDBHaltReason( void * dev );
void RVNetConnect( void * dev );
int RVGetNumRegisters( void * dev );
int RVReadCPURegister( void * dev, int regno, uint32_t * regret );
int RVWriteCPURegister( void * dev, int regno, uint32_t value );
void RVDebugExec( void * dev, int halt_reset_or_resume );
int RVDebugExec( void * dev, enum HaltResetResumeType 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 );
Expand Down Expand Up @@ -203,6 +210,7 @@ void HandleGDBPacket( void * dev, char * data, int len )
data++;

char cmd = *(data++);
//printf( "DATA: [%c] %c%c%c%c%c%c%c%c%c\n",cmd, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8] );
switch( cmd )
{
case 'q':
Expand Down Expand Up @@ -237,7 +245,7 @@ void HandleGDBPacket( void * dev, char * data, int len )
SendReplyFull( "" );
break;
}
printf("Got monitor command: %s\n", cmd);
//printf("Got monitor command: %s\n", cmd);
// Support commands that OpenOCD also does:
// https://openocd.org/doc/html/General-Commands.html
if(StringMatch(cmd, "halt")) {
Expand Down Expand Up @@ -273,8 +281,8 @@ void HandleGDBPacket( void * dev, char * data, int len )
SendReplyFull( "+" );
}
else {
printf("Unknown monitor command '%s', use 'monitor help'.\n", cmd);
MakeGDBPrintText("Unknown monitor command, use 'monitor help'\n");
fprintf( stderr, "Unknown monitor command '%s', use 'monitor help'.\n", cmd );
MakeGDBPrintText( "Unknown monitor command, use 'monitor help'\n" );
SendReplyFull( "-" );
}
} else {
Expand All @@ -292,24 +300,25 @@ void HandleGDBPacket( void * dev, char * data, int len )
}
else
{
printf( "Unknown command: %s\n", data );
fprintf( stderr, "Unknown command: %s\n", data );
SendReplyFull( "" );
}
break;
case 'c':
case 'C':
RVDebugExec( dev, (cmd == 's' )?9:(cmd == 'C')?4:2 );
SendReplyFull( "OK" );
RVDebugExec( dev, (cmd == 's' )?HALT_TYPE_SINGLE_STEP:(cmd == 'C')?HALT_TYPE_CONTINUE_WITH_SIGNAL:HALT_TYPE_CONTINUE );
//SendReplyFull( "OK" ); ... this will be sent from RVNetPoll
break;
case 's':
RVDebugExec( dev, 4 );
SendReplyFull( "OK" );
RVDebugExec( dev, HALT_TYPE_SINGLE_STEP );
//SendReplyFull( "OK" ); // Will be sent from RVNetPoll
//RVHandleGDBBreakRequest( dev );
RVSendGDBHaltReason( dev );
break;
case 'D':
// Handle disconnect.
RVHandleDisconnect( dev );
//SendReplyFull( "OK" );
break;
case 'k':
RVHandleKillRequest( dev ); // no reply.
Expand All @@ -320,7 +329,6 @@ void HandleGDBPacket( void * dev, char * data, int len )
if( ReadHex( &data, -1, &reg ) < 0 ) goto err;
if( *(data++) != ',' ) goto err;
if( ReadHex( &data, -1, &value ) < 0 ) goto err;
printf( "REG: %02x = %08x\n", reg, value );
RVWriteCPURegister( dev, reg, value );
break;
}
Expand Down Expand Up @@ -432,24 +440,23 @@ void HandleGDBPacket( void * dev, char * data, int len )
{
data += 10; // FlashWrite

printf( "Write\n" );
if( *(data++) != ':' ) goto err;
uint32_t address_to_write = 0;
if( ReadHex( &data, -1, &address_to_write ) < 0 ) goto err;
if( *(data++) != ':' ) goto err;
int toflash = len - (data - odata) - 1;
printf( "LEN: %08x %d %d %c\n", address_to_write, len, toflash, data[0] );
if( RVWriteFlash( dev, address_to_write, len, (uint8_t*)data ) == 0 )
fprintf( stderr, "Writing flash: %08x len %d\n", address_to_write, toflash );
if( RVWriteFlash( dev, address_to_write, toflash, (uint8_t*)data ) == 0 )
{
printf( "Write OK\n" );
fprintf( stderr, "Write OK\n" );
SendReplyFull( "OK" );
}
else
SendReplyFull( "E 93" );
}
else
{
printf( "Warning: Unknown v command %s\n", data );
fprintf( stderr, "Warning: Unknown v command %s\n", data );
SendReplyFull( "E 01" );
}
break;
Expand Down Expand Up @@ -493,12 +500,12 @@ printf( "LEN: %08x %d %d %c\n", address_to_write, len, toflash, data[0] );
SendReplyFull( "" );
break;
default:
printf( "UNKNOWN PACKET: %d (%s)\n", len, data-1 );
fprintf( stderr, "UNKNOWN PACKET: %d (%s)\n", len, data-1 );
for( i = 0; i < len; i++ )
{
printf( "%02x ", data[i] );
fprintf( stderr, "%02x ", data[i] );
}
printf( "\n" );
fprintf( stderr, "\n" );
goto err;
break;
}
Expand Down Expand Up @@ -543,7 +550,7 @@ void MicroGDBStubHandleClientData( void * dev, const uint8_t * rxdata, int len )
{
char escaped = c ^ 0x20;
gdbbuffer[gdbbufferplace++] = escaped;
printf( "ESCAPED @ %02x -> %c [%d]\n", gdbbufferplace, escaped, escaped );
fprintf( stderr, "ESCAPED @ %02x -> %c [%d]\n", gdbbufferplace, escaped, escaped );
gdbbufferstate = 1;
}
break;
Expand All @@ -570,15 +577,15 @@ void MicroGDBStubHandleClientData( void * dev, const uint8_t * rxdata, int len )
}
else
{
printf( "Checksum Error: Got %02x expected %02x / len: %d\n", gdbrunningcsum, gdbchecksum, gdbbufferplace );
fprintf( stderr, "Checksum Error: Got %02x expected %02x / len: %d\n", gdbrunningcsum, gdbchecksum, gdbbufferplace );
int i;
for( i = 0; i < gdbbufferplace; i++ )
{
int c = ((uint8_t*)gdbbuffer)[i];
printf( "%02x [%c] ", c, (c>=32 && c < 128)?c:' ');
if( ( i & 0xf ) == 0xf ) printf( "\n" );
fprintf( stderr, "%02x [%c] ", c, (c>=32 && c < 128)?c:' ');
if( ( i & 0xf ) == 0xf ) fprintf( stderr, "\n" );
}
printf( "\n" );
fprintf( stderr, "\n" );
MicroGDBStubSendReply( "-", -1, 0 );
}

Expand Down Expand Up @@ -693,7 +700,7 @@ int MicroGDBPollServer( void * dev )

if( r < 0 )
{
printf( "R: %d\n", r );
fprintf( stderr, "R poll(...): %d\n", r );
}

//If there's faults, bail.
Expand Down
36 changes: 25 additions & 11 deletions minichlink/minichgdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ void SendReplyFull( const char * replyMessage );
int shadow_running_state = 1;
int last_halt_reason = 5;
uint32_t backup_regs[33]; //0..15 + PC, or 0..32 + PC
int gdbasserting_break = 0;

#define MAX_SOFTWARE_BREAKPOINTS 128
int num_software_breakpoints = 0;
Expand Down Expand Up @@ -125,6 +126,11 @@ void RVNetPoll(void * dev )
last_halt_reason = 5;//((dscr>>6)&3)+5;
RVSendGDBHaltReason( dev );
}
else
{
// this is the reply to 's' or 'c' packets.
SendReplyFull( "OK" );
}
shadow_running_state = statusrunning;
}
}
Expand Down Expand Up @@ -201,7 +207,7 @@ int RVWriteCPURegister( void * dev, int regno, uint32_t value )
return 0;
}

void RVDebugExec( void * dev, int halt_reset_or_resume )
int RVDebugExec( void * dev, enum HaltResetResumeType halt_reset_or_resume )
{
struct InternalState * iss = (struct InternalState*)(((struct ProgrammerStructBase*)dev)->internal);
int nrregs = iss->nr_registers_for_debug;
Expand All @@ -211,10 +217,18 @@ void RVDebugExec( void * dev, int halt_reset_or_resume )
fprintf( stderr, "Error: Can't alter halt mode with this programmer.\n" );
exit( -6 );
}

// Special case halt_reset_or_resume = 4: Skip instruction and resume.
if( halt_reset_or_resume == 4 || halt_reset_or_resume == 2 )
if( halt_reset_or_resume == HALT_TYPE_CONTINUE_WITH_SIGNAL || halt_reset_or_resume == HALT_TYPE_CONTINUE )
{
if( gdbasserting_break )
{
// This is tricky, but I don't know how else to handle it.
// If GDB is stepping, and you ctrl+c, then, it will ignore that and keep going.
// Here I say if the user ctrl+c'd actually fail to switch run mode.
gdbasserting_break = 0;
SendReplyFull( "E 99" );
return 1;
}
// First see if we already know about this breakpoint
int matchingbreakpoint = -1;
// For this we want to advance PC.
Expand Down Expand Up @@ -259,7 +273,7 @@ void RVDebugExec( void * dev, int halt_reset_or_resume )
else
; //No change, it is a normal instruction.

if( halt_reset_or_resume == 4 )
if( halt_reset_or_resume == HALT_TYPE_CONTINUE_WITH_SIGNAL )
{
MCF.SetEnableBreakpoints( dev, 1, 1 );
}
Expand All @@ -268,9 +282,9 @@ void RVDebugExec( void * dev, int halt_reset_or_resume )
halt_reset_or_resume = HALT_MODE_RESUME;
}

if( shadow_running_state != ( halt_reset_or_resume >= 2 ) )
if( shadow_running_state != ( halt_reset_or_resume >= HALT_TYPE_CONTINUE ) )
{
if( halt_reset_or_resume < 2 )
if( halt_reset_or_resume < HALT_TYPE_CONTINUE )
{
RVCommandPrologue( dev );
}
Expand All @@ -281,7 +295,8 @@ void RVDebugExec( void * dev, int halt_reset_or_resume )
MCF.HaltMode( dev, halt_reset_or_resume );
}

shadow_running_state = halt_reset_or_resume >= 2;
shadow_running_state = halt_reset_or_resume >= HALT_TYPE_CONTINUE;
return 0;
}

int RVReadMem( void * dev, uint32_t memaddy, uint8_t * payload, int len )
Expand Down Expand Up @@ -465,10 +480,9 @@ void RVHandleDisconnect( void * dev )

void RVHandleGDBBreakRequest( void * dev )
{
if( shadow_running_state )
{
MCF.HaltMode( dev, 5 );
}
if( !shadow_running_state )
gdbasserting_break = 1;
MCF.HaltMode( dev, 5 );
}


Expand Down
5 changes: 2 additions & 3 deletions minichlink/minichlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -2128,14 +2128,14 @@ int DefaultWriteAllCPURegisters( void * dev, uint32_t * regret )
int i;
for( i = 0; i < iss->nr_registers_for_debug; i++ )
{
MCF.WriteReg32( dev, DMCOMMAND, 0x00230000 | 0x1000 | i ); // Read xN into DATA0.
if( MCF.WriteReg32( dev, DMDATA0, regret[i] ) )
{
return -5;
}
MCF.WriteReg32( dev, DMCOMMAND, 0x00230000 | 0x1000 | i ); // Read xN into DATA0.
}
MCF.WriteReg32( dev, DMCOMMAND, 0x00230000 | 0x7b1 ); // Read xN into DATA0.
int r = MCF.WriteReg32( dev, DMDATA0, regret[i] );
MCF.WriteReg32( dev, DMCOMMAND, 0x00230000 | 0x7b1 ); // Read xN into DATA0.
return r;
}

Expand Down Expand Up @@ -2172,7 +2172,6 @@ int DefaultSetEnableBreakpoints( void * dev, int is_enabled, int single_step )
else
DCSR &=~4;

//printf( "Setting DCSR: %08x\n", DCSR );
if( MCF.WriteCPURegister( dev, 0x7b0, DCSR ) )
fprintf( stderr, "Error: DCSR could not be read\n" );

Expand Down

0 comments on commit dc7db24

Please sign in to comment.