X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=include%2Fbootstage.h;h=3b2216b8a8c8316df3dec35153947087623a905c;hb=ea2453d56b8860dbd18a3c517531ffc8dcb5c839;hp=b56d95351c8f8d850fd84dc4534e4752641a4ca1;hpb=770605e4f9874230728f5a592820c619b1565ebc;p=u-boot diff --git a/include/bootstage.h b/include/bootstage.h index b56d95351c..3b2216b8a8 100644 --- a/include/bootstage.h +++ b/include/bootstage.h @@ -26,6 +26,17 @@ #ifndef _BOOTSTAGE_H #define _BOOTSTAGE_H +/* The number of boot stage records available for the user */ +#ifndef CONFIG_BOOTSTAGE_USER_COUNT +#define CONFIG_BOOTSTAGE_USER_COUNT 20 +#endif + +/* Flags for each bootstage record */ +enum bootstage_flags { + BOOTSTAGEF_ERROR = 1 << 0, /* Error record */ + BOOTSTAGEF_ALLOC = 1 << 1, /* Allocate an id */ +}; + /* * A list of boot stages that we know about. Each of these indicates the * state that we are at, and the action that we are about to perform. For @@ -169,8 +180,48 @@ enum bootstage_id { BOOTSTAGE_ID_NAND_FIT_READ = 150, BOOTSTAGE_ID_NAND_FIT_READ_OK, + + /* + * These boot stages are new, higher level, and not directly related + * to the old boot progress numbers. They are useful for recording + * rough boot timing information. + */ + BOOTSTAGE_ID_AWAKE, + BOOTSTAGE_ID_START_SPL, + BOOTSTAGE_ID_START_UBOOT_F, + BOOTSTAGE_ID_START_UBOOT_R, + BOOTSTAGE_ID_USB_START, + BOOTSTAGE_ID_ETH_START, + BOOTSTAGE_ID_BOOTP_START, + BOOTSTAGE_ID_BOOTP_STOP, + BOOTSTAGE_ID_BOOTM_START, + BOOTSTAGE_ID_BOOTM_HANDOFF, + BOOTSTAGE_ID_MAIN_LOOP, + BOOTSTAGE_KERNELREAD_START, + BOOTSTAGE_KERNELREAD_STOP, + BOOTSTAGE_ID_BOARD_INIT, + BOOTSTAGE_ID_BOARD_INIT_DONE, + + BOOTSTAGE_ID_CPU_AWAKE, + BOOTSTAGE_ID_MAIN_CPU_AWAKE, + BOOTSTAGE_ID_MAIN_CPU_READY, + + BOOTSTAGE_ID_ACCUM_LCD, + + /* a few spare for the user, from here */ + BOOTSTAGE_ID_USER, + BOOTSTAGE_ID_COUNT = BOOTSTAGE_ID_USER + CONFIG_BOOTSTAGE_USER_COUNT, + BOOTSTAGE_ID_ALLOC, }; +/* + * Return the time since boot in microseconds, This is needed for bootstage + * and should be defined in CPU- or board-specific code. If undefined then + * millisecond resolution will be used (the standard get_timer()). + */ +ulong timer_get_boot_us(void); + +#ifndef CONFIG_SPL_BUILD /* * Board code can implement show_boot_progress() if needed. * @@ -178,10 +229,24 @@ enum bootstage_id { * has occurred. */ void show_boot_progress(int val); +#else +#define show_boot_progress(val) do {} while (0) +#endif -#ifdef CONFIG_BOOTSTAGE +#if defined(CONFIG_BOOTSTAGE) && !defined(CONFIG_SPL_BUILD) /* This is the full bootstage implementation */ +/** + * Add a new bootstage record + * + * @param id Bootstage ID to use (ignored if flags & BOOTSTAGEF_ALLOC) + * @param name Name of record, or NULL for none + * @param flags Flags (BOOTSTAGEF_...) + * @param mark Time to record in this record, in microseconds + */ +ulong bootstage_add_record(enum bootstage_id id, const char *name, + int flags, ulong mark); + /* * Mark a time stamp for the current boot stage. */ @@ -189,6 +254,66 @@ ulong bootstage_mark(enum bootstage_id id); ulong bootstage_error(enum bootstage_id id); +ulong bootstage_mark_name(enum bootstage_id id, const char *name); + +/** + * Mark the start of a bootstage activity. The end will be marked later with + * bootstage_accum() and at that point we accumulate the time taken. Calling + * this function turns the given id into a accumulator rather than and + * absolute mark in time. Accumulators record the total amount of time spent + * in an activty during boot. + * + * @param id Bootstage id to record this timestamp against + * @param name Textual name to display for this id in the report (maybe NULL) + * @return start timestamp in microseconds + */ +uint32_t bootstage_start(enum bootstage_id id, const char *name); + +/** + * Mark the end of a bootstage activity + * + * After previously marking the start of an activity with bootstage_start(), + * call this function to mark the end. You can call these functions in pairs + * as many times as you like. + * + * @param id Bootstage id to record this timestamp against + * @return time spent in this iteration of the activity (i.e. the time now + * less the start time recorded in the last bootstage_start() call + * with this id. + */ +uint32_t bootstage_accum(enum bootstage_id id); + +/* Print a report about boot time */ +void bootstage_report(void); + +/** + * Add bootstage information to the device tree + * + * @return 0 if ok, -ve on error + */ +int bootstage_fdt_add_report(void); + +/* + * Stash bootstage data into memory + * + * @param base Base address of memory buffer + * @param size Size of memory buffer + * @return 0 if stashed ok, -1 if out of space + */ +int bootstage_stash(void *base, int size); + +/** + * Read bootstage data from memory + * + * Bootstage data is read from memory and placed in the bootstage table + * in the user records. + * + * @param base Base address of memory buffer + * @param size Size of memory buffer (-1 if unknown) + * @return 0 if unstashed ok, -1 if bootstage info not found, or out of space + */ +int bootstage_unstash(void *base, int size); + #else /* * This is a dummy implementation which just calls show_boot_progress(), @@ -207,6 +332,20 @@ static inline ulong bootstage_error(enum bootstage_id id) return 0; } +static inline ulong bootstage_mark_name(enum bootstage_id id, const char *name) +{ + return 0; +} + +static inline int bootstage_stash(void *base, int size) +{ + return 0; /* Pretend to succeed */ +} + +static inline int bootstage_unstash(void *base, int size) +{ + return 0; /* Pretend to succeed */ +} #endif /* CONFIG_BOOTSTAGE */ #endif