diff options
author | Bill Richardson <wfrichar@chromium.org> | 2011-09-23 15:14:49 -0700 |
---|---|---|
committer | Bill Richardson <wfrichar@chromium.org> | 2011-09-26 13:25:26 -0700 |
commit | 25a3dbc83c3d2e9745cac7f466c541ee6215af0e (patch) | |
tree | 62f31603db80bbfd9414471f7e180672fbb257ff | |
parent | 4313fba2fb928f662a63b7566f235291dc1455f7 (diff) | |
download | vboot-25a3dbc83c3d2e9745cac7f466c541ee6215af0e.tar.gz |
Make startup delay and noises simpler to change.
BUG=none
TEST=manual
Booted in dev-mode. All noises and delays are unchanged (2 second delay when
gbb.flags is 1, 30-second with beeps at 20 seconds when gbb.flags is 0).
Change-Id: I816e57c4f8f6025299851b3d42b4a350f9925994
Reviewed-on: http://gerrit.chromium.org/gerrit/8240
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Tested-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r-- | firmware/lib/include/vboot_display.h | 13 | ||||
-rw-r--r-- | firmware/lib/vboot_api_kernel.c | 123 |
2 files changed, 110 insertions, 26 deletions
diff --git a/firmware/lib/include/vboot_display.h b/firmware/lib/include/vboot_display.h index 8dc22606..aace9708 100644 --- a/firmware/lib/include/vboot_display.h +++ b/firmware/lib/include/vboot_display.h @@ -21,5 +21,18 @@ VbError_t VbCheckDisplayKey(VbCommonParams* cparams, uint32_t key, void VbExEasterEgg(VbCommonParams* cparams, VbNvContext *vncptr); +typedef struct VbDevMusicNote { + uint16_t msec; + uint16_t frequency; +} __attribute__((packed)) VbDevMusicNote; + +typedef struct VbDevMusic { + uint8_t sig[4]; /* "$SND" */ + uint32_t checksum; /* crc32 over count & all notes */ + uint32_t count; /* number of notes */ + VbDevMusicNote notes[1]; /* gcc allows [0], MSVC doesn't */ + /* more VbDevMusicNotes follow immediately */ +} __attribute__((packed)) VbDevMusic; + #endif /* VBOOT_REFERENCE_VBOOT_DISPLAY_H_ */ diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c index ed288103..fa3a9372 100644 --- a/firmware/lib/vboot_api_kernel.c +++ b/firmware/lib/vboot_api_kernel.c @@ -105,77 +105,110 @@ VbError_t VbBootNormal(VbCommonParams* cparams, LoadKernelParams* p) { return VbTryLoadKernel(cparams, p, VB_DISK_FLAG_FIXED); } +#define DEV_LOOP_TIME 10 /* Minimum note granularity in msecs */ + +static uint16_t VbMsecToLoops(uint16_t msec) { + return (DEV_LOOP_TIME / 2 + msec) / DEV_LOOP_TIME; +} + +static VbDevMusicNote default_notes[] = { {20000, 0}, /* 20 seconds */ + {250, 400}, /* two beeps */ + {250, 0}, + {250, 400}, + {9250, 0} }; /* total 30 seconds */ + +static VbDevMusicNote short_notes[] = { {2000, 0} }; /* two seconds */ + +/* Return a valid set of note events. */ +static VbDevMusicNote* VbGetDevMusicNotes(uint32_t *count, int use_short) { + + if (use_short) { + *count = sizeof(short_notes) / sizeof(short_notes[0]); + return short_notes; + } + + *count = sizeof(default_notes) / sizeof(default_notes[0]); + return default_notes; +} -/* Developer mode delays. All must be multiples of DEV_DELAY_INCREMENT */ -#define DEV_DELAY_INCREMENT 250 /* Delay each loop, in msec */ -#define DEV_DELAY_BEEP1 20000 /* Beep for first time at this time */ -#define DEV_DELAY_BEEP2 20500 /* Beep for second time at this time */ -#define DEV_DELAY_TIMEOUT 30000 /* Give up at this time */ -#define DEV_DELAY_TIMEOUT_SHORT 2000 /* Give up at this time (short delay) */ /* Handle a developer-mode boot */ VbError_t VbBootDeveloper(VbCommonParams* cparams, LoadKernelParams* p) { GoogleBinaryBlockHeader* gbb = (GoogleBinaryBlockHeader*)cparams->gbb_data; - uint32_t delay_timeout = DEV_DELAY_TIMEOUT; - uint32_t delay_time = 0; uint32_t allow_usb = 0; + uint32_t note_count = 0; + VbDevMusicNote* music_notes = 0; + uint32_t current_note = 0; + uint32_t current_note_loops = 0; + int background_beep = 1; /* Check if USB booting is allowed */ VbNvGet(&vnc, VBNV_DEV_BOOT_USB, &allow_usb); - /* Use a short developer screen delay if indicated by GBB flags */ + /* Show the dev mode warning screen */ + VbDisplayScreen(cparams, VB_SCREEN_DEVELOPER_WARNING, 0, &vnc); + + /* See if we have full background sound capability or not. */ + if (VBERROR_SUCCESS != VbExBeep(0,0)) { + VBDEBUG(("VbBootDeveloper: VbExBeep() is limited\n")); + background_beep = 0; + } + + /* Prepare to generate audio/delay event. Use a short developer screen delay + * if indicated by GBB flags. + */ if (gbb->major_version == GBB_MAJOR_VER && gbb->minor_version >= 1 && (gbb->flags & GBB_FLAG_DEV_SCREEN_SHORT_DELAY)) { VBDEBUG(("VbBootDeveloper() - using short developer screen delay\n")); - delay_timeout = DEV_DELAY_TIMEOUT_SHORT; + music_notes = VbGetDevMusicNotes(¬e_count, 1); + } else { + music_notes = VbGetDevMusicNotes(¬e_count, 0); } - /* Show the dev mode warning screen */ - VbDisplayScreen(cparams, VB_SCREEN_DEVELOPER_WARNING, 0, &vnc); + VBDEBUG(("VbBootDeveloper() - note count %d\n", note_count)); - /* Loop for dev mode warning delay */ - for (delay_time = 0; delay_time < delay_timeout; - delay_time += DEV_DELAY_INCREMENT) { + /* We'll loop until we finish the notes or are interrupted */ + while(1) { uint32_t key; if (VbExIsShutdownRequested()) return VBERROR_SHUTDOWN_REQUESTED; - if (DEV_DELAY_BEEP1 == delay_time || DEV_DELAY_BEEP2 == delay_time) - VbExBeep(DEV_DELAY_INCREMENT, 400); - else - VbExSleepMs(DEV_DELAY_INCREMENT); - - /* Handle keypress */ key = VbExKeyboardRead(); switch (key) { + case 0: + /* nothing pressed */ + break; case '\r': case ' ': case 0x1B: /* Enter, space, or ESC = reboot to recovery */ VBDEBUG(("VbBootDeveloper() - user pressed ENTER/SPACE/ESC\n")); + VbExBeep(0, 0); /* sound off */ VbSetRecoveryRequest(VBNV_RECOVERY_RW_DEV_SCREEN); return 1; case 0x04: /* Ctrl+D = dismiss warning; advance to timeout */ VBDEBUG(("VbBootDeveloper() - user pressed Ctrl+D; skip delay\n")); - delay_time = DEV_DELAY_TIMEOUT; + goto fallout; break; case 0x15: /* Ctrl+U = try USB boot, or beep if failure */ VBDEBUG(("VbBootDeveloper() - user pressed Ctrl+U; try USB\n")); + VbExBeep(0, 0); /* sound off */ if (!allow_usb) { VBDEBUG(("VbBootDeveloper() - USB booting is disabled\n")); - VbExBeep(DEV_DELAY_INCREMENT / 2, 400); - VbExSleepMs(DEV_DELAY_INCREMENT / 2); - VbExBeep(DEV_DELAY_INCREMENT / 2, 400); + VbExBeep(120, 400); + VbExSleepMs(120); + VbExBeep(120, 400); } else if (VBERROR_SUCCESS == VbTryLoadKernel(cparams, p, VB_DISK_FLAG_REMOVABLE)) { VBDEBUG(("VbBootDeveloper() - booting USB\n")); return VBERROR_SUCCESS; } else { VBDEBUG(("VbBootDeveloper() - no kernel found on USB\n")); - VbExBeep(DEV_DELAY_INCREMENT, 400); + VbExBeep(250, 200); + VbExBeep(100, 0); /* Clear recovery requests from failed kernel loading, so * that powering off at this point doesn't put us into * recovery mode. */ @@ -186,9 +219,47 @@ VbError_t VbBootDeveloper(VbCommonParams* cparams, LoadKernelParams* p) { VbCheckDisplayKey(cparams, key, &vnc); break; } + + /* Time to play a note? */ + if (!current_note_loops) { + VBDEBUG(("VbBootDeveloper() - current_note is %d\n", current_note)); + + /* Sorry, out of notes */ + if (current_note >= note_count) + break; + + /* For how many loops do we hold this note? */ + current_note_loops = VbMsecToLoops(music_notes[current_note].msec); + VBDEBUG(("VbBootDeveloper() - new current_note_loops == %d\n", + current_note_loops)); + + if (background_beep) { + + /* start (or stop) the sound */ + VbExBeep(0, music_notes[current_note].frequency); + + } else if (music_notes[current_note].frequency) { + + /* the sound will block, so don't loop repeatedly */ + current_note_loops = 1; + VbExBeep(music_notes[current_note].msec, + music_notes[current_note].frequency); + } + + current_note++; + } + + /* Wait a bit. Yes, one extra loop sometimes, but it's only 10msec */ + VbExSleepMs(DEV_LOOP_TIME); + + /* That's one... */ + if (current_note_loops) + current_note_loops--; } +fallout: /* Timeout or Ctrl+D; attempt loading from fixed disk */ + VbExBeep(0, 0); /* sound off */ VBDEBUG(("VbBootDeveloper() - trying fixed disk\n")); return VbTryLoadKernel(cparams, p, VB_DISK_FLAG_FIXED); } |