debug: coredump: add xtensa intel adsp, support toolchains
Adds compatibility with Intel ADSP GDB from Zephyr SDK and from Cadence toolchain to coredump_gdbserver.py. Adds CAVS 15-25 (APL) register definitions. Implements handle_register_single_read_packet to serve ADSP GDB p packets. Prevents BSA from changing between stack dump printout and coredump by taking lock. Observed to be necessary for accurate results on slower simulated platforms. Signed-off-by: Lauren Murphy <lauren.murphy@intel.com>
This commit is contained in:
parent
b034711f59
commit
318e6db239
8 changed files with 249 additions and 59 deletions
|
|
@ -9,12 +9,13 @@
|
|||
#include <xtensa-asm2.h>
|
||||
|
||||
#define ARCH_HDR_VER 1
|
||||
#define XTENSA_BLOCK_HDR_VER 1
|
||||
#define XTENSA_BLOCK_HDR_VER 2
|
||||
|
||||
enum xtensa_soc_code {
|
||||
XTENSA_SOC_UNKNOWN = 0,
|
||||
XTENSA_SOC_SAMPLE_CONTROLLER,
|
||||
XTENSA_SOC_ESP32,
|
||||
XTENSA_SOC_INTEL_ADSP,
|
||||
};
|
||||
|
||||
struct xtensa_arch_block {
|
||||
|
|
@ -28,14 +29,16 @@ struct xtensa_arch_block {
|
|||
*/
|
||||
uint8_t soc;
|
||||
|
||||
/* Future versions of Xtensa coredump
|
||||
* may expand minimum set of registers
|
||||
/* Future versions of Xtensa coredump may expand
|
||||
* minimum set of registers
|
||||
*
|
||||
* (This should stay the second field for the same
|
||||
* reason as the first once we have more versions)
|
||||
*/
|
||||
uint16_t version;
|
||||
|
||||
uint8_t toolchain;
|
||||
|
||||
struct {
|
||||
/* Minimum set shown by GDB 'info registers',
|
||||
* skipping user-defined register EXPSTATE
|
||||
|
|
@ -101,13 +104,18 @@ void arch_coredump_info_dump(const z_arch_esf_t *esf)
|
|||
|
||||
arch_blk.version = XTENSA_BLOCK_HDR_VER;
|
||||
|
||||
#if CONFIG_SOC_XTENSA_SAMPLE_CONTROLLER
|
||||
arch_blk.soc = XTENSA_SOC_SAMPLE_CONTROLLER;
|
||||
#elif CONFIG_SOC_ESP32
|
||||
arch_blk.soc = XTENSA_SOC_ESP32;
|
||||
#else
|
||||
arch_blk.soc = XTENSA_SOC_UNKNOWN;
|
||||
#endif
|
||||
#if CONFIG_SOC_XTENSA_SAMPLE_CONTROLLER
|
||||
arch_blk.soc = XTENSA_SOC_SAMPLE_CONTROLLER;
|
||||
#elif CONFIG_SOC_ESP32
|
||||
arch_blk.soc = XTENSA_SOC_ESP32;
|
||||
#elif CONFIG_SOC_FAMILY_INTEL_ADSP
|
||||
arch_blk.soc = XTENSA_SOC_INTEL_ADSP;
|
||||
#else
|
||||
arch_blk.soc = XTENSA_SOC_UNKNOWN;
|
||||
#endif
|
||||
|
||||
/* Set in top-level CMakeLists.txt for use with Xtensa coredump */
|
||||
arch_blk.toolchain = XTENSA_TOOLCHAIN_VARIANT;
|
||||
|
||||
__asm__ volatile("rsr.exccause %0" : "=r"(arch_blk.r.exccause));
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <xtensa_backtrace.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <zephyr/debug/coredump.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);
|
||||
|
||||
|
|
@ -97,7 +98,17 @@ char *z_xtensa_exccause(unsigned int cause_code)
|
|||
void z_xtensa_fatal_error(unsigned int reason, const z_arch_esf_t *esf)
|
||||
{
|
||||
if (esf) {
|
||||
/* Don't want to get elbowed by xtensa_switch
|
||||
* in between printing registers and dumping them;
|
||||
* corrupts backtrace
|
||||
*/
|
||||
unsigned int key = arch_irq_lock();
|
||||
|
||||
z_xtensa_dump_stack(esf);
|
||||
|
||||
coredump(reason, esf, IS_ENABLED(CONFIG_MULTITHREADING) ? k_current_get() : NULL);
|
||||
|
||||
arch_irq_unlock(key);
|
||||
}
|
||||
#if defined(CONFIG_XTENSA_ENABLE_BACKTRACE)
|
||||
#if XCHAL_HAVE_WINDOWED
|
||||
|
|
|
|||
|
|
@ -57,6 +57,11 @@ This usually involves the following steps:
|
|||
|
||||
4. Start the debugger corresponding to the target architecture.
|
||||
|
||||
.. note::
|
||||
Developers for Intel ADSP CAVS 15-25 platforms using
|
||||
``ZEPHYR_TOOLCHAIN_VARIANT=zephyr`` should use the debugger in the
|
||||
``xtensa-intel_apl_adsp`` toolchain of the SDK.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@
|
|||
#include <zephyr/logging/log_ctrl.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/fatal.h>
|
||||
#ifndef CONFIG_XTENSA
|
||||
#include <zephyr/debug/coredump.h>
|
||||
#endif
|
||||
|
||||
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);
|
||||
|
||||
|
|
@ -122,7 +124,9 @@ void z_fatal_error(unsigned int reason, const z_arch_esf_t *esf)
|
|||
LOG_ERR("Current thread: %p (%s)", thread,
|
||||
thread_name_get(thread));
|
||||
|
||||
#ifndef CONFIG_XTENSA
|
||||
coredump(reason, esf, thread);
|
||||
#endif
|
||||
|
||||
k_sys_fatal_error_handler(reason, esf);
|
||||
|
||||
|
|
|
|||
|
|
@ -7,29 +7,66 @@
|
|||
import binascii
|
||||
import logging
|
||||
import struct
|
||||
import sys
|
||||
|
||||
from enum import Enum
|
||||
from gdbstubs.gdbstub import GdbStub
|
||||
|
||||
logger = logging.getLogger("gdbstub")
|
||||
|
||||
# Matches same in coredump.c
|
||||
XTENSA_BLOCK_HDR_DUMMY_SOC = 255
|
||||
|
||||
class XtensaSoc():
|
||||
# Must match --soc arg options; see get_soc
|
||||
class XtensaSoc(Enum):
|
||||
UNKNOWN = 0
|
||||
SAMPLE_CONTROLLER = 1
|
||||
ESP32 = 2
|
||||
INTEL_ADSP_CAVS = 3
|
||||
|
||||
|
||||
def get_soc_definition(soc):
|
||||
# The previous version of this script didn't need to know
|
||||
# what toolchain Zephyr was built with; it assumed sample_controller
|
||||
# was built with the Zephyr SDK and ESP32 with Espressif's.
|
||||
# However, if a SOC can be built by two separate toolchains,
|
||||
# there is a chance that the GDBs provided by the toolchains will
|
||||
# assign different indices to the same registers. For example, the
|
||||
# Intel ADSP family of SOCs can be built with both Zephyr's
|
||||
# SDK and Cadence's XCC toolchain. With the same SOC APL,
|
||||
# the SDK's GDB assigns PC the index 0, while XCC's GDB assigns
|
||||
# it the index 32.
|
||||
#
|
||||
# (The Espressif value isn't really required, since ESP32 can
|
||||
# only be built with Espressif's toolchain, but it's included for
|
||||
# completeness.)
|
||||
class XtensaToolchain(Enum):
|
||||
UNKNOWN = 0
|
||||
ZEPHYR = 1
|
||||
XCC = 2
|
||||
ESPRESSIF = 3
|
||||
|
||||
|
||||
def get_gdb_reg_definition(soc, toolchain):
|
||||
if soc == XtensaSoc.SAMPLE_CONTROLLER:
|
||||
return XtensaSoc_SampleController
|
||||
return GdbRegDef_Sample_Controller
|
||||
elif soc == XtensaSoc.ESP32:
|
||||
return XtensaSoc_ESP32
|
||||
return GdbRegDef_ESP32
|
||||
elif soc == XtensaSoc.INTEL_ADSP_CAVS:
|
||||
if toolchain == XtensaToolchain.ZEPHYR:
|
||||
return GdbRegDef_Intel_Adsp_CAVS_Zephyr
|
||||
elif toolchain == XtensaToolchain.XCC:
|
||||
return GdbRegDef_Intel_Adsp_CAVS_XCC
|
||||
elif toolchain == XtensaToolchain.ESPRESSIF:
|
||||
logger.error("Can't use espressif toolchain with CAVS. " +
|
||||
"Use zephyr or xcc instead. Exiting...")
|
||||
sys.exit(1)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class ExceptionCodes():
|
||||
class ExceptionCodes(Enum):
|
||||
# Matches arch/xtensa/core/fatal.c->z_xtensa_exccause
|
||||
ILLEGAL_INSTRUCTION = 0
|
||||
# Syscall not fatal
|
||||
|
|
@ -54,6 +91,9 @@ class ExceptionCodes():
|
|||
LOAD_PROHIBITED = 28
|
||||
STORE_PROHIBITED = 29
|
||||
# Coprocessor disabled spans 32 - 39
|
||||
COPROCESSOR_DISABLED_START = 32
|
||||
COPROCESSOR_DISABLED_END = 39
|
||||
Z_EXCEPT_REASON = 63
|
||||
# Others (reserved / unknown) map to default signal
|
||||
|
||||
|
||||
|
|
@ -62,8 +102,8 @@ class GdbStub_Xtensa(GdbStub):
|
|||
GDB_SIGNAL_DEFAULT = 7
|
||||
|
||||
# Mapping based on section 4.4.1.5 of the
|
||||
# Xtensa ISA Reference Manual
|
||||
# (Table 4–64. Exception Causes)
|
||||
# Xtensa ISA Reference Manual (Table 4–64. Exception Causes)
|
||||
# Somewhat arbitrary; included only because GDB requests it
|
||||
GDB_SIGNAL_MAPPING = {
|
||||
ExceptionCodes.ILLEGAL_INSTRUCTION: 4,
|
||||
ExceptionCodes.INSTR_FETCH_ERROR: 7,
|
||||
|
|
@ -85,12 +125,14 @@ class GdbStub_Xtensa(GdbStub):
|
|||
ExceptionCodes.LOAD_STORE_PRIVILEGE: 11,
|
||||
ExceptionCodes.LOAD_PROHIBITED: 11,
|
||||
ExceptionCodes.STORE_PROHIBITED: 11,
|
||||
ExceptionCodes.Z_EXCEPT_REASON: 6,
|
||||
}
|
||||
|
||||
reg_fmt = "<I"
|
||||
|
||||
def __init__(self, logfile, elffile):
|
||||
super().__init__(logfile=logfile, elffile=elffile)
|
||||
|
||||
self.registers = None
|
||||
self.exception_code = None
|
||||
self.gdb_signal = self.GDB_SIGNAL_DEFAULT
|
||||
|
|
@ -102,48 +144,61 @@ class GdbStub_Xtensa(GdbStub):
|
|||
def parse_arch_data_block(self):
|
||||
arch_data_blk = self.logfile.get_arch_data()['data']
|
||||
|
||||
# Get SOC in order to get correct format for unpack
|
||||
self.soc = bytearray(arch_data_blk)[0]
|
||||
self.xtensaSoc = get_soc_definition(self.soc)
|
||||
tu = struct.unpack(self.xtensaSoc.ARCH_DATA_BLK_STRUCT, arch_data_blk)
|
||||
self.version = struct.unpack('H', arch_data_blk[1:3])[0]
|
||||
|
||||
# Get SOC and toolchain to get correct format for unpack
|
||||
self.soc = XtensaSoc(bytearray(arch_data_blk)[0])
|
||||
if self.version >= 2:
|
||||
self.toolchain = XtensaToolchain(bytearray(arch_data_blk)[3])
|
||||
arch_data_blk_regs = arch_data_blk[4:]
|
||||
else:
|
||||
# v1 only supported ESP32 and sample_controller, each of which
|
||||
# only build with one toolchain
|
||||
if self.soc == XtensaSoc.ESP32:
|
||||
self.toolchain = XtensaToolchain.ESPRESSIF
|
||||
else:
|
||||
self.toolchain = XtensaToolchain.ZEPHYR
|
||||
arch_data_blk_regs = arch_data_blk[3:]
|
||||
|
||||
self.gdb_reg_def = get_gdb_reg_definition(self.soc, self.toolchain)
|
||||
|
||||
tu = struct.unpack(self.gdb_reg_def.ARCH_DATA_BLK_STRUCT_REGS,
|
||||
arch_data_blk_regs)
|
||||
|
||||
self.registers = dict()
|
||||
|
||||
self.version = tu[1]
|
||||
|
||||
self.map_registers(tu)
|
||||
|
||||
|
||||
def map_registers(self, tu):
|
||||
i = 2
|
||||
for r in self.xtensaSoc.RegNum:
|
||||
regNum = r.value
|
||||
i = 0
|
||||
for r in self.gdb_reg_def.RegNum:
|
||||
reg_num = r.value
|
||||
# Dummy WINDOWBASE and WINDOWSTART to enable GDB
|
||||
# without dumping them and all AR registers;
|
||||
# avoids interfering with interrupts / exceptions
|
||||
if r == self.xtensaSoc.RegNum.WINDOWBASE:
|
||||
self.registers[regNum] = 0
|
||||
elif r == self.xtensaSoc.RegNum.WINDOWSTART:
|
||||
self.registers[regNum] = 1
|
||||
if r == self.gdb_reg_def.RegNum.WINDOWBASE:
|
||||
self.registers[reg_num] = 0
|
||||
elif r == self.gdb_reg_def.RegNum.WINDOWSTART:
|
||||
self.registers[reg_num] = 1
|
||||
else:
|
||||
if r == self.xtensaSoc.RegNum.EXCCAUSE:
|
||||
if r == self.gdb_reg_def.RegNum.EXCCAUSE:
|
||||
self.exception_code = tu[i]
|
||||
self.registers[regNum] = tu[i]
|
||||
self.registers[reg_num] = tu[i]
|
||||
i += 1
|
||||
|
||||
|
||||
def compute_signal(self):
|
||||
sig = self.GDB_SIGNAL_DEFAULT
|
||||
code = self.exception_code
|
||||
code = ExceptionCodes(self.exception_code)
|
||||
|
||||
if code is None:
|
||||
sig = self.GDB_SIGNAL_DEFAULT
|
||||
|
||||
# Map cause to GDB signal number
|
||||
if code in self.GDB_SIGNAL_MAPPING:
|
||||
sig = self.GDB_SIGNAL_MAPPING[code]
|
||||
# Coprocessor disabled code spans 32 - 39
|
||||
elif 32 <= code <= 39:
|
||||
elif ExceptionCodes.COPROCESSOR_DISABLED_START.value <= code <= \
|
||||
ExceptionCodes.COPROCESSOR_DISABLED_END.value:
|
||||
sig = 8
|
||||
|
||||
self.gdb_signal = sig
|
||||
|
|
@ -154,18 +209,16 @@ class GdbStub_Xtensa(GdbStub):
|
|||
pkt = b''
|
||||
|
||||
GDB_G_PKT_MAX_REG = \
|
||||
max([regNum.value for regNum in self.xtensaSoc.RegNum])
|
||||
max([reg_num.value for reg_num in self.gdb_reg_def.RegNum])
|
||||
|
||||
# We try to send as many of the registers listed
|
||||
# as possible, but we are constrained by the
|
||||
# maximum length of the g packet
|
||||
while idx <= GDB_G_PKT_MAX_REG and idx * 4 < self.xtensaSoc.SOC_GDB_GPKT_BIN_SIZE:
|
||||
while idx <= GDB_G_PKT_MAX_REG and idx * 4 < self.gdb_reg_def.SOC_GDB_GPKT_BIN_SIZE:
|
||||
if idx in self.registers:
|
||||
bval = struct.pack(self.reg_fmt, self.registers[idx])
|
||||
pkt += binascii.hexlify(bval)
|
||||
else:
|
||||
# Register not in coredump -> unknown value
|
||||
# Send in "xxxxxxxx"
|
||||
pkt += b'x' * 8
|
||||
|
||||
idx += 1
|
||||
|
|
@ -174,17 +227,20 @@ class GdbStub_Xtensa(GdbStub):
|
|||
|
||||
|
||||
def handle_register_single_read_packet(self, pkt):
|
||||
# Mark registers as "<unavailable>". 'p' packets are not sent for the registers
|
||||
# currently handled in this file so we can safely reply "xxxxxxxx" here.
|
||||
self.put_gdb_packet(b'x' * 8)
|
||||
# format is pXX, where XX is the hex representation of the idx
|
||||
regIdx = int('0x' + pkt[1:].decode('utf8'), 16)
|
||||
try:
|
||||
bval = struct.pack(self.reg_fmt, self.registers[regIdx])
|
||||
self.put_gdb_packet(binascii.hexlify(bval))
|
||||
except KeyError:
|
||||
self.put_gdb_packet(b'x' * 8)
|
||||
|
||||
# The following classes map registers to their index (idx) on
|
||||
# a specific SOC. Since SOCs can have different numbers of
|
||||
# registers (e.g. 32 VS 64 ar), the index of a register will
|
||||
# differ per SOC. See xtensa_config.c.
|
||||
|
||||
# The following classes map registers to their index used by
|
||||
# the GDB of a specific SOC and toolchain. See xtensa_config.c.
|
||||
|
||||
# WARNING: IF YOU CHANGE THE ORDER OF THE REGISTERS IN ONE
|
||||
# SOC's MAPPING, YOU MUST CHANGE THE ORDER TO MATCH IN THE OTHERS
|
||||
# MAPPING, YOU MUST CHANGE THE ORDER TO MATCH IN THE OTHERS
|
||||
# AND IN arch/xtensa/core/coredump.c's xtensa_arch_block.r.
|
||||
# See map_registers.
|
||||
|
||||
|
|
@ -192,15 +248,18 @@ class GdbStub_Xtensa(GdbStub):
|
|||
# values are dummied by this script, they have to be last in the
|
||||
# mapping below.
|
||||
|
||||
# sdk-ng -> overlays/xtensa_sample_controller/gdb/gdb/xtensa-config.c
|
||||
class XtensaSoc_SampleController:
|
||||
ARCH_DATA_BLK_STRUCT = '<BHIIIIIIIIIIIIIIIIIIIIII'
|
||||
|
||||
# This fits the maximum possible register index (110)
|
||||
# unlike on ESP32 GDB, there doesn't seem to be an
|
||||
# actual hard limit to how big the g packet can be
|
||||
# sample_controller is unique to Zephyr SDK
|
||||
# sdk-ng -> overlays/xtensa_sample_controller/gdb/gdb/xtensa-config.c
|
||||
class GdbRegDef_Sample_Controller:
|
||||
ARCH_DATA_BLK_STRUCT_REGS = '<IIIIIIIIIIIIIIIIIIIIII'
|
||||
|
||||
# This fits the maximum possible register index (110).
|
||||
# Unlike on ESP32 GDB, there doesn't seem to be an
|
||||
# actual hard limit to how big the g packet can be.
|
||||
SOC_GDB_GPKT_BIN_SIZE = 444
|
||||
|
||||
|
||||
class RegNum(Enum):
|
||||
PC = 0
|
||||
EXCCAUSE = 77
|
||||
|
|
@ -228,15 +287,17 @@ class XtensaSoc_SampleController:
|
|||
WINDOWBASE = 34
|
||||
WINDOWSTART = 35
|
||||
|
||||
|
||||
# ESP32 is unique to espressif toolchain
|
||||
# espressif xtensa-overlays -> xtensa_esp32/gdb/gdb/xtensa-config.c
|
||||
class XtensaSoc_ESP32:
|
||||
ARCH_DATA_BLK_STRUCT = '<BHIIIIIIIIIIIIIIIIIIIIIIIII'
|
||||
class GdbRegDef_ESP32:
|
||||
ARCH_DATA_BLK_STRUCT_REGS = '<IIIIIIIIIIIIIIIIIIIIIIIII'
|
||||
|
||||
# Maximum index register that can be sent in a group packet is
|
||||
# 104, which prevents us from sending An registers directly.
|
||||
# We get around this by assigning each An in the dump to ARn
|
||||
# and setting WINDOWBASE to 0 and WINDOWSTART to 1; ESP32 GDB
|
||||
# will recalculate the corresponding An
|
||||
# will recalculate the corresponding An.
|
||||
SOC_GDB_GPKT_BIN_SIZE = 420
|
||||
|
||||
class RegNum(Enum):
|
||||
|
|
@ -267,3 +328,85 @@ class XtensaSoc_ESP32:
|
|||
LCOUNT = 67
|
||||
WINDOWBASE = 69
|
||||
WINDOWSTART = 70
|
||||
|
||||
|
||||
# sdk-ng -> overlays/xtensa_intel_apl/gdb/gdb/xtensa-config.c
|
||||
class GdbRegDef_Intel_Adsp_CAVS_Zephyr:
|
||||
ARCH_DATA_BLK_STRUCT_REGS = '<IIIIIIIIIIIIIIIIIIIIIIIII'
|
||||
|
||||
# If you send all the registers below (up to index 173)
|
||||
# GDB incorrectly assigns 0 to EXCCAUSE / EXCVADDR... for some
|
||||
# reason. Since APL GDB sends p packets for every An register
|
||||
# even if it was sent in the g packet, I arbitrarily shrunk the
|
||||
# G packet to include up to A1, which fixed the issue.
|
||||
SOC_GDB_GPKT_BIN_SIZE = 640
|
||||
|
||||
|
||||
class RegNum(Enum):
|
||||
PC = 0
|
||||
EXCCAUSE = 148
|
||||
EXCVADDR = 154
|
||||
SAR = 68
|
||||
PS = 74
|
||||
SCOMPARE1 = 77
|
||||
A0 = 158
|
||||
A1 = 159
|
||||
A2 = 160
|
||||
A3 = 161
|
||||
A4 = 162
|
||||
A5 = 163
|
||||
A6 = 164
|
||||
A7 = 165
|
||||
A8 = 166
|
||||
A9 = 167
|
||||
A10 = 168
|
||||
A11 = 169
|
||||
A12 = 170
|
||||
A13 = 171
|
||||
A14 = 172
|
||||
A15 = 173
|
||||
LBEG = 65
|
||||
LEND = 66
|
||||
LCOUNT = 67
|
||||
WINDOWBASE = 70
|
||||
WINDOWSTART = 71
|
||||
|
||||
|
||||
# Reverse-engineered from:
|
||||
# sof -> src/debug/gdb/gdb.c
|
||||
# sof -> src/arch/xtensa/include/xtensa/specreg.h
|
||||
class GdbRegDef_Intel_Adsp_CAVS_XCC:
|
||||
ARCH_DATA_BLK_STRUCT_REGS = '<IIIIIIIIIIIIIIIIIIIIIIIII'
|
||||
|
||||
# xt-gdb doesn't use the g packet at all
|
||||
SOC_GDB_GPKT_BIN_SIZE = 0
|
||||
|
||||
|
||||
class RegNum(Enum):
|
||||
PC = 32
|
||||
EXCCAUSE = 744
|
||||
EXCVADDR = 750
|
||||
SAR = 515
|
||||
PS = 742
|
||||
SCOMPARE1 = 524
|
||||
A0 = 256
|
||||
A1 = 257
|
||||
A2 = 258
|
||||
A3 = 259
|
||||
A4 = 260
|
||||
A5 = 261
|
||||
A6 = 262
|
||||
A7 = 263
|
||||
A8 = 264
|
||||
A9 = 265
|
||||
A10 = 266
|
||||
A11 = 267
|
||||
A12 = 268
|
||||
A13 = 269
|
||||
A14 = 270
|
||||
A15 = 271
|
||||
LBEG = 512
|
||||
LEND = 513
|
||||
LCOUNT = 514
|
||||
WINDOWBASE = 584
|
||||
WINDOWSTART = 585
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
config SOC_FAMILY_INTEL_ADSP
|
||||
select WINSTREAM
|
||||
select ARCH_SUPPORTS_COREDUMP
|
||||
bool
|
||||
|
||||
if SOC_FAMILY_INTEL_ADSP
|
||||
|
|
|
|||
|
|
@ -22,3 +22,16 @@ zephyr_library_sources_ifdef(
|
|||
CONFIG_DEBUG_COREDUMP_BACKEND_FLASH_PARTITION
|
||||
coredump_backend_flash_partition.c
|
||||
)
|
||||
|
||||
# @Intent: Set XTENSA_TOOLCHAIN_VARIANT macro required for Xtensa coredump
|
||||
if(CONFIG_XTENSA)
|
||||
if(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "zephyr")
|
||||
zephyr_compile_options(-DXTENSA_TOOLCHAIN_VARIANT=1)
|
||||
elseif(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "xcc")
|
||||
zephyr_compile_options(-DXTENSA_TOOLCHAIN_VARIANT=2)
|
||||
elseif(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "espressif")
|
||||
zephyr_compile_options(-DXTENSA_TOOLCHAIN_VARIANT=3)
|
||||
else()
|
||||
zephyr_compile_options(-DXTENSA_TOOLCHAIN_VARIANT=0)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -13,9 +13,14 @@ void func_3(uint32_t *addr)
|
|||
#if defined(CONFIG_BOARD_M2GL025_MIV) || \
|
||||
defined(CONFIG_BOARD_HIFIVE1) || \
|
||||
defined(CONFIG_BOARD_LONGAN_NANO) || \
|
||||
defined(CONFIG_BOARD_LONGAN_NANO_LITE)
|
||||
defined(CONFIG_BOARD_LONGAN_NANO_LITE) || \
|
||||
defined(CONFIG_SOC_FAMILY_INTEL_ADSP)
|
||||
ARG_UNUSED(addr);
|
||||
/* Call k_panic() directly so Renode doesn't pause execution */
|
||||
/* Call k_panic() directly so Renode doesn't pause execution.
|
||||
* Needed on ADSP as well, since null pointer derefence doesn't
|
||||
* fault as the lowest memory region is writable. SOF uses k_panic
|
||||
* a lot, so it's good to check that it causes a coredump.
|
||||
*/
|
||||
k_panic();
|
||||
#elif !defined(CONFIG_CPU_CORTEX_M)
|
||||
/* For null pointer reference */
|
||||
|
|
|
|||
Loading…
Reference in a new issue