[coreboot-gerrit] New patch to review for coreboot: 5f52bcc boot state: run timers on state entry

Aaron Durbin (adurbin@google.com) gerrit at coreboot.org
Tue Apr 30 18:29:08 CEST 2013


Aaron Durbin (adurbin at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3159

-gerrit

commit 5f52bcc91ae1dc8f6755a4c5f5b0419a09ca1070
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Mon Apr 29 23:22:01 2013 -0500

    boot state: run timers on state entry
    
    When TIMER_QUEUE is configured on call the timer callbacks on
    entry into a state but before its entry callbacks. In addition
    provide a barrier to the following states so that timers are drained
    before proceeding. This allows for blocking state traversal for key
    components of boot.
    	BS_OS_RESUME
    	BS_WRITE_TABLES
    	BS_PAYLOAD_LOAD
    	BS_PAYLOAD_BOOT
    
    Future functionality consists of evaluating the timer callbacks within
    the device tree. One example is dev_initialize() as that seems state
    seems to take 90% of the boot time. The timer callbacks could then be
    ran in a more granular manner.
    
    Change-Id: Idb549ea17c5ec38eb57b4f6f366a1c2183f4a6dd
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 src/lib/hardwaremain.c | 48 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 34 insertions(+), 14 deletions(-)

diff --git a/src/lib/hardwaremain.c b/src/lib/hardwaremain.c
index 7bf0237..8e5481e 100644
--- a/src/lib/hardwaremain.c
+++ b/src/lib/hardwaremain.c
@@ -78,23 +78,27 @@ struct boot_state {
 	struct boot_state_callback *seq_callbacks[2];
 	boot_state_t (*run_state)(void *arg);
 	void *arg;
-	int complete;
+	int complete : 1;
+	int timers_drain : 1;
 #if CONFIG_HAVE_MONOTONIC_TIMER
 	struct boot_state_times times;
 #endif
 };
 
-#define BS_INIT(state_, run_func_)		\
-	{					\
-		.name = #state_,		\
-		.id = state_,			\
-		.seq_callbacks = { NULL, NULL },\
-		.run_state = run_func_,		\
-		.arg = NULL,			\
-		.complete = 0			\
+#define BS_INIT(state_, run_func_, drain_timers_)		\
+	{							\
+		.name = #state_,				\
+		.id = state_,					\
+		.seq_callbacks = { NULL, NULL },		\
+		.run_state = run_func_,				\
+		.arg = NULL,					\
+		.complete = 0,					\
+		.timers_drain = drain_timers_,			\
 	}
 #define BS_INIT_ENTRY(state_, run_func_)	\
-	[state_] = BS_INIT(state_, run_func_)
+	[state_] = BS_INIT(state_, run_func_, 0)
+#define BS_INIT_ENTRY_DRAIN_TIMERS(state_, run_func_)	\
+	[state_] = BS_INIT(state_, run_func_, 1)
 
 static struct boot_state boot_states[] = {
 	BS_INIT_ENTRY(BS_PRE_DEVICE, bs_pre_device),
@@ -105,10 +109,10 @@ static struct boot_state boot_states[] = {
 	BS_INIT_ENTRY(BS_DEV_INIT, bs_dev_init),
 	BS_INIT_ENTRY(BS_POST_DEVICE, bs_post_device),
 	BS_INIT_ENTRY(BS_OS_RESUME_CHECK, bs_os_resume_check),
-	BS_INIT_ENTRY(BS_OS_RESUME, bs_os_resume),
-	BS_INIT_ENTRY(BS_WRITE_TABLES, bs_write_tables),
-	BS_INIT_ENTRY(BS_PAYLOAD_LOAD, bs_payload_load),
-	BS_INIT_ENTRY(BS_PAYLOAD_BOOT, bs_payload_boot),
+	BS_INIT_ENTRY_DRAIN_TIMERS(BS_OS_RESUME, bs_os_resume),
+	BS_INIT_ENTRY_DRAIN_TIMERS(BS_WRITE_TABLES, bs_write_tables),
+	BS_INIT_ENTRY_DRAIN_TIMERS(BS_PAYLOAD_LOAD, bs_payload_load),
+	BS_INIT_ENTRY_DRAIN_TIMERS(BS_PAYLOAD_BOOT, bs_payload_boot),
 };
 
 static boot_state_t bs_pre_device(void *arg)
@@ -278,6 +282,20 @@ static inline void bs_sample_time(struct boot_state *state) {}
 static inline void bs_report_time(struct boot_state *state) {}
 #endif
 
+#if CONFIG_TIMER_QUEUE
+static void bs_run_timers(int drain)
+{
+	/* Drain all timer callbacks until none are left, if directed.
+	 * Otherwise run the timers only once. */
+	do {
+		if (!timers_run())
+			break;
+	} while (drain);
+}
+#else
+static void bs_run_timers(int drain) {}
+#endif
+
 static void bs_call_callbacks(struct boot_state *state,
                               boot_state_sequence_t seq)
 {
@@ -313,6 +331,8 @@ static void bs_walk_state_machine(boot_state_t current_state_id)
 
 		printk(BS_DEBUG_LVL, "BS: Entering %s state.\n", state->name);
 
+		bs_run_timers(state->timers_drain);
+
 		bs_sample_time(state);
 
 		bs_call_callbacks(state, BS_ON_ENTRY);



More information about the coreboot-gerrit mailing list