blob: 437e7735c9fed6c41e05d4533244993a5d352028 [file] [log] [blame]
/*
* Copyright (c) 2016, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Intel Corporation nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
* Keyon Jie <yang.jie@linux.intel.com>
*/
#ifndef __INCLUDE_DEBUG__
#define __INCLUDE_DEBUG__
#include <sof/sof.h>
#include <sof/mailbox.h>
#include <uapi/ipc.h>
#include <platform/platform.h>
#include <stdint.h>
#include <stdlib.h>
#define DEBUG
#ifdef DEBUG
/* dump file and line to start of mailbox or shared memory */
#define dbg() \
do { \
volatile uint32_t *__m = (uint32_t*)mailbox_get_debug_base(); \
*(__m++) = (__FILE__[0] << 24) + (__FILE__[1] << 16) +\
(__FILE__[2] << 8) + (__FILE__[3]); \
*(__m++) = (__func__[0] << 24) + (__func__[1] << 16) + \
(__func__[2] << 8) + (__func__[3]); \
*__m = __LINE__; \
} while (0);
/* dump file and line to offset in mailbox or shared memory */
#define dbg_at(__x) \
do { \
volatile uint32_t *__m = (uint32_t*)mailbox_get_debug_base() + __x; \
*(__m++) = (__FILE__[0] << 24) + (__FILE__[1] << 16) +\
(__FILE__[2] << 8) + (__FILE__[3]); \
*(__m++) = (__func__[0] << 24) + (__func__[1] << 16) + \
(__func__[2] << 8) + (__func__[3]); \
*__m = __LINE__; \
} while (0);
/* dump value to start of mailbox or shared memory */
#define dbg_val(__v) \
do { \
volatile uint32_t *__m = \
(volatile uint32_t*)mailbox_get_debug_base(); \
*__m = __v; \
} while (0);
/* dump value to offset in mailbox or shared memory */
#define dbg_val_at(__v, __x) \
do { \
volatile uint32_t *__m = \
(volatile uint32_t*)mailbox_get_debug_base() + __x; \
*__m = __v; \
} while (0);
/* dump data area at addr and size count to start of mailbox or shared memory */
#define dump(addr, count) \
do { \
volatile uint32_t *__m = (uint32_t*)mailbox_get_debug_base(); \
volatile uint32_t *__a = (uint32_t*)addr; \
volatile int __c = count; \
while (__c--) \
*(__m++) = *(__a++); \
} while (0);
/* dump data area at addr and size count at mailbox offset or shared memory */
#define dump_at(addr, count, offset) \
do { \
volatile uint32_t *__m = (uint32_t*)mailbox_get_debug_base() + offset; \
volatile uint32_t *__a = (uint32_t*)addr; \
volatile int __c = count; \
while (__c--) \
*(__m++) = *(__a++); \
} while (0);
/* dump object to start of mailbox */
#define dump_object(__o) \
dbg(); \
dump(&__o, sizeof(__o) >> 2);
/* dump object from pointer at start of mailbox */
#define dump_object_ptr(__o) \
dbg(); \
dump(__o, sizeof(*(__o)) >> 2);
#define dump_object_ptr_at(__o, __at) \
dbg(); \
dump_at(__o, sizeof(*(__o)) >> 2, __at);
#else
#define dbg()
#define dbg_at(__x)
#define dbg_val(__v)
#define dbg_val_at(__v, __x)
#define dump(addr, count)
#define dump_object(__o)
#define dump_object_ptr(__o)
#endif
/* dump stack as part of panic */
static inline uint32_t dump_stack(uint32_t p, void *addr, size_t offset,
size_t limit)
{
extern void *__stack;
extern void *_stack_sentry;
void *stack_bottom = (void *)&__stack - sizeof(void *);
void *stack_limit = (void *)&_stack_sentry;
void *stack_top = arch_get_stack_ptr() + offset;
size_t size = stack_bottom - stack_top;
/* is stack smashed ? */
if (stack_top - offset <= stack_limit) {
stack_bottom = stack_limit;
p = SOF_IPC_PANIC_STACK;
return p;
}
/* make sure stack size won't overflow dump area */
if (size > limit)
size = limit;
/* copy stack contents and writeback */
rmemcpy(addr, stack_top, size - sizeof(void *));
dcache_writeback_region(addr, size - sizeof(void *));
return p;
}
#endif