diff options
Diffstat (limited to 'kapi')
| -rw-r--r-- | kapi/gdb/__init__.py | 9 | ||||
| -rw-r--r-- | kapi/gdb/devices/__init__.py | 1 | ||||
| -rw-r--r-- | kapi/gdb/devices/resource.py | 63 | ||||
| -rw-r--r-- | kapi/gdb/filesystem/__init__.py | 2 | ||||
| -rw-r--r-- | kapi/gdb/filesystem/device_number.py | 23 |
5 files changed, 98 insertions, 0 deletions
diff --git a/kapi/gdb/__init__.py b/kapi/gdb/__init__.py index 1b367535..c48db922 100644 --- a/kapi/gdb/__init__.py +++ b/kapi/gdb/__init__.py @@ -2,6 +2,7 @@ import gdb.printing from .boot_modules import * from .devices import * +from .filesystem import * from .memory import * @@ -19,6 +20,9 @@ def build_pretty_printers(): "kapi_devices_device", "^kapi::devices::device$", KapiDevicesDevicePrinter ) pp.add_printer( + "kapi_devices_resource", "^kapi::devices::resource$", KapiDevicesResourcePrinter + ) + pp.add_printer( "kapi_boot_modules_boot_module", "^kapi::boot_modules::boot_module$", KapiBootModulesBootModulePrinter, @@ -28,6 +32,11 @@ def build_pretty_printers(): "^kapi::boot_modules::boot_module_registry$", KapiBootModulesBootModuleRegistryPrinter, ) + pp.add_printer( + "kapi_filesystem_device_number", + "^kapi::filesystem::device_number$", + KapiFilesystemDeviceNumberPrinter, + ) return pp diff --git a/kapi/gdb/devices/__init__.py b/kapi/gdb/devices/__init__.py index 3bab1ea6..c01db236 100644 --- a/kapi/gdb/devices/__init__.py +++ b/kapi/gdb/devices/__init__.py @@ -1 +1,2 @@ +from .resource import KapiDevicesResourcePrinter from .device import KapiDevicesDevicePrinter 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 + diff --git a/kapi/gdb/filesystem/__init__.py b/kapi/gdb/filesystem/__init__.py new file mode 100644 index 00000000..a60554c0 --- /dev/null +++ b/kapi/gdb/filesystem/__init__.py @@ -0,0 +1,2 @@ +from .device_number import KapiFilesystemDeviceNumberPrinter + diff --git a/kapi/gdb/filesystem/device_number.py b/kapi/gdb/filesystem/device_number.py new file mode 100644 index 00000000..e215dd3a --- /dev/null +++ b/kapi/gdb/filesystem/device_number.py @@ -0,0 +1,23 @@ +import gdb + + +class KapiFilesystemDeviceNumberPrinter(gdb.ValuePrinter): + + def __init__(self, val): + self.__val = val + + def to_string(self): + try: + major = int(self.__val["major"]) + minor = int(self.__val["minor"]) + return f"{major}:{minor}" + except (gdb.error, AttributeError): + return "<device_number ?>" + + def children(self): + yield ("major", self.__val["major"]) + yield ("minor", self.__val["minor"]) + + def display_hint(self): + return None + |
