Hi,

Sorry about the email quality I'm too tired to re-check it again.

I had an idea to hijack the gprof for fun. I compiled the coreboot with -pg option (and enabled stack frames) resulting that each called function has a "mcount" funtion called in prolog for gprof. However we do not use libc and gprof but we can use this for:

1) to show where whole execution flow goes
2) real time tracing (if console is RAM)
3) stack size checking

So far I have a proof of concept which is attached. It adds for ramstage -pg option and then implements the mcount function which looks into the frame pointer and prints to serial console who is it and who is the caller. This function then calls C function gprof which just print stack size and that information

Also, I protect the recursive usage of mcount during the gprof call via in_pg. Which is also triggered to remove sprintf and printf bits from logs.

It produces something like this:


Stage: loading fallback/coreboot_ram @ 0x100000 (606208 bytes), entry @ 0x100000
Stage: done loading.
Jumping to image.
~0x00107139(0x00100099)1638316
~0x00108599(0x00107146)1638304
~0x00107da5(0x0010714b)1638296
~0x001070fe(0x00107dbe)1638288
~0x00108599(0x00107157)1638304
~0x00107d3c(0x00107186)1638264
coreboot-4.0-1681-gd6a736e-dirty Mon Aug 29 22:56:18 CEST 2011 booting...
~0x00108599(0x00107190)1638304
~0x0011157d(0x001071a1)1638320
~0x00109a7a(0x001071a6)1638304
~0x00107d3c(0x00109a86)1638264
Enumerating buses...

No timing info so far. I annotate this log with a help of gdb and script tp:

Check fallback/romstage
Check fallback/coreboot_ram
Stage: loading fallback/coreboot_ram @ 0x100000 (606208 bytes), entry @ 0x100000
Stage: done loading.
Jumping to image.
~0x00107139(0x00100099)1638316~0x107139 is in hardwaremain (src/boot /hardwaremain.c:57). FROM 0x100099 is at src/arch/x86/lib/c_start.S:85. ~0x00108599(0x00107146)1638304~0x108599 is in post_code (src/arch/x86/include/arch/io.h:46). FROM 0x107146 is in hardwaremain (src/boot/hardwaremain.c:63). ~0x00107da5(0x0010714b)1638296~0x107da5 is in console_init (src/console/console.c:42). FROM 0x10714b is in hardwaremain (src/boot/hardwaremain.c:65). ~0x001070fe(0x00107dbe)1638288~0x1070fe is in uart_init (src/arch/x86/include/arch/io.h:46). FROM 0x107dbe is in console_init (src/console/console.c:44). ~0x00108599(0x00107157)1638304~0x108599 is in post_code (src/arch/x86/include/arch/io.h:46). FROM 0x107157 is in hardwaremain (src/boot/hardwaremain.c:67). ~0x00107d3c(0x00107186)1638264~0x107d3c is in do_printk (src/console/printk.c:25). FROM 0x107186 is in hardwaremain (src/boot/hardwaremain.c:71).
coreboot-4.0-1681-gd6a736e-dirty Mon Aug 29 22:56:18 CEST 2011 booting...

Or some nice bits:

