[5/8] arm: Add boottime support for the ARM architecture

Message ID 1353422034-28107-6-git-send-email-lee.jones@linaro.org
State New
Headers show

Commit Message

Lee Jones Nov. 20, 2012, 2:33 p.m.
This patch adds support for passing boot time information to
the Linus kernel using ATAGS when booting on ARM based devices.

Based heavily on the original driver by Jonas Aaberg.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 arch/arm/include/asm/setup.h |   18 +++++++++++++++++
 arch/arm/lib/bootm.c         |   45 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 61 insertions(+), 2 deletions(-)

Patch

diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index 78a7fac..6088440 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -205,6 +205,19 @@  struct tag_memclk {
 	u32 fmemclk;
 };
 
+/* for automatic boot timing testcases */
+#define ATAG_BOOTTIME  0x41000403
+#define BOOTTIME_MAX 10
+
+#include <boottime.h>
+
+struct tag_boottime {
+	struct boottime_entry entry[BOOTTIME_MAX];
+	u32 idle;  /* in us */
+	u32 total; /* in us */
+	u8 num;
+};
+
 struct tag {
 	struct tag_header hdr;
 	union {
@@ -227,6 +240,11 @@  struct tag {
 		 * DC21285 specific
 		 */
 		struct tag_memclk	memclk;
+
+		/*
+		 * Boot time
+		 */
+		struct tag_boottime     boottime;
 	} u;
 };
 
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index 1bd2730..03774c8 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -28,6 +28,7 @@ 
 #include <common.h>
 #include <command.h>
 #include <image.h>
+#include <boottime.h>
 #include <u-boot/zlib.h>
 #include <asm/byteorder.h>
 #include <fdt.h>
@@ -114,7 +115,8 @@  static void announce_and_cleanup(void)
 	defined(CONFIG_CMDLINE_TAG) || \
 	defined(CONFIG_INITRD_TAG) || \
 	defined(CONFIG_SERIAL_TAG) || \
-	defined(CONFIG_REVISION_TAG)
+	defined(CONFIG_REVISION_TAG) || \
+	defined(CONFIG_BOOTTIME)
 static void setup_start_tag (bd_t *bd)
 {
 	params = (struct tag *)bd->bi_boot_params;
@@ -130,6 +132,37 @@  static void setup_start_tag (bd_t *bd)
 }
 #endif
 
+#ifdef CONFIG_BOOTTIME
+static void setup_boottime_tags(void)
+{
+	unsigned int i;
+	struct boottime_entry *b;
+
+	params->hdr.tag = ATAG_BOOTTIME;
+	params->hdr.size = tag_size(tag_boottime);
+
+	params->u.boottime.idle = boottime_idle_get();
+	params->u.boottime.total = boottime_idle_done();
+
+	for (i = 0; i < BOOTTIME_MAX; i++) {
+		b = boottime_get_entry(i);
+		if (b == NULL)
+			break;
+
+		params->u.boottime.entry[i].time = b->time;
+		strncpy((char *)params->u.boottime.entry[i].name,
+			(char *)b->name, BOOTTIME_MAX_NAME_LEN);
+		params->u.boottime.entry[i].name[BOOTTIME_MAX_NAME_LEN - 1] = '\0';
+
+	}
+
+	params->u.boottime.num = i;
+
+	params = tag_next(params);
+
+}
+#endif
+
 #ifdef CONFIG_SETUP_MEMORY_TAGS
 static void setup_memory_tags(bd_t *bd)
 {
@@ -233,6 +266,10 @@  static void setup_end_tag(bd_t *bd)
 }
 #endif
 
+#ifdef CONFIG_BOOTTIME
+static void setup_boottime_tags(void);
+#endif
+
 #ifdef CONFIG_OF_LIBFDT
 static int create_fdt(bootm_headers_t *images)
 {
@@ -293,9 +330,13 @@  static void boot_prep_linux(bootm_headers_t *images)
 	defined(CONFIG_CMDLINE_TAG) || \
 	defined(CONFIG_INITRD_TAG) || \
 	defined(CONFIG_SERIAL_TAG) || \
-	defined(CONFIG_REVISION_TAG)
+	defined(CONFIG_REVISION_TAG) || \
+	defined (CONFIG_BOOTTIME)
 		debug("using: ATAGS\n");
 		setup_start_tag(gd->bd);
+#ifdef CONFIG_BOOTTIME
+		setup_boottime_tags();
+#endif
 #ifdef CONFIG_SERIAL_TAG
 		setup_serial_tag(&params);
 #endif