lib/trace: Remove TRACE support
Looks like the option is generally not compatible with garbage collections. Nothing gets inlined, for example is_smp_boot() no longer evaluates to constant false and thus the symbols from secondary.S would need to be present for the build to pass even if we set SMP=n. Also the addresses of relocatable ramstage are currently not normalised on the logs, so util/genprof would be unable dress those. Change-Id: I0b6f310e15e6f4992cd054d288903fea8390e5cf Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/45757 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Angel Pons <th3fanbus@gmail.com> Reviewed-by: Nico Huber <nico.h@gmx.de>
This commit is contained in:
parent
5e053af7a6
commit
8c99c27df1
|
@ -183,9 +183,6 @@ decompressor-generic-ccopts += -D__DECOMPRESSOR__
|
|||
bootblock-generic-ccopts += -D__BOOTBLOCK__
|
||||
romstage-generic-ccopts += -D__ROMSTAGE__
|
||||
ramstage-generic-ccopts += -D__RAMSTAGE__
|
||||
ifeq ($(CONFIG_TRACE),y)
|
||||
ramstage-c-ccopts += -finstrument-functions
|
||||
endif
|
||||
ifeq ($(CONFIG_COVERAGE),y)
|
||||
ramstage-c-ccopts += -fprofile-arcs -ftest-coverage
|
||||
endif
|
||||
|
|
13
src/Kconfig
13
src/Kconfig
|
@ -1113,23 +1113,12 @@ config DEBUG_INTEL_ME
|
|||
is present on Intel 6-series chipsets.
|
||||
endif
|
||||
|
||||
config TRACE
|
||||
bool "Trace function calls"
|
||||
default n
|
||||
help
|
||||
If enabled, every function will print information to console once
|
||||
the function is entered. The syntax is ~0xaaaabbbb(0xccccdddd)
|
||||
the 0xaaaabbbb is the actual function and 0xccccdddd is EIP
|
||||
of calling function. Please note some printk related functions
|
||||
are omitted from trace to have good looking console dumps.
|
||||
|
||||
config DEBUG_FUNC
|
||||
bool "Enable function entry and exit reporting macros" if DEFAULT_CONSOLE_LOGLEVEL_8
|
||||
default n
|
||||
help
|
||||
This option enables additional function entry and exit debug messages
|
||||
for select functions. If supported, this is less output than
|
||||
the TRACE option.
|
||||
for select functions.
|
||||
Note: This option will increase the size of the coreboot image.
|
||||
If unsure, say N.
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <console/vtxprintf.h>
|
||||
#include <smp/spinlock.h>
|
||||
#include <smp/node.h>
|
||||
#include <trace.h>
|
||||
#include <timer.h>
|
||||
|
||||
DECLARE_SPIN_LOCK(console_lock)
|
||||
|
@ -81,7 +80,6 @@ int do_vprintk(int msg_level, const char *fmt, va_list args)
|
|||
if (log_this < CONSOLE_LOG_FAST)
|
||||
return 0;
|
||||
|
||||
DISABLE_TRACE;
|
||||
spin_lock(&console_lock);
|
||||
|
||||
console_time_run();
|
||||
|
@ -96,7 +94,6 @@ int do_vprintk(int msg_level, const char *fmt, va_list args)
|
|||
console_time_stop();
|
||||
|
||||
spin_unlock(&console_lock);
|
||||
ENABLE_TRACE;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <console/vtxprintf.h>
|
||||
#include <string.h>
|
||||
#include <trace.h>
|
||||
|
||||
struct vsnprintf_context {
|
||||
char *str_buf;
|
||||
|
@ -24,16 +23,12 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
|
|||
int i;
|
||||
struct vsnprintf_context ctx;
|
||||
|
||||
DISABLE_TRACE;
|
||||
|
||||
ctx.str_buf = buf;
|
||||
ctx.buf_limit = size ? size - 1 : 0;
|
||||
i = vtxprintf(str_tx_byte, fmt, args, &ctx);
|
||||
if (size)
|
||||
*ctx.str_buf = '\0';
|
||||
|
||||
ENABLE_TRACE;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include <arch/io.h>
|
||||
#include <boot/coreboot_tables.h>
|
||||
#include <console/uart.h>
|
||||
#include <trace.h>
|
||||
#include "uart8250reg.h"
|
||||
|
||||
/* Should support 8250, 16450, 16550, 16550A type UARTs */
|
||||
|
@ -54,7 +53,6 @@ static unsigned char uart8250_rx_byte(unsigned int base_port)
|
|||
|
||||
static void uart8250_init(unsigned int base_port, unsigned int divisor)
|
||||
{
|
||||
DISABLE_TRACE;
|
||||
/* Disable interrupts */
|
||||
outb(0x0, base_port + UART8250_IER);
|
||||
/* Enable FIFOs */
|
||||
|
@ -72,7 +70,6 @@ static void uart8250_init(unsigned int base_port, unsigned int divisor)
|
|||
|
||||
/* Set to 3 for 8N1 */
|
||||
outb(CONFIG_TTYS0_LCS, base_port + UART8250_LCR);
|
||||
ENABLE_TRACE;
|
||||
}
|
||||
|
||||
static const unsigned int bases[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __TRACE_H
|
||||
#define __TRACE_H
|
||||
|
||||
#if !ENV_ROMSTAGE_OR_BEFORE && CONFIG(TRACE)
|
||||
|
||||
void __cyg_profile_func_enter(void *, void *)
|
||||
__attribute__((no_instrument_function));
|
||||
|
||||
void __cyg_profile_func_exit(void *, void *)
|
||||
__attribute__((no_instrument_function));
|
||||
|
||||
extern volatile int trace_dis;
|
||||
|
||||
#define DISABLE_TRACE do { trace_dis = 1; } while (0);
|
||||
#define ENABLE_TRACE do { trace_dis = 0; } while (0);
|
||||
#define DISABLE_TRACE_ON_FUNCTION __attribute__((no_instrument_function));
|
||||
|
||||
#else /* !CONFIG_TRACE */
|
||||
|
||||
#define DISABLE_TRACE
|
||||
#define ENABLE_TRACE
|
||||
#define DISABLE_TRACE_ON_FUNCTION
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -140,8 +140,6 @@ ramstage-y += wrdd.c
|
|||
ramstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
|
||||
ramstage-$(CONFIG_BOOTSPLASH) += bootsplash.c
|
||||
ramstage-$(CONFIG_BOOTSPLASH) += jpeg.c
|
||||
ramstage-$(CONFIG_TRACE) += trace.c
|
||||
postcar-$(CONFIG_TRACE) += trace.c
|
||||
ramstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
|
||||
ramstage-$(CONFIG_COVERAGE) += libgcov.c
|
||||
ramstage-y += edid.c
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <console/console.h>
|
||||
#include <trace.h>
|
||||
|
||||
int volatile trace_dis = 0;
|
||||
|
||||
void __cyg_profile_func_enter(void *func, void *callsite)
|
||||
{
|
||||
|
||||
if (trace_dis)
|
||||
return;
|
||||
|
||||
DISABLE_TRACE
|
||||
printk(BIOS_INFO, "~%p(%p)\n", func, callsite);
|
||||
ENABLE_TRACE
|
||||
}
|
||||
|
||||
void __cyg_profile_func_exit(void *func, void *callsite)
|
||||
{
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
genprof
|
|
@ -1,12 +0,0 @@
|
|||
CC=gcc
|
||||
CFLAGS=-O2 -Wall
|
||||
|
||||
all: genprof
|
||||
|
||||
genprof: genprof.o
|
||||
$(CC) $(CFLAGS) -o genprof $^
|
||||
|
||||
clean:
|
||||
rm -f genprof *.o *~
|
||||
|
||||
distclean: clean
|
|
@ -1,31 +0,0 @@
|
|||
Function tracing
|
||||
----------------
|
||||
|
||||
Enable CONFIG_TRACE in debug menu. Run the compiled image on target. You will get
|
||||
a log with a lot of lines like:
|
||||
|
||||
...
|
||||
~0x001072e8(0x00100099)
|
||||
~0x00108bc0(0x0010730a)
|
||||
...
|
||||
|
||||
First address is address of function which was just entered, the second address
|
||||
is address of functions which call that.
|
||||
|
||||
You can use the log2dress to dress the log again:
|
||||
|
||||
...
|
||||
src/arch/x86/lib/c_start.S:85 calls /home/ruik/coreboot/src/boot/selfboot.c:367
|
||||
/home/ruik/coreboot/src/boot/selfboot.c:370 calls /home/ruik/coreboot/src/device/device.c:325
|
||||
...
|
||||
|
||||
Alternatively, you can use genprof to generate a gmon.out file, which can be used
|
||||
by gprof to show the call traces. You will need to install uthash library to compile
|
||||
that.
|
||||
|
||||
Great use is:
|
||||
|
||||
make
|
||||
./genprof /tmp/yourlog ; gprof ../../build/ramstage | ./gprof2dot.py -e0 -n0 | dot -Tpng -o output.png
|
||||
|
||||
Which generates a PNG with a call graph.
|
|
@ -1 +0,0 @@
|
|||
Format function tracing logs `Bash` `C`
|
|
@ -1,114 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <uthash.h>
|
||||
#include <sys/gmon_out.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define GMON_SEC "seconds s"
|
||||
uint32_t mineip = 0xffffffff;
|
||||
uint32_t maxeip = 0;
|
||||
|
||||
/* a hash structure to hold the arc */
|
||||
struct arec {
|
||||
uint32_t eip;
|
||||
uint32_t from;
|
||||
uint32_t count;
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
|
||||
struct arec *arc = NULL;
|
||||
|
||||
void note_arc(uint32_t eip, uint32_t from)
|
||||
{
|
||||
struct arec *s;
|
||||
|
||||
HASH_FIND_INT(arc, &eip, s);
|
||||
if (s == NULL) {
|
||||
s = malloc(sizeof(struct arec));
|
||||
s->eip = eip;
|
||||
s->from = from;
|
||||
s->count = 1;
|
||||
if (eip > maxeip)
|
||||
maxeip = eip;
|
||||
if (eip < mineip)
|
||||
maxeip = eip;
|
||||
|
||||
HASH_ADD_INT(arc, eip, s);
|
||||
} else {
|
||||
s->count++;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
FILE *f, *fo;
|
||||
struct arec *s;
|
||||
uint32_t eip, from, tmp;
|
||||
uint8_t tag;
|
||||
uint16_t hit;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Please specify the coreboot trace log as parameter\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
f = fopen(argv[1], "r");
|
||||
if (f == NULL) {
|
||||
perror("Unable to open the input file");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fo = fopen("gmon.out", "w+");
|
||||
if (fo == NULL) {
|
||||
perror("Unable to open the output file");
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (!feof(f)) {
|
||||
if (fscanf(f, "~%x(%x)%*[^\n]\n", &eip, &from) == 2) {
|
||||
note_arc(eip, from);
|
||||
} else if (fscanf(f, "%*c~%x(%x)%*[^\n]\n", &eip, &from) == 2) {
|
||||
note_arc(eip, from);
|
||||
} else {
|
||||
/* just drop a line */
|
||||
tmp = fscanf(f, "%*[^\n]\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* write gprof header */
|
||||
fwrite(GMON_MAGIC, 1, sizeof(GMON_MAGIC) - 1, fo);
|
||||
tmp = GMON_VERSION;
|
||||
fwrite(&tmp, 1, sizeof(tmp), fo);
|
||||
tmp = 0;
|
||||
fwrite(&tmp, 1, sizeof(tmp), fo);
|
||||
fwrite(&tmp, 1, sizeof(tmp), fo);
|
||||
fwrite(&tmp, 1, sizeof(tmp), fo);
|
||||
/* write fake histogram */
|
||||
tag = GMON_TAG_TIME_HIST;
|
||||
fwrite(&tag, 1, sizeof(tag), fo);
|
||||
fwrite(&mineip, 1, sizeof(mineip), fo);
|
||||
fwrite(&maxeip, 1, sizeof(maxeip), fo);
|
||||
/* size of histogram */
|
||||
tmp = 1;
|
||||
fwrite(&tmp, 1, sizeof(tmp), fo);
|
||||
/* prof rate */
|
||||
tmp = 1000;
|
||||
fwrite(&tmp, 1, sizeof(tmp), fo);
|
||||
fwrite(GMON_SEC, 1, sizeof(GMON_SEC) - 1, fo);
|
||||
hit = 1;
|
||||
fwrite(&hit, 1, sizeof(hit), fo);
|
||||
|
||||
/* write call graph data */
|
||||
tag = GMON_TAG_CG_ARC;
|
||||
for (s = arc; s != NULL; s = s->hh.next) {
|
||||
fwrite(&tag, 1, sizeof(tag), fo);
|
||||
fwrite(&s->from, 1, sizeof(s->from), fo);
|
||||
fwrite(&s->eip, 1, sizeof(s->eip), fo);
|
||||
fwrite(&s->count, 1, sizeof(s->count), fo);
|
||||
}
|
||||
|
||||
fclose(fo);
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#Parse a log and get back the function names and line numbers
|
||||
#Provide a log file as first argument
|
||||
|
||||
#Please rewrite to something more saner !
|
||||
|
||||
cat $1 | while read line ; do
|
||||
A=`echo $line | cut -c 1`
|
||||
|
||||
if [ "$A" = '~' ] ; then
|
||||
FROM=`echo $line | tr \~ \( | tr \) \( | awk -F\( '{print $3}'`
|
||||
TO=`echo $line | tr \~ \( | tr \) \(|awk -F\( '{print $2}'`
|
||||
addr2line -e ../../build/cbfs/fallback/ramstage.debug "$FROM" | tr -d "\n"
|
||||
echo -n " calls "
|
||||
addr2line -e ../../build/cbfs/fallback/ramstage.debug "$TO"
|
||||
else
|
||||
echo "$line"
|
||||
fi
|
||||
|
||||
done
|
Loading…
Reference in New Issue