Adding high table area
~0x0010dc84(0x0010e23d)463340~0x10dc84 is in lb_add_memory_range (src/arch/x86/boot/coreboot_table.c:417). FROM 0x10e23d is in write_coreboot_table (src/arch/x86/boot/coreboot_table.c:495). ~0x00113a60(0x0010dd65)463304~0x113a60 is in memmove (src/lib/memmove.c:3). FROM 0x10dd65 is in lb_add_memory_range (src/arch/x86/boot/coreboot_table.c:383). ~0x00113a60(0x0010dd65)463304~0x113a60 is in memmove (src/lib/memmove.c:3). FROM 0x10dd65 is in lb_add_memory_range (src/arch/x86/boot/coreboot_table.c:383). ~0x0010d96a(0x0010dea1)463296~0x10d96a is in lb_memory_range (src/arch/x86/boot/coreboot_table.c:252). FROM 0x10dea1 is in lb_add_memory_range (src/arch/x86/boot/coreboot_table.c:420). ~0x0010d9fa(0x0010e23d)463324~0x10d9fa is in lb_cleanup_memory_ranges (src/arch/x86/boot/coreboot_table.c:317). FROM 0x10e23d is in write_coreboot_table (src/arch/x86/boot/coreboot_table.c

P#1 freq 1000 [MHz] voltage 1100 [mV] TDP 21000 [mW]
~0x00110384(0x00116dcd)463164~0x110384 is in acpigen_write_processor (src/arch/x86/boot/acpigen.c:259). FROM 0x116dcd is in amd_model_fxx_generate_powernow (src/cpu/amd/model_fxx/powernow_a
cpi.c:44).
~0x0010fd74(0x001103ab)463148~0x10fd74 is in acpigen_write_len_f (src/arch/x86/boot/acpigen.c:40). FROM 0x1103ab is in acpigen_write_processor (src/arch/x86/boot/acpigen.c:271). ~0x0010853f(0x001103c4)463128~0x10853f is in sprintf (src/console/vsprintf.c:58). FROM 0x1103c4 is in acpigen_write_processor (src/arch/x86/boot/acpigen.c:272). ~0x0010fe6b(0x001103cc)463100~0x10fe6b is in acpigen_emit_namestring (src/arch/x86/boot/acpigen.c:203). FROM 0x1103cc is in acpigen_write_processor (src/arch/x86/boot/acpigen.c:70). ~0x0010fb66(0x0010ff03)463048~0x10fb66 is in acpigen_emit_simple_namestring (src/arch/x86/boot/acpigen.c:156). FROM 0x10ff03 is in acpigen_emit_namestring (src/arch/x86/boot/acpigen.c:174). ~0x0010fb66(0x0010ff14)463048~0x10fb66 is in acpigen_emit_simple_namestring (src/arch/x86/boot/acpigen.c:156). FROM 0x10ff14 is in acpigen_emit_namestring (src/arch/x86/boot/acpigen.c:234). ~0x0010fbcf(0x00116dd8)463236~0x10fbcf is in acpigen_write_empty_PCT (src/arch/x86/boot/acpigen.c:283). FROM 0x116dd8 is in amd_model_fxx_generate_powernow (src/cpu/amd/model_fxx/powernow_a

It looks like a fun, especially if one can image that the log is printed to raw memory and TSC info is used.

The whole log is on assembler.cz/alog.txt.gz which answeres a questions about execution flows ;)

I bit changed the annotate script at the end, because it took ages to execute ;) Good method is to just grep all lines with the info to one file, sort -u ask for the rest and just grep in the results for matching lines and intermix with original log. Instead of doing 30000 lines it did only few hundreds.

If there is someone with more time it would be great to integrate this somehow.

Thanks
Rudolf
>From 251e44bb0cfd07c0fc40335873b5ceecea4a28ca Mon Sep 17 00:00:00 2001
From: Rudolf Marek <[email protected]>
Date: Mon, 29 Aug 2011 23:29:30 +0200
Subject: [PATCH] dummy commit

Change-Id: I3a9655a17abab7114406eaf1c458542a84046ac4
---
 get_back.sh      |   27 +++++++++++++++++++++++++++
 src/lib/gprof.c  |   40 ++++++++++++++++++++++++++++++++++++++++
 src/lib/mcount.S |   32 ++++++++++++++++++++++++++++++++
 3 files changed, 99 insertions(+), 0 deletions(-)
 create mode 100755 get_back.sh
 create mode 100644 src/lib/gprof.c
 create mode 100644 src/lib/mcount.S

diff --git a/get_back.sh b/get_back.sh
new file mode 100755
index 0000000..cecfa47
--- /dev/null
+++ b/get_back.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+function ask_gdb {
+echo 'list *'"$1" > /tmp/a
+gdb  -batch -x /tmp/a build/coreboot_ram | grep ^0x
+}
+
+
+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}'`
+F=`ask_gdb "$FROM"`
+T=`ask_gdb "$TO"`
+echo $T FROM $F
+else
+echo "$line"
+fi
+
+
+
+#echo $line
+
+done
\ No newline at end of file
diff --git a/src/lib/gprof.c b/src/lib/gprof.c
new file mode 100644
index 0000000..12243b8
--- /dev/null
+++ b/src/lib/gprof.c
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Rudolf Marek <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#include <types.h>
+#include <console/console.h>
+
+volatile int in_pg = 0;
+
+
+void gprof(u32 fromeip, u32 callerip);
+
+void gprof(u32 fromeip, u32 callerip) {
+	int size;
+
+	asm volatile ("movl %%esp, %%eax\t\n"
+		       "subl _estack, %%eax\n\t"
+			"movl %%eax, %0\n\t"
+			: "=r" (size)
+			:
+			: "eax"
+			);
+    printk(BIOS_INFO, "~0x%08x(0x%08x)%d\n", fromeip, callerip, size );
+}
+
diff --git a/src/lib/mcount.S b/src/lib/mcount.S
new file mode 100644
index 0000000..c667248
--- /dev/null
+++ b/src/lib/mcount.S
@@ -0,0 +1,32 @@
+.text
+        .globl _mcount
+/*
+
+RETaddr
+oldEBP
+EBP = ESP
+
+
+*/
+_mcount:
+	pushl	%ebp
+	movl	%esp,%ebp
+
+	movl $1, %eax
+	xchg  %eax, (in_pg)
+	testl %eax, %eax
+	jnz	out
+
+	movl	(%ebp), %eax /* get frame pointer of caller */
+	movl	4(%eax), %eax /* get caller of caller */
+	pushl	%eax		/*pass it to the gprof */
+	pushl	4(%ebp) /* safe caller EIP on stack */
+
+	call	gprof
+
+	movl $0, %eax
+	xchg  %eax, (in_pg)
+out:
+	movl    %ebp,%esp
+	popl    %ebp
+	ret
-- 
1.7.1

