amd-debug-tools 0.2.0__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of amd-debug-tools might be problematic. Click here for more details.

Files changed (53) hide show
  1. {amd_debug_tools-0.2.0/src/amd_debug_tools.egg-info → amd_debug_tools-0.2.2}/PKG-INFO +4 -3
  2. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/README.md +3 -2
  3. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/pyproject.toml +19 -1
  4. amd_debug_tools-0.2.2/setup.cfg +4 -0
  5. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/common.py +48 -0
  6. amd_debug_tools-0.2.2/src/amd_debug/display.py +34 -0
  7. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/failures.py +13 -1
  8. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/installer.py +69 -5
  9. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/prerequisites.py +157 -56
  10. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/s2idle.py +46 -17
  11. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/sleep_report.py +2 -2
  12. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/templates/md +0 -7
  13. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/validator.py +3 -5
  14. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2/src/amd_debug_tools.egg-info}/PKG-INFO +4 -3
  15. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug_tools.egg-info/SOURCES.txt +19 -17
  16. amd_debug_tools-0.2.2/src/amd_debug_tools.egg-info/top_level.txt +18 -0
  17. amd_debug_tools-0.2.2/src/launcher.py +35 -0
  18. {amd_debug_tools-0.2.0/test → amd_debug_tools-0.2.2/src}/test_acpi.py +0 -4
  19. {amd_debug_tools-0.2.0/test → amd_debug_tools-0.2.2/src}/test_batteries.py +0 -3
  20. {amd_debug_tools-0.2.0/test → amd_debug_tools-0.2.2/src}/test_bios.py +0 -4
  21. {amd_debug_tools-0.2.0/test → amd_debug_tools-0.2.2/src}/test_common.py +171 -3
  22. {amd_debug_tools-0.2.0/test → amd_debug_tools-0.2.2/src}/test_database.py +0 -6
  23. amd_debug_tools-0.2.2/src/test_display.py +143 -0
  24. {amd_debug_tools-0.2.0/test → amd_debug_tools-0.2.2/src}/test_failures.py +0 -3
  25. {amd_debug_tools-0.2.0/test → amd_debug_tools-0.2.2/src}/test_installer.py +103 -7
  26. {amd_debug_tools-0.2.0/test → amd_debug_tools-0.2.2/src}/test_kernel.py +0 -4
  27. amd_debug_tools-0.2.2/src/test_launcher.py +53 -0
  28. {amd_debug_tools-0.2.0/test → amd_debug_tools-0.2.2/src}/test_prerequisites.py +243 -34
  29. {amd_debug_tools-0.2.0/test → amd_debug_tools-0.2.2/src}/test_pstate.py +0 -5
  30. {amd_debug_tools-0.2.0/test → amd_debug_tools-0.2.2/src}/test_s2idle.py +69 -37
  31. {amd_debug_tools-0.2.0/test → amd_debug_tools-0.2.2/src}/test_sleep_report.py +0 -4
  32. {amd_debug_tools-0.2.0/test → amd_debug_tools-0.2.2/src}/test_validator.py +3 -9
  33. {amd_debug_tools-0.2.0/test → amd_debug_tools-0.2.2/src}/test_wake.py +0 -4
  34. amd_debug_tools-0.2.0/setup.cfg +0 -23
  35. amd_debug_tools-0.2.0/src/amd_debug_tools.egg-info/top_level.txt +0 -1
  36. amd_debug_tools-0.2.0/test/test_launcher.py +0 -96
  37. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/LICENSE +0 -0
  38. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/__init__.py +0 -0
  39. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/acpi.py +0 -0
  40. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/bash/amd-s2idle +0 -0
  41. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/battery.py +0 -0
  42. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/bios.py +0 -0
  43. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/database.py +0 -0
  44. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/kernel.py +0 -0
  45. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/pstate.py +0 -0
  46. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/s2idle-hook +0 -0
  47. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/templates/html +0 -0
  48. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/templates/stdout +0 -0
  49. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/templates/txt +0 -0
  50. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug/wake.py +0 -0
  51. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug_tools.egg-info/dependency_links.txt +0 -0
  52. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug_tools.egg-info/entry_points.txt +0 -0
  53. {amd_debug_tools-0.2.0 → amd_debug_tools-0.2.2}/src/amd_debug_tools.egg-info/requires.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amd-debug-tools
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: debug tools for AMD systems
5
5
  Author-email: Mario Limonciello <superm1@kernel.org>
