aboutsummaryrefslogtreecommitdiff
path: root/kapi/gdb/devices/resource.py
diff options
context:
space:
mode:
Diffstat (limited to 'kapi/gdb/devices/resource.py')
-rw-r--r--kapi/gdb/devices/resource.py63
1 files changed, 63 insertions, 0 deletions
diff --git a/kapi/gdb/devices/resource.py b/kapi/gdb/devices/resource.py
new file mode 100644
index 00000000..dd5fd320
--- /dev/null
+++ b/kapi/gdb/devices/resource.py
@@ -0,0 +1,63 @@
+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"<unknown:{self.__type_int}>")
+
+ 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
+