From ede94f2d23ce0fc15459427a1d5307a35a7a4b10 Mon Sep 17 00:00:00 2001 From: Manfred Steiner Date: Sun, 21 Jul 2024 16:30:10 +0200 Subject: [PATCH] asm improvements --- software/gdb-stub/.gdbinit | 25 ++-- software/gdb-stub/.gdbinit-gdbstub | 1 + software/gdb-stub/.gdbinit-nano | 16 --- software/gdb-stub/.gdbinit-sim | 17 --- software/gdb-stub/.vscode/settings.json | 97 +-------------- software/gdb-stub/src/bootloader.cpp | 149 +++++++++--------------- software/gdb-stub/src/gdb.cpp | 2 + software/gdb-stub/src/gdb.h | 47 ++++---- 8 files changed, 99 insertions(+), 255 deletions(-) create mode 100644 software/gdb-stub/.gdbinit-gdbstub diff --git a/software/gdb-stub/.gdbinit b/software/gdb-stub/.gdbinit index 4859227..cc62ea0 100644 --- a/software/gdb-stub/.gdbinit +++ b/software/gdb-stub/.gdbinit @@ -1,21 +1,20 @@ # start gdb with: -# avr-gdb -nx -x .gdbinit-sim `-ex="target remote $(cat /tmp/sim-megaavr-atmega644p-uart1)" -# avr-gdb -nx -x .gdbinit-nano +# avr-gdb -x .gdbinit-gdbstub +# avr-gdb -x .gdbinit-sim `-ex="target remote $(cat /tmp/sim-megaavr-atmega644p-uart1)" +# avr-gdb -x .gdbinit-nano -alias reset = set *((uint8_t *)0x8010fd) = 0x40 -alias startapp = set *((uint8_t *)0x8010fd) = 0x20 -alias killapp = set *((uint8_t *)0x8010fd) = 0x10 -alias gdbstatus = print *((struct gdb::Status *)0x8010fb) -alias gdbctrl = print *((struct gdb::Control *)0x8010fd) -alias gdbbreakpoint = print *((struct gdb::Breakpoint *)0x8010d7) +alias _reset = set *((uint8_t *)0x8010fd) = 0x40 +alias _startapp = set *((uint8_t *)0x8010fd) = 0x20 +alias _killapp = set *((uint8_t *)0x8010fd) = 0x10 +alias _status = print ((gdb::Gdb *)0x801039)->status +alias _ctrl = print ((gdb::Gdb *)0x801039)->ctrl +alias _breakpoint = print ((gdb::Gdb *)0x801039)->breakpoint +alias _gdb = print *((gdb::Gdb *)0x801039) +set print pretty set history save on set history size unlimited set history remove-duplicates unlimited set pagination off -#set non-stop 1 -file dist/gdb-stub_atmega644p.elf -set serial baud 115200 -#target remote /dev/pts/19 -#target remote /dev/ttyUSB1 +file dist/gdb-stub_atmega644p.elf diff --git a/software/gdb-stub/.gdbinit-gdbstub b/software/gdb-stub/.gdbinit-gdbstub new file mode 100644 index 0000000..ad7a6f7 --- /dev/null +++ b/software/gdb-stub/.gdbinit-gdbstub @@ -0,0 +1 @@ +target remote :1234 diff --git a/software/gdb-stub/.gdbinit-nano b/software/gdb-stub/.gdbinit-nano index 5efcc7b..5b2e10a 100644 --- a/software/gdb-stub/.gdbinit-nano +++ b/software/gdb-stub/.gdbinit-nano @@ -1,20 +1,4 @@ -# start gdb with `avr-gdb -nx -x .gdbinit-nano` - -alias reset = set *((uint8_t *)0x8010fd) = 0x40 -alias startapp = set *((uint8_t *)0x8010fd) = 0x20 -alias killapp = set *((uint8_t *)0x8010fd) = 0x10 -alias gdbstatus = print *((struct gdb::Status *)0x8010fb) -alias gdbctrl = print *((struct gdb::Control *)0x8010fd) -alias gdbbreakpoint = print *((struct gdb::Breakpoint *)0x8010d7) - -set history save on -set history size unlimited -set history remove-duplicates unlimited -set pagination off set non-stop 1 -file dist/gdb-stub_atmega644p.elf - set serial baud 115200 -#target remote /dev/pts/19 target remote /dev/ttyUSB1 diff --git a/software/gdb-stub/.gdbinit-sim b/software/gdb-stub/.gdbinit-sim index f8ef345..2445349 100644 --- a/software/gdb-stub/.gdbinit-sim +++ b/software/gdb-stub/.gdbinit-sim @@ -1,19 +1,2 @@ -# start gdb with: avr-gdb -nx -x .gdbinit-sim `-ex="target remote $(cat /tmp/sim-megaavr-atmega644p-uart1)" - -alias reset = set *((uint8_t *)0x8010fd) = 0x40 -alias startapp = set *((uint8_t *)0x8010fd) = 0x20 -alias killapp = set *((uint8_t *)0x8010fd) = 0x10 -alias gdbstatus = print *((struct gdb::Status *)0x8010fb) -alias gdbctrl = print *((struct gdb::Control *)0x8010fd) -alias gdbbreakpoint = print *((struct gdb::Breakpoint *)0x8010d7) - -set history save on -set history size unlimited -set history remove-duplicates unlimited -set pagination off set non-stop 1 -file dist/gdb-stub_atmega644p.elf - -set serial baud 115200 -#target remote /dev/pts/19 diff --git a/software/gdb-stub/.vscode/settings.json b/software/gdb-stub/.vscode/settings.json index df0709c..3cd553a 100644 --- a/software/gdb-stub/.vscode/settings.json +++ b/software/gdb-stub/.vscode/settings.json @@ -28,97 +28,8 @@ "[markdown]": { "files.trimTrailingWhitespace": false }, - "cSpell.words": [ - "adiw", - "APPINIT", - "APPMEM", - "atmega", - "avrdude", - "blgdb", - "Bootloader", - "BOOTLOADERMEM", - "brne", - "COMPA", - "DDRB", - "EECR", - "EEPE", - "EEPROM", - "efuse", - "Entf", - "EVWS", - "execerr", - "execovf", - "fdev", - "FLASHERASE", - "FLASHWRITE", - "fprintln", - "fputnchar", - "gdbin", - "GDBMEM", - "gdbout", - "gputc", - "gtkwave", - "hfuse", - "lfuse", - "memputc", - "memputs", - "MMCU", - "Modbus", - "monin", - "movw", - "multiprocess", - "mytrace", - "OCIE", - "ONLYLOCASE", - "padd", - "pmon", - "PORTB", - "printdbg", - "printdbgln", - "PROGMEM", - "putch", - "putln", - "putnc", - "putnchar", - "pval", - "RAMEND", - "RAMPZ", - "rbuffer", - "Recived", - "rjmp", - "rpos", - "RXCIE", - "RXEN", - "sbic", - "simavr", - "SPMCSR", - "SPMEN", - "SRAM", - "SREG", - "TCCR", - "TCNT", - "TIFR", - "TIMSK", - "tnotrun", - "TXEN", - "UBRR", - "UCSR", - "UCSZ", - "UDRE", - "USART", - "usbasp", - "vect", - "waitack", - "WDRF", - "WDTO", - "wpos", - "xmemprint", - "xprint", - "xprintmem", - "xput", - "xputc", - "xputs", - "xputsmem" - ], - "C_Cpp.errorSquiggles": "Disabled" + "cSpell.words": [], + "cSpell.ignorePaths": [ + "**/*.json", "**/*.c", "**/*.h", "**/*.cpp", "**/*.hpp", "**/Makefile" + ] } diff --git a/software/gdb-stub/src/bootloader.cpp b/software/gdb-stub/src/bootloader.cpp index 940d6a4..19d7efc 100644 --- a/software/gdb-stub/src/bootloader.cpp +++ b/software/gdb-stub/src/bootloader.cpp @@ -20,24 +20,12 @@ // #define GLOBAL_GDB_UART0 #define GLOBAL_GDB_UART1 -// #define ATT_SECTION_BOOTLOADER -// __attribute__((optimize("O0"))) #define ATT_SECTION_APP_START __attribute__((section(".app_start"))) __attribute__((strong)) -// extern const char BOOTLOADER_MSG[] BOOTLOADERMEM_0 = "gdb-stub V0.1"; -// extern const char BOOTLOADER_MSG_SEP1[] BOOTLOADERMEM_1 = " ("; -// extern const char BOOTLOADER_MSG_DATE[] BOOTLOADERMEM_2 = __DATE__; -// extern const char BOOTLOADER_MSG_SEP2[] BOOTLOADERMEM_3 = ","; -// extern const char BOOTLOADER_MSG_TIME[] BOOTLOADERMEM_4 = __TIME__; -// extern const char BOOTLOADER_MSG_END[] BOOTLOADERMEM_5 = ")\0"; - extern const char BOOTLOADER_MSG_TEXT[] BOOTLOADERMEM_0 = "gdb-stub V0.1"; -// const char BOOTLOADER_MSG_SEP1[] PROGMEM = " ("; extern const char BOOTLOADER_MSG_DATE[] BOOTLOADERMEM_1 = __DATE__; -// const char BOOTLOADER_MSG_SEP2[] PROGMEM = ","; extern const char BOOTLOADER_MSG_TIME[] BOOTLOADERMEM_2 = __TIME__; -// const char BOOTLOADER_MSG_END[] PROGMEM = ")"; uint8_t eeprom[1] __attribute__((section(".eeprom"))) = { 0x80 }; uint8_t fusex[3] __attribute__((section(".fuse"))) = { 0xe7, 0xd8, 0xff }; @@ -46,9 +34,6 @@ uint8_t lock[1] __attribute__((section(".lock"))) = { 0xff }; extern int main (); - - - namespace bootloader { void __attribute__ ((naked)) bootloaderStart () { @@ -83,12 +68,18 @@ namespace bootloader { } void __attribute__((naked)) bootloaderStartFromReset () { - asm volatile ( + #ifndef __AVR_ATmega644P__ + #error wrong CPU, fix RAMEND + #endif + __asm__ ( + ".equ RAMEND, 0x10ff \n" "__bootloader_start_from_reset: \n" "eor r1, r1 \n" "out 0x3f, r1 \n" // SREG = 0 - "ldi r28, 0xFF \n" // reset SP to 0x01ff (RAMEND for Atmega644p) - "ldi r29, 0x10 \n" + //"ldi r28, 0xFF \n" // reset SP to 0x01ff (RAMEND for Atmega644p) + // "ldi r29, 0x10 \n" + "ldi r28, lo8(RAMEND) \n" // reset SP to 0x01ff (RAMEND for Atmega644p) + "ldi r29, hi8(RAMEND) \n" "out 0x3e, r29 \n" // SPH = 0x08 "out 0x3d, r28 \n" // SPL = 0xFF "nop \n" @@ -106,13 +97,6 @@ namespace bootloader { gdb::handleUartIsrByte(UDR1); } - // void jmpTablePutc (char c) { - // asm volatile ( - // "__bootloader_putc: \n" - // ); - // putc(stdoutUart, c); - // } - void jmpTablePuts (const char *s) { asm volatile ( "__bootloader_puts: \n" @@ -152,11 +136,6 @@ namespace bootloader { void bootloaderLoop () { - // asm volatile ( - // "__bootloader_loop: \n" - // ); - // init(); - #ifdef SIMAVR eepromWriteByte(0, 0x80); #else @@ -180,47 +159,38 @@ namespace bootloader { ); } - // void __attribute__((naked)) bootloaderInit () { - // asm volatile ( - // "eor r1, r1 \n" - // "out 0x3f, r1 \n" // SREG = 0 - // "pop r23 \n" // return address to r23:r22 - // "pop r22 \n" - // "ldi r28, 0xFF \n" // reset SP to 0x08ff (RAMEND) - // "ldi r29, 0x08 \n" - // "out 0x3e, r29 \n" // SPH = 0x08 - // "out 0x3d, r28 \n" // SPL = 0xFF - // ); - // bootloaderInit2 (sizeof(struct gdb::Gdb)); - // } - void __attribute__((naked)) bootloaderInit (size_t gdbSize) { + #ifndef __AVR_ATmega644P__ + #error wrong CPU -> check SPH, SPL + #endif asm volatile ( - " pop r23 \n" // get two return addresses from stack - " pop r22 \n" - " pop r21 \n" - " pop r20 \n" - - " movw r26, r28 \n" - " ldi r30,0xfe \n" // gdb.magic - " st X, r30 \n" - " ldi r30,0x01 \n" // gdb.version - " st -X, r30 \n" - - " sub r28, r24 \n" // allocate struct Gdb on stack - " sbc r29, r25 \n" - " out 0x3e, r29 \n" // SPH = ... - " out 0x3d, r28 \n" // SPL = ... - - "loop: st Y+, r1 \n" // initialize struct Gdb - " cp r28, r26 \n" - " cpc r29, r27 \n" - " brne loop \n" - - " push r20 \n" // restore the two return addresses on stack - " push r21 \n" - " push r22 \n" - " push r23 \n" + " .equ SPH, 0x3e \n" + " .equ SPL, 0x3d \n" + " pop r23 \n" // get two return addresses from stack + " pop r22 \n" + " pop r21 \n" + " pop r20 \n" + + " movw r26, r28 \n" + " ldi r30, 0xfe \n" // gdb.magic + " st X, r30 \n" + " ldi r30,0x01 \n" // gdb.version + " st -X, r30 \n" + + " sub r28, r24 \n" // allocate struct Gdb on stack + " sbc r29, r25 \n" + " out SPH, r29 \n" // SPH = ... + " out SPL, r28 \n" // SPL = ... + + "loop: st Y+, r1 \n" // initialize struct Gdb + " cp r28, r26 \n" + " cpc r29, r27 \n" + " brne loop \n" + + " push r20 \n" // restore the two return addresses on stack + " push r21 \n" + " push r22 \n" + " push r23 \n" ); // disable watchdog (maybe enabled from restart command) @@ -263,17 +233,21 @@ namespace bootloader { } void __attribute__((naked)) jmpTableGdbStopApplication () { - // void jmpTableGdbStopApplication () { + #ifndef __AVR_ATmega644P__ + #error wrong CPU -> check RAMEND, SFR + #endif asm volatile ( - "__gdb_stopApplication: \n" - "push r25 \n" // save r25 (used for address of gdb::gdb.breakpoint) - "lds r25, 0x10fc \n" // gdb.status - "andi r25, 0x01 \n" // gdb.status.isConnected + ".equ RAMEND, 0x10ff \n" + ".equ SFR, 0x3f \n" + "__gdb_stopApplication: \n" + "push r25 \n" // save r25 (used for address of gdb::gdb.breakpoint) + "lds r25, RAMEND - 3 \n" // gdb.status + "andi r25, 0x01 \n" // gdb.status.isConnected "breq __gdb_stopApplication_end \n" - "in r25, 0x3f \n" // SFR -> r25 - "cli \n" // disable interrupts while saveBreakpoints() - "push r25 \n" // save original SFR - "push r24 \n" // save parameter register + "in r25, SFR \n" // SFR -> r25 + "cli \n" // disable interrupts while saveBreakpoints() + "push r25 \n" // save original SFR + "push r24 \n" // save parameter register ); gdb::saveBreakpointRegs(GDB_BREAKPOINT_PTR); struct gdb::Gdb *pgdb = GDB_PTR; @@ -283,11 +257,12 @@ namespace bootloader { ); gdb::stopApplication(); asm volatile ( - "pop r25 \n" // restore SFR - "out 0x3f, r25 \n" + ".equ SFR, 0x3f \n" + "pop r25 \n" // restore SFR + "out SFR, r25 \n" "__gdb_stopApplication_end: \n" - "pop r25 \n" // restore r25 - "ret \n" + "pop r25 \n" // restore r25 + "ret \n" ); } @@ -308,11 +283,6 @@ namespace bootloader { UCSR1B = (1 << TXEN1) | (1 << RXEN1); gdb::init(); - // if (SPL == 0xfb) { // init called from main() via blgdb::init() - // struct gdb::Gdb *pgdb = GDB_PTR; - // pgdb->status.isAppStarted = 1; - // pgdb->status.isStopped = 0; - // } } uint8_t prepareAppStart () { @@ -474,10 +444,6 @@ namespace bootloader { asm volatile ( "__bootloader_printChar: \n" ); - // switch (uart) { - // case 0: putUart0Byte(c); break; - // case 1: putUart1Byte(c); break; - // } if (uart == 0) { putUart0Byte(c); } else { @@ -543,7 +509,6 @@ namespace bootloader { } void eepromWriteByte (uint8_t *p, uint8_t value) { - // eeprom_write_byte(p, value) asm volatile ( "mov r18, r22 \n" "sbic 0x1f, 1 \n" diff --git a/software/gdb-stub/src/gdb.cpp b/software/gdb-stub/src/gdb.cpp index 64b1e13..da0ecf4 100644 --- a/software/gdb-stub/src/gdb.cpp +++ b/software/gdb-stub/src/gdb.cpp @@ -47,6 +47,8 @@ namespace gdb { // uint16_t cnt = 0; void init () { + struct gdb::Gdb *pgdb = GDB_PTR; + pgdb->status.flashPage = -1; } void main () { diff --git a/software/gdb-stub/src/gdb.h b/software/gdb-stub/src/gdb.h index 0a13e41..dc30bc6 100644 --- a/software/gdb-stub/src/gdb.h +++ b/software/gdb-stub/src/gdb.h @@ -15,9 +15,9 @@ #endif -#define GDB_PTR (gdb::Gdb *)(RAMEND - sizeof(gdb::Gdb) + 1) -// #define GDB_BREAKPOINT_PTR (struct gdb::Breakpoint *)(RAMEND - 2 - sizeof(gdb::Control) - sizeof(gdb::Status) - sizeof(gdb::Breakpoint)) -#define GDB_BREAKPOINT_PTR (struct gdb::Breakpoint *)(RAMEND - 4 - sizeof(gdb::Breakpoint)) +#define GDB_PTR ((gdb::Gdb *)(RAMEND - sizeof(gdb::Gdb) + 1)) +#define GDB_BREAKPOINT_PTR &((GDB_PTR)->breakpoint) +// #define GDB_BREAKPOINT_PTR (struct gdb::Breakpoint *)(RAMEND - 2 - sizeof(gdb::Control) - sizeof(gdb::Status) - sizeof(gdb::Breakpoint) + 1) // #define GDB_BREAKPOINT_PTR (struct gdb::Breakpoint *)(RAMEND - 6 - sizeof(gdb::Breakpoint)) namespace gdb { @@ -27,28 +27,28 @@ namespace gdb { enum BufferState { idle = 0, data, esc, chk1, chk2, chk2err, exec, execerr, send, waitack }; - struct Status { // (gdb) print *((struct gdb::Status *)0x8010f9) + struct Status { // (gdb) print ((gdb::Gdb *)0x801039)->status uint8_t errorFlags; // @0x10f9 - // int16_t flashPage; // @0x10fa - uint8_t isConnected:1; // @0x10fc.0x01, address used in bootloader::jmpTableGdbStopApplication() - uint8_t isAppStarted:1; // @0x10fc.0x02 - uint8_t isStopped:1; // @0x10fc.0x04 - uint8_t isBreakpointValid:1; // @0x10fc.0x08 - uint8_t isSendingNotification:1; // @0x10fc.0x10 + int16_t flashPage; // @0x10fa + uint8_t isConnected:1; // @0x10fc Bit 0, address used in bootloader::jmpTableGdbStopApplication() + uint8_t isAppStarted:1; // @0x10fc Bit 1 + uint8_t isStopped:1; // @0x10fc Bit 2 + uint8_t isBreakpointValid:1; // @0x10fc Bit 3 + uint8_t isSendingNotification:1; // @0x10fc Bit 4 }; - struct Control { // (gdb) print *((struct gdb::Control *)0x8010fd) - uint8_t clearErrors:1; // @0x10fd.0x01 - uint8_t interrupt:1; // @0x10fd.0x02 - uint8_t stop:1; // @0x10fd.0x04 - uint8_t proceed:1; // @0x10fd.0x08 - uint8_t kill:1; // @0x10fd.0x10 - uint8_t start:1; // @0x10fd.0x20 - uint8_t reset:1; // @0x10fd.0x40 - uint8_t notify:1; // @0x10fd.0x80 + struct Control { // (gdb) print ((gdb::Gdb *)0x801039)->ctrl + uint8_t clearErrors:1; // Bit 0 + uint8_t interrupt:1; // Bit 1 + uint8_t stop:1; // Bit 2 + uint8_t proceed:1; // Bit 3 + uint8_t kill:1; // Bit 4 + uint8_t start:1; // Bit 5 + uint8_t reset:1; // Bit 6 + uint8_t notify:1; // Bit 7 }; - struct Buffer { + struct Buffer { // (gdb) print ((gdb::Gdb *)0x801039)->buffer enum BufferState state; uint8_t rpos; uint8_t chkSumFromGdb; @@ -56,14 +56,14 @@ namespace gdb { char buffer[BUFFER_SIZE]; }; - struct Breakpoint { + struct Breakpoint { // (gdb) print ((gdb::Gdb *)0x801039)->breakpoint uint8_t regs[32]; uint16_t sp; uint16_t pc; uint8_t sfr; }; - struct Gdb { // (gdb) set print pretty (gdb) print *((gdb::Gdb *)0x80103b) + struct Gdb { // (gdb) set print pretty (gdb) print *((gdb::Gdb *)0x801039) uint8_t timer; struct Buffer buffer; struct Breakpoint breakpoint; @@ -73,8 +73,7 @@ namespace gdb { uint8_t magic; }; - // extern struct Gdb gdb; - + // -------------------------------------------------------------------------------------------------------- void init () ATT_OPTIMIZE_GDB ATT_SECTION_GDB; void main () ATT_OPTIMIZE_GDB ATT_SECTION_GDB; -- 2.39.5