amd-debug-tools 0.2.2__tar.gz → 0.2.4__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.
Files changed (50) hide show
  1. {amd_debug_tools-0.2.2/src/amd_debug_tools.egg-info → amd_debug_tools-0.2.4}/PKG-INFO +1 -1
  2. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/__init__.py +1 -1
  3. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/bios.py +4 -2
  4. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/failures.py +1 -1
  5. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/installer.py +4 -2
  6. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/kernel.py +8 -0
  7. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/prerequisites.py +17 -27
  8. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/pstate.py +5 -3
  9. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/s2idle.py +33 -30
  10. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/sleep_report.py +128 -85
  11. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/templates/html +4 -2
  12. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/validator.py +21 -15
  13. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4/src/amd_debug_tools.egg-info}/PKG-INFO +1 -1
  14. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/launcher.py +0 -1
  15. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/test_bios.py +4 -4
  16. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/test_launcher.py +2 -1
  17. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/test_prerequisites.py +11 -19
  18. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/test_s2idle.py +41 -11
  19. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/test_sleep_report.py +29 -0
  20. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/test_validator.py +116 -7
  21. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/LICENSE +0 -0
  22. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/README.md +0 -0
  23. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/pyproject.toml +0 -0
  24. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/setup.cfg +0 -0
  25. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/acpi.py +0 -0
  26. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/bash/amd-s2idle +0 -0
  27. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/battery.py +0 -0
  28. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/common.py +0 -0
  29. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/database.py +0 -0
  30. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/display.py +0 -0
  31. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/s2idle-hook +0 -0
  32. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/templates/md +0 -0
  33. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/templates/stdout +0 -0
  34. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/templates/txt +0 -0
  35. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug/wake.py +0 -0
  36. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug_tools.egg-info/SOURCES.txt +0 -0
  37. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug_tools.egg-info/dependency_links.txt +0 -0
  38. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug_tools.egg-info/entry_points.txt +0 -0
  39. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug_tools.egg-info/requires.txt +0 -0
  40. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/amd_debug_tools.egg-info/top_level.txt +0 -0
  41. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/test_acpi.py +0 -0
  42. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/test_batteries.py +0 -0
  43. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/test_common.py +0 -0
  44. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/test_database.py +0 -0
  45. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/test_display.py +0 -0
  46. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/test_failures.py +0 -0
  47. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/test_installer.py +0 -0
  48. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/test_kernel.py +0 -0
  49. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/test_pstate.py +0 -0
  50. {amd_debug_tools-0.2.2 → amd_debug_tools-0.2.4}/src/test_wake.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amd-debug-tools
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: debug tools for AMD systems
5
5
  Author-email: Mario Limonciello <superm1@kernel.org>
6
6
  License-Expression: MIT
@@ -42,4 +42,4 @@ def launch_tool(tool_name):
42
42
  return tools[tool_name]()
43
43
  else:
44
44
  print(f"\033[91mUnknown exe: {tool_name}\033[0m")
45
- return False
45
+ return 1
@@ -122,7 +122,7 @@ def parse_args():
122
122
  return args
123
123
 
124
124
 
125
- def main():
125
+ def main() -> None|int:
126
126
  """Main function"""
127
127
  args = parse_args()
128
128
  ret = False
@@ -135,4 +135,6 @@ def main():
135
135
  elif args.command == "version":
136
136
  print(version())
137
137
  show_log_info()
138
- return ret
138
+ if ret is False:
139
+ return 1
140
+ return
@@ -142,7 +142,7 @@ class MissingDriver(S0i3Failure):
142
142
  self.description = f"{slot} driver is missing"
143
143
  self.explanation = (
144
144
  f"No driver has been bound to PCI device {slot} "
145
- "Without a driver, the hardware may be able to enter a low power. "
145
+ "Without a driver, the hardware may be able to enter a low power "
146
146
  "state, but there may be spurious wake up events."
147
147
  )
148
148
 
@@ -446,7 +446,7 @@ def parse_args():
446
446
  return parser.parse_args()
447
447
 
448
448
 
449
- def install_dep_superset() -> bool:
449
+ def install_dep_superset() -> None|int:
450
450
  """Install all python supserset dependencies"""
451
451
  args = parse_args()
452
452
  tool = Installer(tool_debug=args.tool_debug)
@@ -465,4 +465,6 @@ def install_dep_superset() -> bool:
465
465
  if ret:
466
466
  print_color("All dependencies installed", "✅")
467
467
  show_log_info()
468
- return ret
468
+ if ret is False:
469
+ return 1
470
+ return
@@ -19,6 +19,7 @@ def get_kernel_command_line() -> str:
19
19
  "apparmor",
20
20
  "audit",
21
21
  "auto",
22
+ "bluetooth.disable_ertm",
22
23
  "boot",
23
24
  "BOOT_IMAGE",
24
25
  "console",
@@ -29,6 +30,7 @@ def get_kernel_command_line() -> str:
29
30
  "earlycon",
30
31
  "earlyprintk",
31
32
  "ether",
33
+ "init",
32
34
  "initrd",
33
35
  "ip",
34
36
  "LANG",
@@ -47,7 +49,9 @@ def get_kernel_command_line() -> str:
47
49
  "nfs.nfs4_unique_id",
48
50
  "nfsroot",
49
51
  "noplymouth",
52
+ "nowatchdog",
50
53
  "ostree",
54
+ "preempt",
51
55
  "quiet",
52
56
  "rd.dm.uuid",
53
57
  "rd.luks.allow-discards",
@@ -66,12 +70,15 @@ def get_kernel_command_line() -> str:
66
70
  "ro",
67
71
  "root",
68
72
  "rootflags",
73
+ "rootfstype",
69
74
  "roothash",
70
75
  "rw",
71
76
  "security",
77
+ "selinux",
72
78
  "showopts",
73
79
  "splash",
74
80
  "swap",
81
+ "systemd.machine_id",
75
82
  "systemd.mask",
76
83
  "systemd.show_status",
77
84
  "systemd.unit",
@@ -82,6 +89,7 @@ def get_kernel_command_line() -> str:
82
89
  "verbose",
83
90
  "vt.handoff",
84
91
  "zfs",
92
+ "zswap.enabled",
85
93
  ]
86
94
  # remove anything that starts with something in filtered from cmdline
87
95
  return " ".join([x for x in cmdline.split() if not x.startswith(tuple(filtered))])
@@ -134,22 +134,19 @@ class PrerequisiteValidator(AmdTool):
134
134
  if len(edids) == 0:
135
135
  self.db.record_debug("No EDID data found")
136
136
  return True
137
-
138
137
  for name, p in edids.items():
139
138
  output = None
140
- for cmd in ["di-edid-decode", "edid-decode"]:
139
+ for tool in ["di-edid-decode", "edid-decode"]:
141
140
  try:
142
- cmd = ["edid-decode", p]
141
+ cmd = [tool, p]
143
142
  output = subprocess.check_output(
144
143
  cmd, stderr=subprocess.DEVNULL
145
- ).decode("utf-8")
144
+ ).decode("utf-8", errors="ignore")
146
145
  break
147
146
  except FileNotFoundError:
148
147
  self.db.record_debug(f"{cmd} not installed")
149
148
  except subprocess.CalledProcessError as e:
150
- self.db.record_debug(
151
- f"failed to capture edid with {cmd}: {e.output}"
152
- )
149
+ pass
153
150
  if not output:
154
151
  self.db.record_prereq("Failed to capture EDID table", "👀")
155
152
  else:
@@ -245,7 +242,6 @@ class PrerequisiteValidator(AmdTool):
245
242
  for dev in self.pyudev.list_devices(subsystem="pci", DRIVER="nvme"):
246
243
  # https://git.kernel.org/torvalds/c/e79a10652bbd3
247
244
  if minimum_kernel(6, 10):
248
- self.db.record_debug("New enough kernel to avoid NVME check")
249
245
  break
250
246
  pci_slot_name = dev.properties["PCI_SLOT_NAME"]
251
247
  vendor = dev.properties.get("ID_VENDOR_FROM_DATABASE", "")
@@ -319,7 +315,6 @@ class PrerequisiteValidator(AmdTool):
319
315
  # not needed to check in newer kernels
320
316
  # see https://github.com/torvalds/linux/commit/77f1972bdcf7513293e8bbe376b9fe837310ee9c
321
317
  if minimum_kernel(6, 10):
322
- self.db.record_debug("New enough kernel to avoid HSMP check")
323
318
  return True
324
319
  f = os.path.join("/", "boot", f"config-{platform.uname().release}")
325
320
  if os.path.exists(f):
@@ -527,7 +522,7 @@ class PrerequisiteValidator(AmdTool):
527
522
  f"{keys['sys_vendor']} {keys['product_name']} ({keys['product_family']})",
