An Example GDB Script¶
This example script demonstrates a lot of techniques: - Variable assignment, reading from memory, masking, maths, - Writing to memory: set {uint32_t}0x50000020 = $value
- Functions - Loops - etc...
define hexdump # arg0: the address # arg1: the data printf "0x%04x: 0x%02x 0x%02x 0x%02x 0x%02x\n", \ ( $arg0 & 0x0FFF ), \ ( ( $arg1 >> 0 ) & 0xFF ), \ ( ( $arg1 >> 8 ) & 0xFF ), \ ( ( $arg1 >> 16 ) & 0xFF ), \ ( ( $arg1 >> 24 ) & 0xFF ) end define dump_packet # reading from GRXSTSR will always return the top of the FIFO... it won't pop. # after reading from GRXSTSP, this will no longer show the packet's metadata, it will # show the first word in the FIFO, etc... not as documented #x/1xw 0x5000001c # reading from GRXSTSP will retrieve the next 32-bit word from the Rx FIFO, and pop it # this is initially the metadata... it looks like we could configure DMA to poke this # register to retrieve the full packet, but that's not how it's documented, and it's # not what others are doing either... so lets not do that? set $metadata = ( {uint32_t}0x50000020 ) set $m_frmnum = ( $metadata & 0x01e00000 ) >> 21 set $m_pktsts = ( $metadata & 0x001e0000 ) >> 17 set $m_dpid = ( $metadata & 0x00018000 ) >> 15 set $m_bcnt = ( $metadata & 0x00007ff0 ) >> 4 set $m_epnum = ( $metadata & 0x0000000f ) >> 0 printf "GRXSTS: Receive Status: %08x\n", $metadata printf "FRMNUM: Frame Number: %d\n", $m_frmnum printf "PKTSTS: Packet Status: %d\n", $m_pktsts printf "DPID: Data PID: %d\n", $m_dpid printf "BCNT: Byte Count: %d\n", $m_bcnt printf "EPNUM: Endpoint Number: %d\n", $m_epnum # setup to read n bytes from the beginning of the FIFO # similarly to GRXSTSP, it looks like we can repeatedly read from the FIFO base address # and retrieve the entire packet... but that's not how it's documented, etc... set $len = $m_bcnt set $read_addr = 0x50001000 printf "Packet length: %d\n", $len # BUT... funny story. If you try to read the metadata AND payload through GRXSTSP or # the FIFO register(s), then you'll get 'junk' in GRXSTS after the last packet has been # read, and the Rx FIFO will continue to be marked as non-empty in GINTSTS. #yay # read all the data... the last read may be short (i.e: if $len % 4 != 0) while ($len > 0) # you must be 32-bit / word-wise reads from the FIFO, because the FIFO will shift # on each read to the register set $data = ( {uint32_t}$read_addr ) hexdump $read_addr $data set $read_addr = $read_addr + 4 set $len = $len - 4 end end # reading from GINTSTS will show us if the Rx FIFO is non-empty (bit 4) set $more = ({uint32_t}0x50000014) & 0x00000010 printf "\nData? " while ($more) printf "Yes!\n\n" printf "--- Start Packet ---\n" dump_packet printf "--- End packet ---\n" # reading from GINTSTS will show us if the Rx FIFO is non-empty (bit 4) set $more = ({uint32_t}0x50000014) & 0x00000010 printf "\nMore? " end printf "No...\n"