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"