528
523
  "💻",
529
524
  )
530
- debug_str = "DMI data:\n"
525
+ debug_str = "DMI|value\n"
531
526
  for key, value in keys.items():
532
527
  if (
533
528
  "product_name" in key
@@ -535,7 +530,7 @@ class PrerequisiteValidator(AmdTool):
535
530
  or "product_family" in key
536
531
  ):
537
532
  continue
538
- debug_str += f"{key}: {value}\n"
533
+ debug_str += f"{key}| {value}\n"
539
534
  self.db.record_debug(debug_str)
540
535
  return True
541
536
 
@@ -600,6 +595,9 @@ class PrerequisiteValidator(AmdTool):
600
595
  with open(target, "rb") as r:
601
596
  r.seek(0x70)
602
597
  found = struct.unpack("<I", r.read(4))[0] & BIT(21)
598
+ except FileNotFoundError:
599
+ self.db.record_prereq("FADT check unavailable", "🚦")
600
+ return True
603
601
  except PermissionError:
604
602
  self.db.record_prereq("FADT check unavailable", "🚦")
605
603
  return True
@@ -916,7 +914,7 @@ class PrerequisiteValidator(AmdTool):
916
914
  devices = []
917
915
  for dev in self.pyudev.list_devices(subsystem="pci"):
918
916
  devices.append(dev)
919
- debug_str = "PCI devices\n"
917
+ debug_str = "PCI Slot | Vendor | Class | ID | ACPI path\n"
920
918
  for dev in devices:
921
919
  pci_id = dev.properties["PCI_ID"].lower()
922
920
  pci_slot_name = dev.properties["PCI_SLOT_NAME"]
@@ -939,15 +937,12 @@ class PrerequisiteValidator(AmdTool):
939
937
  p = os.path.join(dev.sys_path, "firmware_node", "path")
940
938
  if os.path.exists(p):
941
939
  acpi = read_file(p)
942
- debug_str += (
943
- f"{prefix}{pci_slot_name} : "
944
- f"{database_vendor} {database_class} [{pci_id}] : {acpi}\n"
945
- )
946
940
  else:
947
- debug_str += (
948
- f"{prefix}{pci_slot_name} : "
949
- f"{database_vendor} {database_class} [{pci_id}]\n"
950
- )
941
+ acpi = ""
942
+ debug_str += (
943
+ f"{prefix}{pci_slot_name} | "
944
+ f"{database_vendor} | {database_class} | {pci_id} | {acpi}\n"
945
+ )
951
946
  if debug_str:
952
947
  self.db.record_debug(debug_str)
953
948
 
@@ -964,12 +959,8 @@ class PrerequisiteValidator(AmdTool):
964
959
  if status == 0:
965
960
  continue
966
961
  devices.append(dev)
967
- debug_str = "ACPI name: ACPI path [driver]\n"
962
+ debug_str = "ACPI name | ACPI path | Kernel driver\n"
968
963
  for dev in devices:
969
- if dev == devices[-1]:
970
- prefix = "└─"
971
- else:
972
- prefix = "│ "
973
964
  p = os.path.join(dev.sys_path, "path")
974
965
  pth = read_file(p)
975
966
  p = os.path.join(dev.sys_path, "physical_node", "driver")
@@ -977,7 +968,7 @@ class PrerequisiteValidator(AmdTool):
977
968
  driver = os.path.basename(os.readlink(p))
978
969
  else:
979
970
  driver = None
980
- debug_str += f"{prefix}{dev.sys_name}: {pth} [{driver}]\n"
971
+ debug_str += f"{dev.sys_name} | {pth} | {driver}\n"
981
972
  if debug_str:
982
973
  self.db.record_debug(debug_str)
983
974
  return True
@@ -1157,7 +1148,6 @@ class PrerequisiteValidator(AmdTool):
1157
1148
  if not found_iommu:
1158
1149
  self.db.record_prereq("IOMMU disabled", "✅")
1159
1150
  return True
1160
- debug_str += "DMA protection:\n"
1161
1151
  p = os.path.join("/", "sys", "firmware", "acpi", "tables", "IVRS")
1162
1152
  with open(p, "rb") as f:
1163
1153
  data = f.read()
@@ -300,15 +300,17 @@ def parse_args():
300
300
  return parser.parse_args()
301
301
 
302
302
 