6
6
  License-Expression: MIT
@@ -125,8 +125,9 @@ The following optional arguments are supported for this command:
125
125
  --format FORMAT Format of the report to produce (html, txt or md)
126
126
  --report-file File to write the report to
127
127
  --tool-debug Enable tool debug logging
128
- --report-debug Include debug messages in the report
129
-
128
+ --report-debug
129
+ --no-report-debug
130
+ Include debug messages in report (WARNING: can significantly increase report size)
130
131
  If the tool is launched with an environment that can call `xdg-open`, the report
131
132
  will be opened in a browser.
132
133
 
@@ -101,8 +101,9 @@ The following optional arguments are supported for this command:
101
101
  --format FORMAT Format of the report to produce (html, txt or md)
102
102
  --report-file File to write the report to
103
103
  --tool-debug Enable tool debug logging
104
- --report-debug Include debug messages in the report
105
-
104
+ --report-debug
105
+ --no-report-debug
106
+ Include debug messages in report (WARNING: can significantly increase report size)
106
107
  If the tool is launched with an environment that can call `xdg-open`, the report
107
108
  will be opened in a browser.
108
109
 
@@ -2,9 +2,22 @@
2
2
  requires = ["setuptools>=59.8.0", "setuptools-git-versioning>=2.0,<3"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
+ [tool.setuptools]
6
+ package-dir = {"" = "src"}
7
+
8
+ [tool.setuptools.package-data]
9
+ amd_debug = ["s2idle-hook"]
10
+ "amd_debug.templates" = ["*"]
11
+ "amd_debug.bash" = ["amd-s2idle"]
12
+
5
13
  [tool.setuptools-git-versioning]
6
14
  enabled = true
7
15
 
16
+ [tool.coverage.run]
17
+ branch = true
18
+ source = ["src"]
19
+ omit = ["src/launcher.py"]
20
+
8
21
  [project]
9
22
  name = "amd-debug-tools"
10
23
  authors = [{ name = "Mario Limonciello", email = "superm1@kernel.org" }]
@@ -27,8 +40,13 @@ dependencies = [
27
40
  "matplotlib",
28
41
  "seaborn",
29
42
  ]
30
- dynamic = ["version", "scripts"]
43
+ dynamic = ["version"]
31
44
  license = "MIT"
32
45
 
33
46
  [project.urls]
34
47
  "Homepage" = "https://web.git.kernel.org/pub/scm/linux/kernel/git/superm1/amd-debug-tools.git/"
48
+
49
+ [project.scripts]
50
+ amd-s2idle = "amd_debug:amd_s2idle"
51
+ amd-bios = "amd_debug:amd_bios"
52
+ amd-pstate = "amd_debug:amd_pstate"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -14,6 +14,7 @@ import struct
14
14
  import subprocess
15
15
  import re
16
16
  import sys
17
+ from ast import literal_eval
17
18
  from datetime import date, timedelta
18
19
 
19
20
 
@@ -81,6 +82,15 @@ def print_color(message, group) -> None:
81
82
  print(f"{prefix}{color}{message}{suffix}")
82
83
 
83
84
 
85
+ def colorize_choices(choices, default) -> str:
86
+ """Output a list of choices with colors, where the default is highlighted"""
87
+ if default not in choices:
88
+ raise ValueError(f"Default choice '{default}' not in choices")
89
+ choices = [c for c in choices if c != default]
90
+ choices = [f"{Colors.OK}{default}{Colors.ENDC}"] + choices
91
+ return ", ".join(choices)
92
+
93
+
84
94
  def fatal_error(message):
85
95
  """Prints a fatal error message and exits"""
86
96
  _configure_log(None)
@@ -88,6 +98,21 @@ def fatal_error(message):
88
98
  sys.exit(1)
89
99
 
90
100
 
101
+ def apply_prefix_wrapper(header, message):
102
+ """Apply a prefix to wrap a newline delimitted message"""
103
+ s = f"{header.strip()}\n"
104
+ lines = message.strip().split("\n")
105
+ for i, line in enumerate(lines):
106
+ line = line.strip()
107
+ if not line:
108
+ continue
109
+ if i == len(lines) - 1:
110
+ s += f"└─ {line}\n"
111
+ continue
112
+ s += f"│ {line}\n"
113
+ return s
114
+
115
+
91
116
  def show_log_info():
92
117
  """Show log information"""
93
118
  logger = logging.getLogger()
@@ -254,6 +279,19 @@ def get_property_pyudev(properties, key, fallback=""):
254
279
  return ""
255
280
 
256
281
 
282
+ def find_ip_version(base_path, kind, hw_ver) -> bool:
283
+ """Determine if an IP version is present on the system"""
284
+ b = os.path.join(base_path, "ip_discovery", "die", "0", kind, "0")
285
+ for key, expected_value in hw_ver.items():
286
+ p = os.path.join(b, key)
287
+ if not os.path.exists(p):
288
+ return False
289
+ v = int(read_file(p))
290
+ if v != expected_value:
291
+ return False
292
+ return True
293
+
294
+
257
295
  def read_msr(msr, cpu):
258
296
  """Read a Model-Specific Register (MSR) value from the CPU."""
259
297
  p = f"/dev/cpu/{cpu}/msr"
@@ -284,6 +322,16 @@ def running_ssh():
284
322
  return "SSH_CLIENT" in os.environ or "SSH_TTY" in os.environ
285
323
 
286
324
 
325
+ def convert_string_to_bool(str_value) -> bool:
326
+ """convert a string to a boolean value"""
327
+ try:
328
+ value = literal_eval(str_value)
329
+ except (SyntaxError, ValueError):
330
+ value = None
331
+ sys.exit(f"Invalid entry: {str_value}")
332
+ return bool(value)
333
+
334
+
287
335
  def _git_describe() -> str:
288
336
  """Get the git description of the current commit"""
289
337
  try:
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env python3
2
+ # SPDX-License-Identifier: MIT
3
+ """Display analysis"""
4
+ import os
5
+ from pyudev import Context
6
+
7
+ from amd_debug.common import read_file
8
+
9
+
10
+ class Display:
11
+ """Display analysis"""
12
+
13
+ def __init__(self):
14
+ self.pyudev = Context()
15
+ self.edid = {}
16
+
17
+ for dev in self.pyudev.list_devices(subsystem="drm"):
18
+ if not "card" in dev.device_path:
19
+ continue
20
+ p = os.path.join(dev.sys_path, "status")
21
+ if not os.path.exists(p):
22
+ continue
23
+ f = read_file(p)
24
+ if f != "connected":
25
+ continue
26
+ p = os.path.join(dev.sys_path, "enabled")
27
+ f = read_file(p)
28
+ if f != "enabled":
29
+ continue
30
+ self.edid[dev.sys_name] = os.path.join(dev.sys_path, "edid")
31
+
32
+ def get_edid(self) -> list:
33
+ """Get the path for EDID data for all connected displays"""
34
+ return self.edid
@@ -416,7 +416,7 @@ class LowHardwareSleepResidency(S0i3Failure):
416
416
  super().__init__()
417
417
  self.description = "System had low hardware sleep residency"
418
418
  self.explanation = (
419
- f"The system was asleep for {timedelta(seconds=duration)}, but only spent {percent:.2%} "
419
+ f"The system was asleep for {timedelta(seconds=duration)}, but only spent {percent/100:.2%} "
420
420
  "of this time in a hardware sleep state. In sleep cycles that are at least "
421
421
  "60 seconds long it's expected you spend above 90 percent of the cycle in "
422
422
  "hardware sleep."
@@ -586,3 +586,15 @@ class RogAllyMcuPowerSave(S0i3Failure):
586
586
  "The MCU powersave feature is disabled which will cause problems "
587
587
  "with the controller after suspend/resume."
588
588
  )
589
+
590
+
591
+ class DmcubTooOld(S0i3Failure):
592
+ """DMCUB microcode is too old"""
593
+
594
+ def __init__(self, current, expected):
595
+ super().__init__()
596
+ self.description = "DMCUB microcode is too old"
597
+ self.explanation = (
598
+ f"The DMCUB microcode version {hex(current)} is older than the"
599
+ f"minimum suggested version {hex(expected)}."
600
+ )
@@ -1,6 +1,10 @@
1
1
  #!/usr/bin/python3
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
+ """
5
+ This module contains installer support for amd-debug-tools.
6
+ """
7
+
4
8
  import argparse
5
9
  import os
6
10
  import shutil
@@ -21,6 +25,8 @@ class Headers: # pylint: disable=too-few-public-methods
21
25
  """Headers for the script"""
22
26
 
23
27
  MissingIasl = "ACPI extraction tool `iasl` is missing"
28
+ MissingEdidDecode = "EDID decoding tool `edid-decode` is missing"
29
+ MissingDiEdidDecode = "EDID decoding tool `di-edid-decode` is missing"
24
30
  MissingEthtool = "Ethtool is missing"
25
31
  InstallAction = "Attempting to install"
26
32
  MissingFwupd = "Firmware update library `fwupd` is missing"
@@ -30,6 +36,7 @@ class Headers: # pylint: disable=too-few-public-methods
30
36
  MissingTabulate = "Data library `tabulate` is missing"
31
37
  MissingJinja2 = "Template library `jinja2` is missing"
32
38
  MissingSeaborn = "Data visualization library `seaborn` is missing"
39
+ UnknownDistro = "No distro installation support available, install manually"
33
40
 
34
41
 
35
42
  class DistroPackage:
@@ -66,7 +73,8 @@ class DistroPackage:
66
73
  return False
67
74
  installer = ["pacman", "-Sy", self.arch]
68
75
  else:
69
- return False
76
+ print_color(Headers.UnknownDistro, "👀")
77
+ return True
70
78
 
71
79
  try:
72
80
  subprocess.check_call(installer)
@@ -171,6 +179,30 @@ class EthtoolPackage(DistroPackage):
171
179
  )