diff --git a/Makefile.inc b/Makefile.inc
index 37e4fb6..425501a 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -112,7 +112,8 @@ CFLAGS += -Wstrict-aliasing -Wshadow
 ifeq ($(CONFIG_WARNINGS_ARE_ERRORS),y)
 CFLAGS += -Werror
 endif
-CFLAGS += -fno-common -ffreestanding -fno-builtin -fomit-frame-pointer
+CFLAGS += -fno-common -ffreestanding -fno-builtin
+#-fomit-frame-pointer
 
 additional-dirs := $(objutil)/cbfstool $(objutil)/romcc $(objutil)/options
 
@@ -181,7 +182,7 @@ $(objutil)/%.o: $(objutil)/%.c
 
 $(obj)/%.ramstage.o $(abspath $(obj))/%.ramstage.o: $(obj)/%.c $(obj)/config.h $(OPTION_TABLE_H)
 	@printf "    CC         $(subst $(obj)/,,$(@))\n"
-	$(CC) -MMD $(CFLAGS) -c -o $@ $<
+	$(CC) -MMD $(CFLAGS)  -c -o $@ $<
 
 #######################################################################
 # Clean up rules
diff --git a/src/console/printk.c b/src/console/printk.c
index 488d4e5..26863fc 100644
--- a/src/console/printk.c
+++ b/src/console/printk.c
@@ -14,6 +14,9 @@ int default_console_loglevel = CONFIG_DEFAULT_CONSOLE_LOGLEVEL;
 
 DECLARE_SPIN_LOCK(console_lock)
 
+
+extern volatile int in_pg;
+
 int do_printk(int msg_level, const char *fmt, ...)
 {
 	va_list args;
@@ -23,6 +26,7 @@ int do_printk(int msg_level, const char *fmt, ...)
 		return 0;
 	}
 
+	in_pg = 1;
 	spin_lock(&console_lock);
 
 	va_start(args, fmt);
@@ -32,6 +36,6 @@ int do_printk(int msg_level, const char *fmt, ...)
 	console_tx_flush();
 
 	spin_unlock(&console_lock);
-
+	in_pg = 0;
 	return i;
 }
diff --git a/src/console/vsprintf.c b/src/console/vsprintf.c
index 4a74523..aa8fcf3 100644
--- a/src/console/vsprintf.c
+++ b/src/console/vsprintf.c
@@ -48,14 +48,19 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
 	return i;
 }
 
+extern volatile int in_pg;
+
 int sprintf(char *buf, const char *fmt, ...)
 {
 	va_list args;
 	int i;
 
+	in_pg = 1;
+
 	va_start(args, fmt);
 	i = vsprintf(buf, fmt, args);
 	va_end(args);
 
+	in_pg = 0;
 	return i;
 }
diff --git a/src/cpu/amd/car/post_cache_as_ram.c b/src/cpu/amd/car/post_cache_as_ram.c
index 270c542..0f646b7 100644
--- a/src/cpu/amd/car/post_cache_as_ram.c
+++ b/src/cpu/amd/car/post_cache_as_ram.c
@@ -122,10 +122,12 @@ static void post_cache_as_ram(void)
 	__asm__ volatile (
 		/* set new esp */ /* before CONFIG_RAMBASE */
 		"subl   %0, %%esp\n\t"
+		"subl   %0, %%ebp\n\t"
+		"nop\n\t"
 		::"a"( (CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE)- (CONFIG_RAMTOP) )
 		/* discard all registers (eax is used for %0), so gcc redo everything
 		   after the stack is moved */
-		: "cc", "memory", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp"
+		: "cc", "memory", "%ebx", "%ecx", "%edx", "%esi", "%edi"
 	);
 
 	/* We can put data to stack again */
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 54935ca..afa8d56 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -13,7 +13,8 @@ romstage-$(CONFIG_CONSOLE_SERIAL8250MEM) += uart8250mem.c
 romstage-$(CONFIG_CONSOLE_NE2K) += ne2k.c
 romstage-$(CONFIG_CONSOLE_NE2K) += compute_ip_checksum.c
 romstage-$(CONFIG_USBDEBUG) += usbdebug.c
-
+ramstage-y += gprof.c
+ramstage-y += mcount.S
 ramstage-y += memset.c
 ramstage-y += memcpy.c
 ramstage-y += memcmp.c
diff --git a/src/southbridge/Makefile.inc b/src/southbridge/Makefile.inc
index b7e04db..3e8aca5 100644
--- a/src/southbridge/Makefile.inc
+++ b/src/southbridge/Makefile.inc
@@ -1,3 +1,4 @@
+ramstage-c-ccopts+=-pg
 subdirs-y += amd
 subdirs-y += broadcom
 subdirs-y += intel
-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to