X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=include%2Fbootstage.h;h=3b2216b8a8c8316df3dec35153947087623a905c;hb=b278c4095b59c40ff512c5433b735b000e547554;hp=408356c8631f8161d87d22cff887e726d31db78b;hpb=5dc887164e031dbd6544031eb4dcb8e5c4ddeb13;p=u-boot diff --git a/include/bootstage.h b/include/bootstage.h index 408356c863..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 @@ -58,9 +69,159 @@ enum bootstage_id { BOOTSTAGE_ID_BOOT_OS_RETURNED, /* Tried to boot OS, but it returned */ BOOTSTAGE_ID_CHECK_RAMDISK = 9, /* Checking ram disk */ + BOOTSTAGE_ID_RD_MAGIC, /* Checking ram disk magic */ + BOOTSTAGE_ID_RD_HDR_CHECKSUM, /* Checking ram disk heder checksum */ + BOOTSTAGE_ID_RD_CHECKSUM, /* Checking ram disk checksum */ + BOOTSTAGE_ID_COPY_RAMDISK = 12, /* Copying ram disk into place */ + BOOTSTAGE_ID_RAMDISK, /* Checking for valid ramdisk */ + BOOTSTAGE_ID_NO_RAMDISK, /* No ram disk found (not an error) */ + BOOTSTAGE_ID_RUN_OS = 15, /* Exiting U-Boot, entering OS */ + + BOOTSTAGE_ID_NEED_RESET = 30, + BOOTSTAGE_ID_POST_FAIL, /* Post failure */ + BOOTSTAGE_ID_POST_FAIL_R, /* Post failure reported after reloc */ + + /* + * This set is reported ony by x86, and the meaning is different. In + * this case we are reporting completion of a particular stage. + * This should probably change in he x86 code (which doesn't report + * errors in any case), but discussion this can perhaps wait until we + * have a generic board implementation. + */ + BOOTSTAGE_ID_BOARD_INIT_R, /* We have relocated */ + BOOTSTAGE_ID_BOARD_GLOBAL_DATA, /* Global data is set up */ + + BOOTSTAGE_ID_BOARD_INIT_SEQ, /* We completed the init sequence */ + BOOTSTAGE_ID_BOARD_FLASH, /* We have configured flash banks */ + BOOTSTAGE_ID_BOARD_FLASH_37, /* In case you didn't hear... */ + BOOTSTAGE_ID_BOARD_ENV, /* Environment is relocated & ready */ + BOOTSTAGE_ID_BOARD_PCI, /* PCI is up */ + + BOOTSTAGE_ID_BOARD_INTERRUPTS, /* Exceptions / interrupts ready */ + BOOTSTAGE_ID_BOARD_DONE, /* Board init done, off to main loop */ + /* ^^^ here ends the x86 sequence */ + + /* Boot stages related to loading a kernel from an IDE device */ + BOOTSTAGE_ID_IDE_START = 41, + BOOTSTAGE_ID_IDE_ADDR, + BOOTSTAGE_ID_IDE_BOOT_DEVICE, + BOOTSTAGE_ID_IDE_TYPE, + + BOOTSTAGE_ID_IDE_PART, + BOOTSTAGE_ID_IDE_PART_INFO, + BOOTSTAGE_ID_IDE_PART_TYPE, + BOOTSTAGE_ID_IDE_PART_READ, + BOOTSTAGE_ID_IDE_FORMAT, + + BOOTSTAGE_ID_IDE_CHECKSUM, /* 50 */ + BOOTSTAGE_ID_IDE_READ, + + /* Boot stages related to loading a kernel from an NAND device */ + BOOTSTAGE_ID_NAND_PART, + BOOTSTAGE_ID_NAND_SUFFIX, + BOOTSTAGE_ID_NAND_BOOT_DEVICE, + BOOTSTAGE_ID_NAND_HDR_READ = 55, + BOOTSTAGE_ID_NAND_AVAILABLE = 55, + BOOTSTAGE_ID_NAND_TYPE = 57, + BOOTSTAGE_ID_NAND_READ, + + /* Boot stages related to loading a kernel from an network device */ + BOOTSTAGE_ID_NET_CHECKSUM = 60, + BOOTSTAGE_ID_NET_ETH_START = 64, + BOOTSTAGE_ID_NET_ETH_INIT, + + BOOTSTAGE_ID_NET_START = 80, + BOOTSTAGE_ID_NET_NETLOOP_OK, + BOOTSTAGE_ID_NET_LOADED, + BOOTSTAGE_ID_NET_DONE_ERR, + BOOTSTAGE_ID_NET_DONE, + + /* + * Boot stages related to loading a FIT image. Some of these are a + * bit wonky. + */ + BOOTSTAGE_ID_FIT_FORMAT = 100, + BOOTSTAGE_ID_FIT_NO_UNIT_NAME, + BOOTSTAGE_ID_FIT_UNIT_NAME, + BOOTSTAGE_ID_FIT_CONFIG, + BOOTSTAGE_ID_FIT_CHECK_SUBIMAGE, + BOOTSTAGE_ID_FIT_CHECK_HASH = 104, + + BOOTSTAGE_ID_FIT_CHECK_ARCH, + BOOTSTAGE_ID_FIT_CHECK_KERNEL, + BOOTSTAGE_ID_FIT_CHECKED, + + BOOTSTAGE_ID_FIT_KERNEL_INFO_ERR = 107, + BOOTSTAGE_ID_FIT_KERNEL_INFO, + BOOTSTAGE_ID_FIT_TYPE, + + BOOTSTAGE_ID_FIT_COMPRESSION, + BOOTSTAGE_ID_FIT_OS, + BOOTSTAGE_ID_FIT_LOADADDR, + BOOTSTAGE_ID_OVERWRITTEN, + + BOOTSTAGE_ID_FIT_RD_FORMAT = 120, + BOOTSTAGE_ID_FIT_RD_FORMAT_OK, + BOOTSTAGE_ID_FIT_RD_NO_UNIT_NAME, + BOOTSTAGE_ID_FIT_RD_UNIT_NAME, + BOOTSTAGE_ID_FIT_RD_SUBNODE, + + BOOTSTAGE_ID_FIT_RD_CHECK, + BOOTSTAGE_ID_FIT_RD_HASH = 125, + BOOTSTAGE_ID_FIT_RD_CHECK_ALL, + BOOTSTAGE_ID_FIT_RD_GET_DATA, + BOOTSTAGE_ID_FIT_RD_CHECK_ALL_OK = 127, + BOOTSTAGE_ID_FIT_RD_GET_DATA_OK, + BOOTSTAGE_ID_FIT_RD_LOAD, + + BOOTSTAGE_ID_IDE_FIT_READ = 140, + BOOTSTAGE_ID_IDE_FIT_READ_OK, + + 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. * @@ -68,9 +229,123 @@ enum bootstage_id { * has occurred. */ void show_boot_progress(int val); -static inline void show_boot_error(int val) +#else +#define show_boot_progress(val) do {} while (0) +#endif + +#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. + */ +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(), + * and won't even do that unless CONFIG_SHOW_BOOT_PROGRESS is defined + */ + +static inline ulong bootstage_mark(enum bootstage_id id) +{ + show_boot_progress(id); + return 0; +} + +static inline ulong bootstage_error(enum bootstage_id id) +{ + show_boot_progress(-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) { - show_boot_progress(-val); + return 0; /* Pretend to succeed */ } +#endif /* CONFIG_BOOTSTAGE */ #endif