172
180
 
173
181
 
182
+ class EdidDecodePackage(DistroPackage):
183
+ """Edid-Decode package"""
184
+
185
+ def __init__(self):
186
+ super().__init__(
187
+ deb="edid-decode",
188
+ rpm="edid-decode",
189
+ arch=None,
190
+ message=Headers.MissingEdidDecode,
191
+ )
192
+
193
+
194
+ class DisplayInfoPackage(DistroPackage):
195
+ """display info package"""
196
+
197
+ def __init__(self):
198
+ super().__init__(
199
+ deb="libdisplay-info-bin",
200
+ rpm="libdisplay-info",
201
+ arch="libdisplay-info",
202
+ message=Headers.MissingDiEdidDecode,
203
+ )
204
+
205
+
174
206
  class FwupdPackage(DistroPackage):
175
207
  """Fwupd package"""
176
208
 
@@ -202,14 +234,14 @@ class Installer(AmdTool):
202
234
  # test if fwupd can report device firmware versions
203
235
  try:
204
236
  import gi # pylint: disable=import-outside-toplevel
205
- from gi.repository import (
237
+ from gi.repository import ( # pylint: disable=import-outside-toplevel
206
238
  GLib as _,
207
- ) # pylint: disable=import-outside-toplevel
239
+ )
208
240
 
