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"