303
- def main():
303
+ def main() -> None|int:
304
304
  """Main function"""
305
305
  args = parse_args()
306
306
  ret = False
307
307
  if args.command == "version":
308
308
  print(version())
309
- return True
309
+ return
310
310
  elif args.command == "triage":
311
311
  triage = AmdPstateTriage(args.tool_debug)
312
312
  ret = triage.run()
313
313
  show_log_info()
314
- return ret
314
+ if ret is False:
315
+ return 1
316
+ return
@@ -120,7 +120,7 @@ def prompt_report_arguments(since, until, fname, fmt, report_debug) -> str:
120
120
  if report_debug is None:
121
121
  inp = (
122
122
  input(
123
- f"{Headers.ReportDebugDescription} ({colorize_choices(Defaults.boolean_choices, "true")})? "
123
+ f"{Headers.ReportDebugDescription} ({colorize_choices(Defaults.boolean_choices, 'true')})? "
124
124
  )
125
125
  .lower()
126
126
  .capitalize()
@@ -211,6 +211,14 @@ def run_test_cycle(
211
211
  print("Failed to install dependencies")
212
212
  return False
213
213
 
214
+ try:
215
+ duration, wait, count = prompt_test_arguments(duration, wait, count, rand)
216
+ since, until, fname, fmt, report_debug = prompt_report_arguments(
217
+ datetime.now().isoformat(), Defaults.until.isoformat(), fname, fmt, True
218
+ )
219
+ except KeyboardInterrupt:
220
+ sys.exit("\nTest cancelled")
221
+
214
222
  try:
215
223
  app = PrerequisiteValidator(debug)
216
224
  run = app.run()
@@ -221,37 +229,32 @@ def run_test_cycle(
221
229
 
222
230
  if run or force:
223
231
  app = SleepValidator(tool_debug=debug, bios_debug=bios_debug)
224
- try:
225
- duration, wait, count = prompt_test_arguments(duration, wait, count, rand)
226
- since, until, fname, fmt, report_debug = prompt_report_arguments(
227
- datetime.now().isoformat(), Defaults.until.isoformat(), fname, fmt, True
228
- )
229
- except KeyboardInterrupt:
230
- sys.exit("\nTest cancelled")
231
232
 
232
- app.run(
233
+ run = app.run(
233
234
  duration=duration,
234
235
  wait=wait,
235
236
  count=count,
236
237
  rand=rand,
237
238
  logind=logind,
238
239
  )
240
+ else:
241
+ since = None
242
+ until = None
243
+
244
+ app = SleepReport(
245
+ since=since,
246
+ until=until,
247
+ fname=fname,
248
+ fmt=fmt,
249
+ tool_debug=debug,
250
+ report_debug=report_debug,
251
+ )
252
+ app.run()
239
253
 
240
- app = SleepReport(
241
- since=since,
242
- until=until,
243
- fname=fname,
244
- fmt=fmt,
245
- tool_debug=debug,
246
- report_debug=report_debug,
247
- )
248
- app.run()
249
-
250
- # open report in browser if it's html
251
- display_report_file(fname, fmt)
254
+ # open report in browser if it's html
255
+ display_report_file(fname, fmt)
252
256
 
253
- return True
254
- return False
257
+ return True
255
258
 
256
259
 
257
260
  def install(debug) -> None:
@@ -308,10 +311,8 @@ def parse_args():
308
311
  test_cmd.add_argument(
309
312
  "--random",
310
313
  action="store_true",
311
- help=(
312
- "Run sleep cycles for random durations and wait, using the "
313
- "--duration and --wait arguments as an upper bound",
314
- ),
314
+ help="Run sleep cycles for random durations and wait, using the "
315
+ "--duration and --wait arguments as an upper bound",
315
316
  )
316
317
  test_cmd.add_argument(
317
318
  "--force",
@@ -393,7 +394,7 @@ def parse_args():
393
394
  return parser.parse_args()
394
395
 
395
396
 
396
- def main():
397
+ def main() -> None|int:
397
398
  """Main function"""
398
399
  args = parse_args()
399
400
  ret = False
@@ -428,8 +429,10 @@ def main():
428
429
  )
429
430
  elif args.action == "version":
430
431
  print(version())
431
- return True
432
+ return
432
433
  else:
433
434
  sys.exit("no action specified")
434
435
  show_log_info()
435
- return ret
436
+ if ret is False:
437
+ return 1
438
+ return