209
241
  gi.require_version("Fwupd", "2.0")
210
- from gi.repository import (
242
+ from gi.repository import ( # pylint: disable=import-outside-toplevel
211
243
  Fwupd as _,
212
- ) # pylint: disable=import-outside-toplevel
244
+ )
213
245
 
214
246
  self.fwupd = True
215
247
  except ImportError:
@@ -244,6 +276,37 @@ class Installer(AmdTool):
244
276
  package = EthtoolPackage()
245
277
  if not package.install():
246
278
  return False
279
+ # can be satisified by either edid-decode or di-edid-decode
280
+ if "edid-decode" in self.requirements:
281
+ try:
282
+ di_edid = (
283
+ subprocess.call(
284
+ ["di-edid-decode", "--help"],
285
+ stdout=subprocess.DEVNULL,
286
+ stderr=subprocess.DEVNULL,
287
+ )
288
+ == 255
289
+ )
290
+ except FileNotFoundError:
291
+ di_edid = False
292
+ try:
293
+ edid = (
294
+ subprocess.call(
295
+ ["edid-decode", "--help"], stdout=subprocess.DEVNULL
296
+ )
297
+ == 255
298
+ )
299
+ except FileNotFoundError:
300
+ edid = False
301
+ if not di_edid and not edid:
302
+ # try to install di-edid-decode first
303
+ package = DisplayInfoPackage()
304
+ if package.install():
305
+ return True
306
+ # fall back to edid-decode instead
307
+ package = EdidDecodePackage()
308
+ if not package.install():
309
+ return False
247
310
  if "fwupd" in self.requirements and not self.fwupd:
248
311
  package = FwupdPackage()
249
312
  if not package.install():
@@ -396,6 +459,7 @@ def install_dep_superset() -> bool:
396
459
  "pandas",
397
460
  "seaborn",
398
461
  "tabulate",
462
+ "edid-decode",
399
463
  )
400
464
  ret = tool.install_dependencies()
401
465
  if ret: