import gdb # Map from the resource_type enum integer value to a readable name. # kapi::devices::resource_type is a plain enum struct with no backing store # other than int, so we match by integer. _RESOURCE_TYPES = { 0: "mmio", 1: "port", 2: "irq", 3: "dma", } class KapiDevicesResourcePrinter(gdb.ValuePrinter): def __init__(self, val): self.__val = val self.__type_int = int(val["type"]) self.__type_name = _RESOURCE_TYPES.get(self.__type_int, f"") def _active_member(self): union = self.__val["m_value"] t = self.__type_int if t == 0: return union["range"] if t == 1: return union["port"] if t == 2: return union["irq"] if t == 3: return union["channel"] return union def to_string(self): try: t = self.__type_int union = self.__val["m_value"] if t == 0: # mmio start = int(union["range"]["start"]["m_value"]) size = int(union["range"]["size"]["value"]) return f"mmio [{start:#x}, +{size:#x})" if t == 1: # port start = int(union["port"]["start"]) count = int(union["port"]["count"]) return f"port {start:#x}+{count}" if t == 2: # irq number = int(union["irq"]["number"]) return f"irq {number}" if t == 3: # dma number = int(union["channel"]["number"]) return f"dma channel {number}" except (gdb.error, AttributeError): pass return f"resource ({self.__type_name})" def children(self): yield ("type", self.__val["type"]) yield (self.__type_name, self._active_member()) def display_hint(self): return None