[U-Boot] [PATCH 5/8] arm: Add boottime support for the ARM architecture

Lee Jones
2012-11-20T14:33:51Z

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(-)

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
--
1.7.9.5