diff options
Diffstat (limited to 'gdb-helpers')
-rw-r--r-- | gdb-helpers/rp2040.py | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/gdb-helpers/rp2040.py b/gdb-helpers/rp2040.py new file mode 100644 index 0000000..30a936a --- /dev/null +++ b/gdb-helpers/rp2040.py @@ -0,0 +1,163 @@ +# gdb-helpers/rp2040.py - GDB helpers for the RP2040 CPU. +# +# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> +# SPDX-License-Identifier: AGPL-3.0-or-later + +import gdb + + +def read_mmreg(addr: int) -> int: + return int(gdb.parse_and_eval(f"*(uint32_t*)({addr})")) + + +def read_reg(name: str) -> int: + return int(gdb.selected_frame().read_register(name)) + + +def fmt32(x: int) -> str: + return "0b" + bin(x)[2:].rjust(32, "0") + + +def read_prio(addr: int) -> str: + prios: list[int] = 32 * [0] + for regnum in range(0, 8): + regval = read_mmreg(addr + (regnum * 4)) + prios[(regnum * 4) + 0] = (regval >> (0 + 6)) & 0b11 + prios[(regnum * 4) + 1] = (regval >> (8 + 6)) & 0b11 + prios[(regnum * 4) + 2] = (regval >> (16 + 6)) & 0b11 + prios[(regnum * 4) + 3] = (regval >> (24 + 6)) & 0b11 + return " " + "".join(str(p) for p in reversed(prios)) + + +nvic_names = [ + "TIMER_0", # 0 + "TIMER_1", # 1 + "TIMER_2", # 2 + "TIMER_3", # 3 + "PWM", # 4 + "USB", # 5 + "XIP", # 6 + "PIO0_0", # 7 + "PIO0_1", # 8 + "PIO1_0", # 9 + "PIO1_1", # 10 + "DMA_0", # 11 + "DMA_1", # 12 + "IO_BANK0", # 13 + "IO_QSPI", # 14 + "SIO_PROC0", # 15 + "SIO_PROC1", # 16 + "CLOCKS", # 17 + "SPI0", # 18 + "SPI1", # 19 + "UART0", # 20 + "UART1", # 21 + "ADC_FIFO", # 22 + "I2C0", # 23 + "I2C1", # 24 + "RTC", # 25 + "unused(26)", # 26 + "unused(27)", # 27 + "unused(28)", # 28 + "unused(29)", # 29 + "unused(30)", # 30 + "unused(31)", # 31 +] + +exception_names = [ + "none", # 0 + "reset", # 1 + "NMI", # 2 + "hard fault", # 3 + "reserved(4)", # 4 + "reserved(5)", # 5 + "reserved(6)", # 6 + "reserved(7)", # 7 + "reserved(8)", # 8 + "reserved(9)", # 9 + "reserved(10)", # 10 + "SVCall", # 11 + "reserved(12)", # 12 + "reserved(13)", # 13 + "PendSV", # 14 + "SysTick", # 15 + *[f"nvic_{nvic}" for nvic in nvic_names], +] +while len(exception_names) < 1 << 9: + exception_names += [f"unused({len(exception_names)})"] + + +class RP2040ShowInterrupts(gdb.Command): + """Show the RP2040's interrupt state.""" + + def __init__(self) -> None: + super(RP2040ShowInterrupts, self).__init__( + "rp2040-show-interrupts", gdb.COMMAND_USER + ) + + def invoke(self, arg: str, from_tty: bool) -> None: + base: int = 0xE0000000 + icsr = read_mmreg(base + 0xED04) + psr = read_reg("xPSR") + # ║├┤║├┤├┤║├┤║║├┤├──┤║║║├──┤ + # 10987654321098765432109876543210 (dec bitnum) + # 3 2 1 0 + # ║├┤║├┤├┤║├┤║║├┤├──┤║║║├──┤ + # fedcba9876543210fedcba9876543210 (hex bitnum) + # 1 0 + print( + f""" +ARM Cortex-M0+ memory-mapped registers: + + clocks╖ ┌SIO + SPI┐ ║ │╓QSPI + UART┐│ ║ │║╓bank0 ╓XIP + ADC╖ ││ ║ │║║┌DMA ║╓USB + I2C┐ ║ ││ ║ │║║│ ┌PIO║║╓PWM + RTC╖├┐║┌┤├┐║┌┤║║├┐├──┐║║║┌──┬timers +NVIC_ISER: {fmt32(read_mmreg(base+0xe100)) } Set-Enable +NVIC_ICER: {fmt32(read_mmreg(base+0xe180)) } Clear-Enable +NVIC_ISPR: {fmt32(read_mmreg(base+0xe200)) } Set-Pending +NVIC_ICPR: {fmt32(read_mmreg(base+0xe280)) } Clear-Pending + ║├┤║├┤├┤║├┤║║├┤├──┤║║║├──┤ +NVIC_IPR-: {read_prio(base+0xe400) } Priority (0=highest, 3=lowest) + + isr_pending╖ + isr_preempt╖║ + pend_st_clr╖ ║║ + pend_st_set╖║ ║║ + pend_sv_clr╖║║ ║║ ┌vect_pending + pend_sv_set╖║║║ ║║ | ┌vect_active + nmi_pend_set╖ ║║║║ ║║ ┌────┴──┐ ┌────┴──┐ +ICSR : {fmt32(icsr) } Control and State + └────┬──┘ └────┬──┘ + | └{icsr&0x1FF} ({exception_names[icsr&0x1FF]}) + └{(icsr>>11)&0x1FF} ({exception_names[(icsr>>11)&0x1FF]}) + + ╓endiannes (0=little, 1=big) + vect_key┐ ║ ╓sys_reset_req + ┌───────┴──────┐║ ║╓vect_clr_active +AIRCR : {fmt32(read_mmreg(base+0xed0c)) } Application Interrupt and Reset Control + + ╓sleep_deep + s_ev_on_pend╖ ║╓sleep_on_exit +SCR : {fmt32(read_mmreg(base+0xed10)) } System Control + +ARM Cortex-M0+ processor core registers: + + ╓pm (0=normal, 1=top priority) +PRIMASK : {fmt32(read_reg('primask')) } Priority Mask + + [C]arry╖╓o[V]erflow + [Z]ero╖║║ ╓[T]humb ╓require [a]lignment + [N]egative╖║║║ ║ exec ║ ┌interrupt + app╫╫╫╢ ╟───────┴──────╢┌────┴──┐ +xPSR : {fmt32(psr) } {{Application,Execution,Interrupt}} Program Status + └────┬──┘ + └{psr&0x1FF} ({exception_names[psr&0x1FF]}) + +""" + ) + + +RP2040ShowInterrupts() |