Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

debug: debug_stream: Access debug slot directly using cavstool.py #9498

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions app/debug_stream_overlay.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Enable debug-stream protocol
CONFIG_SOF_DEBUG_STREAM_SLOT=y
# Add thread_info-client for debug stream
CONFIG_SOF_DEBUG_STREAM_THREAD_INFO=y
# Zephyr option for storing human readable thread names
CONFIG_THREAD_NAME=y

# Debug window slot configuration 1
# The CONFIG_SOF_TELEMETRY uses slot 2, but with performance and IO-performance
# it extends beyond slot 3.
CONFIG_MEMORY_WIN_2_SIZE=16384
CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS=n
CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS=n

# If we turn telemetry off all together, we can use slot 2. Slot 1 is used by mtrace
#CONFIG_SOF_DEBUG_STREAM_SLOT_NUMBER=2
#CONFIG_SOF_TELEMETRY=n
#CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS=n
#CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS=n

2 changes: 1 addition & 1 deletion src/debug/debug_stream/debug_stream_slot.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ static int debug_stream_slot_init(void)
size_t offset = hdr_size;
int i;

LOG_INF("%u sections of %u bytes, hdr %u, secton area %u\n",
LOG_INF("%u sections of %u bytes, hdr %u, section area %u\n",
CONFIG_MP_MAX_NUM_CPUS, section_size, hdr_size,
section_area_size);

Expand Down
75 changes: 70 additions & 5 deletions tools/debug_stream/debug_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import argparse
import ctypes
import time
import sys
import os

import logging

Expand All @@ -18,6 +20,7 @@
)

DEBUG_STREAM_PAYLOAD_MAGIC = 0x1ED15EED
DEBUG_SLOT_SIZE = 4096

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

Expand Down Expand Up @@ -225,7 +228,7 @@ def get_hdr(self, slot, pos):
slot[self.boffset + pos * WSIZE :], ctypes.POINTER(DebugStreamRecord)
).contents
if header.id > 100 or header.size_words >= self.buf_words:
logging.warning(
logging.info(
"Broken record id %u seqno %u size %u",
header.id,
header.seqno,
Expand Down Expand Up @@ -286,7 +289,7 @@ def catch_up(self, slot):
self.decode_past_records(slot, circ.w_ptr, circ.next_seqno)
self.prev_w_ptr = circ.w_ptr
self.prev_seqno = circ.next_seqno - 1
logging.info("seqno %u w_ptr %u", self.prev_seqno, self.prev_w_ptr)
logging.debug("seqno %u w_ptr %u", self.prev_seqno, self.prev_w_ptr)

def decode_past_records(self, slot, pos, seqno):
"""
Expand Down Expand Up @@ -373,7 +376,7 @@ class DebugStreamDecoder:
Class for decoding debug-stream slot contents
"""

file_size = 4096 # ADSP debug slot size
file_size = DEBUG_SLOT_SIZE
file = None
slot = None
descs = []
Expand All @@ -393,6 +396,12 @@ def update_slot(self):
self.file.seek(0)
self.slot = self.file.read(self.file_size)

def set_slot(self, buf):
"""
Update slot contents
"""
self.slot = buf

def get_descriptors(self):
"""
Read the core specific descriptors and initialize core
Expand All @@ -403,15 +412,26 @@ def get_descriptors(self):
return False
hdr = ctypes.cast(self.slot, ctypes.POINTER(DebugStreamSlotHdr))
if hdr.contents.hdr.magic != DEBUG_STREAM_PAYLOAD_MAGIC:
logging.warning("Debug Slot has bad magic 0x%08x", hdr.contents.hdr.magic)
logging.info("Debug Slot has bad magic 0x%08x", hdr.contents.hdr.magic)
return False
num_sections = hdr.contents.num_sections
if num_sections == len(self.descs):
return True
if num_sections > 32:
logging.info("Suspiciously many sections %u", num_sections)
return False
hsize = ctypes.sizeof(DebugStreamSlotHdr)
self.descs = (DebugStreamSectionDescriptor * num_sections).from_buffer_copy(
self.slot, hsize
)
for i in range(len(self.descs)):
if (self.descs[i].core_id > 32 or
self.descs[i].buf_words > DEBUG_SLOT_SIZE // WSIZE or
self.descs[i].offset > DEBUG_SLOT_SIZE):
logging.info("Suspicious descriptor %u values %u %u %u", i,
self.descs[i].core_id, self.descs[i].buf_words,
self.descs[i].offset)
return False
self.circdec = [
CircularBufferDecoder(self.descs[i], i, self.rec_printer)
for i in range(len(self.descs))
Expand Down Expand Up @@ -473,6 +493,41 @@ def reset(self):
self.file = None
self.slot = None

def cavstool_main_loop(my_args):
import cavstool
try:
(hda, sd, dsp, hda_ostream_id) = cavstool.map_regs(True)
except Exception as e:
logging.error("Could not map device in sysfs; run as root?")
logging.error(e)
sys.exit(1)
ADSP_DW_SLOT_DEBUG_STREAM = 0x53523134
decoder = DebugStreamDecoder()
while True:
if not cavstool.fw_is_alive(dsp):
cavstool.wait_fw_entered(dsp, timeout_s=None)
if my_args.direct_access_slot < 0:
offset = cavstool.debug_slot_offset_by_type(ADSP_DW_SLOT_DEBUG_STREAM)
if offset is None:
logging.error("Could not find debug_stream slot")
sys.exit(1)
logging.info("Got offset 0x%08x by type 0x%08x", offset,
ADSP_DW_SLOT_DEBUG_STREAM)
else:
offset = cavstool.debug_slot_offset(my_args.direct_access_slot)
buf = cavstool.win_read(offset, 0, DEBUG_SLOT_SIZE)
decoder.set_slot(buf)
if not decoder.get_descriptors():
time.sleep(my_args.update_interval)
continue
decoder.catch_up_all()
while True:
if decoder.poll():
time.sleep(my_args.update_interval)
buf = cavstool.win_read(offset, 0, DEBUG_SLOT_SIZE)
decoder.set_slot(buf)
if not decoder.check_slot():
break

def main_f(my_args):
"""
Expand All @@ -483,6 +538,8 @@ def main_f(my_args):
about the host CPU load. That is why there where no synchronous mechanism
done and the host simply polls for new records.
"""
if my_args.direct_access_slot >= 0 or not os.path.isfile(my_args.debugstream_file):
return cavstool_main_loop(my_args)
decoder = DebugStreamDecoder()
prev_error = None
while True:
Expand All @@ -491,7 +548,8 @@ def main_f(my_args):
decoder.set_file(file)
decoder.update_slot()
if not decoder.get_descriptors():
break
time.sleep(my_args.update_interval)
continue
decoder.catch_up_all()
while True:
if decoder.poll():
Expand Down Expand Up @@ -527,6 +585,13 @@ def parse_params():
help="File to read the DebugStream data from, default /sys/kernel/debug/sof/debug_stream",
default="/sys/kernel/debug/sof/debug_stream",
)
parser.add_argument(
"-c",
"--direct-access-slot",
help="Access specified debug window slot directly, no need for debugfs file",
type=int,
default=-1,
)
parsed_args = parser.parse_args()
return parsed_args

Expand Down
Loading