Skip to content

Commit 558ddfb

Browse files
author
Jyri Sarha
committed
debug: debug_stream: Access debug slot directly using cavstool.py
Access debug slot directly using cavstool.py, by specifying the debug slot number where the debug_stream data is transferred. Adds one command line parameter for selecting the debug slot directly and adds an alternative mainloop for polling the slot through cavstool.py direct access. The commit also adds quite a few data consistency checks and error handling improvements as with the direct memory access its much more likely to get inconsistent data when the DSP is booting up, and code needs to be robust enough not to crash in such a situation. Also the logging messages about those checks failing has been lowered so that they are not too noisy. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
1 parent 88cde10 commit 558ddfb

1 file changed

Lines changed: 63 additions & 4 deletions

File tree

tools/debug_stream/debug_stream.py

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
)
1919

2020
DEBUG_STREAM_PAYLOAD_MAGIC = 0x1ED15EED
21+
DEBUG_SLOT_SIZE = 4096
2122

2223
# TODO: python construct would probably be cleaner than ctypes structs
2324

@@ -286,7 +287,7 @@ def catch_up(self, slot):
286287
self.decode_past_records(slot, circ.w_ptr, circ.next_seqno)
287288
self.prev_w_ptr = circ.w_ptr
288289
self.prev_seqno = circ.next_seqno - 1
289-
logging.info("seqno %u w_ptr %u", self.prev_seqno, self.prev_w_ptr)
290+
logging.debug("seqno %u w_ptr %u", self.prev_seqno, self.prev_w_ptr)
290291

291292
def decode_past_records(self, slot, pos, seqno):
292293
"""
@@ -373,7 +374,7 @@ class DebugStreamDecoder:
373374
Class for decoding debug-stream slot contents
374375
"""
375376

376-
file_size = 4096 # ADSP debug slot size
377+
file_size = DEBUG_SLOT_SIZE
377378
file = None
378379
slot = None
379380
descs = []
@@ -393,6 +394,12 @@ def update_slot(self):
393394
self.file.seek(0)
394395
self.slot = self.file.read(self.file_size)
395396

397+
def set_slot(self, buf):
398+
"""
399+
Update slot contents
400+
"""
401+
self.slot = buf
402+
396403
def get_descriptors(self):
397404
"""
398405
Read the core specific descriptors and initialize core
@@ -403,15 +410,26 @@ def get_descriptors(self):
403410
return False
404411
hdr = ctypes.cast(self.slot, ctypes.POINTER(DebugStreamSlotHdr))
405412
if hdr.contents.hdr.magic != DEBUG_STREAM_PAYLOAD_MAGIC:
406-
logging.warning("Debug Slot has bad magic 0x%08x", hdr.contents.hdr.magic)
413+
logging.info("Debug Slot has bad magic 0x%08x", hdr.contents.hdr.magic)
407414
return False
408415
num_sections = hdr.contents.num_sections
409416
if num_sections == len(self.descs):
410417
return True
418+
if num_sections > 32:
419+
logging.info("Suspiciously many sections %u", num_sections)
420+
return False
411421
hsize = ctypes.sizeof(DebugStreamSlotHdr)
412422
self.descs = (DebugStreamSectionDescriptor * num_sections).from_buffer_copy(
413423
self.slot, hsize
414424
)
425+
for i in range(len(self.descs)):
426+
if (self.descs[i].core_id > 32 or
427+
self.descs[i].buf_words > DEBUG_SLOT_SIZE // WSIZE or
428+
self.descs[i].offset > DEBUG_SLOT_SIZE):
429+
logging.info("Suspicious descriptor %u values %u %u %u", i,
430+
self.descs[i].core_id, self.descs[i].buf_words,
431+
self.descs[i].offest)
432+
return False
415433
self.circdec = [
416434
CircularBufferDecoder(self.descs[i], i, self.rec_printer)
417435
for i in range(len(self.descs))
@@ -473,6 +491,37 @@ def reset(self):
473491
self.file = None
474492
self.slot = None
475493

494+
def cavstool_main_loop(my_args):
495+
import cavstool
496+
try:
497+
(hda, sd, dsp, hda_ostream_id) = cavstool.map_regs(True)
498+
except Exception as e:
499+
logging.error("Could not map device in sysfs; run as root?")
500+
logging.error(e)
501+
sys.exit(1)
502+
503+
decoder = DebugStreamDecoder()
504+
while True:
505+
if not cavstool.fw_is_alive(dsp):
506+
cavstool.wait_fw_entered(dsp, timeout_s=None)
507+
try:
508+
offset = cavstool.debug_slot_offset(my_args.direct_access_slot);
509+
buf = cavstool.win_read(offset, 0, DEBUG_SLOT_SIZE)
510+
decoder.set_slot(buf)
511+
if not decoder.get_descriptors():
512+
time.sleep(my_args.update_interval)
513+
continue
514+
decoder.catch_up_all()
515+
while True:
516+
if decoder.poll():
517+
time.sleep(my_args.update_interval)
518+
buf = cavstool.win_read(offset, 0, DEBUG_SLOT_SIZE)
519+
decoder.set_slot(buf)
520+
if not decoder.check_slot():
521+
break
522+
except Exception as e:
523+
logging.error("%s failure: %s", type(e), e.args)
524+
continue
476525

477526
def main_f(my_args):
478527
"""
@@ -483,6 +532,8 @@ def main_f(my_args):
483532
about the host CPU load. That is why there where no synchronous mechanism
484533
done and the host simply polls for new records.
485534
"""
535+
if my_args.direct_access_slot >= 0:
536+
return cavstool_main_loop(my_args)
486537
decoder = DebugStreamDecoder()
487538
prev_error = None
488539
while True:
@@ -491,7 +542,8 @@ def main_f(my_args):
491542
decoder.set_file(file)
492543
decoder.update_slot()
493544
if not decoder.get_descriptors():
494-
break
545+
time.sleep(my_args.update_interval)
546+
continue
495547
decoder.catch_up_all()
496548
while True:
497549
if decoder.poll():
@@ -527,6 +579,13 @@ def parse_params():
527579
help="File to read the DebugStream data from, default /sys/kernel/debug/sof/debug_stream",
528580
default="/sys/kernel/debug/sof/debug_stream",
529581
)
582+
parser.add_argument(
583+
"-c",
584+
"--direct-access-slot",
585+
help="Access specified debug window slot directly, no need for debugfs file",
586+
type=int,
587+
default=-1,
588+
)
530589
parsed_args = parser.parse_args()
531590
return parsed_args
532591

0 commit comments

Comments
 (0)