static void VbTryLegacy(int allowed)
{
    if (!allowed)
        VBDEBUG(("VbBootDeveloper() - Legacy boot is disabled\n"));
    else if (0 != RollbackKernelLock(0))
        VBDEBUG(("Error locking kernel versions on legacy boot.\n"));
    else
        VbExLegacy();	/* will not return if successful */

    /* If legacy boot fails, beep and return to calling UI loop. */
    VbExBeep(120, 400);
    VbExSleepMs(120);
    VbExBeep(120, 400);
}
Example #2
0
/**
 * Caller should loop without extra delay until this returns false.
 */
int VbAudioLooping(VbAudioContext *audio)
{
	uint64_t now;
	uint16_t freq = audio->current_frequency;
	uint16_t msec = 0;
	int looping = 1;

#if defined(CONFIG_SANDBOX)
	return 0;
#endif

	now = VbExGetTimer();
	while (audio->next_note < audio->note_count &&
	       now >= audio->play_until) {
		freq = audio->music_notes[audio->next_note].frequency;
		msec = audio->music_notes[audio->next_note].msec;
		audio->play_until += VbMsecToTicks(msec);
		audio->next_note++;
	}

	if (now >= audio->play_until) {
		looping = 0;
		freq = 0;
	}

	/* Do action here. */
	if (audio->background_beep) {
		if (audio->current_frequency != freq) {
			VbExBeep(0, freq);
			audio->current_frequency = freq;
		}
	} else if (freq && msec) {
		VbExBeep(msec, freq);
		now = VbExGetTimer();
	}

	audio->last_time = now;
	return looping;
}
Example #3
0
/**
 * Initialization function. Returns context for processing dev-mode delay.
 */
VbAudioContext *VbAudioOpen(VbCommonParams *cparams)
{
	GoogleBinaryBlockHeader* gbb =
		(GoogleBinaryBlockHeader *)cparams->gbb_data;
	VbAudioContext *audio = &au;
	int use_short = 0;
	uint64_t a, b;

	/* Note: may need to allocate things here in future */

	/* Calibrate audio delay */
	a = VbExGetTimer();
	VbExSleepMs(10);
	b = VbExGetTimer();
	ticks_per_msec = (b - a) / 10ULL ;
	VBDEBUG(("VbAudioOpen() - ticks_per_msec is %llu\n", ticks_per_msec));

	/* Initialize */
	Memset(audio, 0, sizeof(*audio));
	audio->background_beep = 1;
	audio->play_until = b;                /* "zero" starts now */

	/* See if we have full background sound capability or not. */
	if (VBERROR_SUCCESS != VbExBeep(0,0)) {
		VBDEBUG(("VbAudioOpen() - VbExBeep() is limited\n"));
		audio->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(("VbAudioOpen() - using short dev screen delay\n"));
		use_short = 1;
	}

	VbGetDevMusicNotes(audio, use_short);
	VBDEBUG(("VbAudioOpen() - note count %d\n", audio->note_count));

	return audio;
}
Example #4
0
/**
 * Caller should call this prior to booting.
 */
void VbAudioClose(VbAudioContext *audio)
{
	VbExBeep(0,0);
	if (audio->free_notes_when_done)
		VbExFree(audio->music_notes);
}
static void beep_handler(uint32_t msec)
{
	VbExBeep(msec, 4000);
}
VbError_t VbBootRecovery(VbCommonParams *cparams, LoadKernelParams *p)
{
    VbSharedDataHeader *shared =
        (VbSharedDataHeader *)cparams->shared_data_blob;
    uint32_t retval;
    uint32_t key;
    int i;

    VBDEBUG(("VbBootRecovery() start\n"));

    /*
     * If the dev-mode switch is off and the user didn't press the recovery
     * button, require removal of all external media.
     */
    if (!(shared->flags & VBSD_BOOT_DEV_SWITCH_ON) &&
            !(shared->flags & VBSD_BOOT_REC_SWITCH_ON)) {
        VbDiskInfo *disk_info = NULL;
        uint32_t disk_count = 0;

        VBDEBUG(("VbBootRecovery() forcing device removal\n"));

        /* If no media is detected initially, delay and make one extra
         * attempt, in case devices appear later than expected. */
        if (VBERROR_SUCCESS != VbExDiskGetInfo(&disk_info, &disk_count,
                                               VB_DISK_FLAG_REMOVABLE))
            disk_count = 0;

        VbExDiskFreeInfo(disk_info, NULL);
        if (0 == disk_count)
            VbExSleepMs(REC_MEDIA_INIT_DELAY);

        while (1) {
            disk_info = NULL;
            disk_count = 0;
            if (VBERROR_SUCCESS !=
                    VbExDiskGetInfo(&disk_info, &disk_count,
                                    VB_DISK_FLAG_REMOVABLE))
                disk_count = 0;

            VbExDiskFreeInfo(disk_info, NULL);

            if (0 == disk_count) {
                VbDisplayScreen(cparams, VB_SCREEN_BLANK,
                                0, &vnc);
                break;
            }

            VBDEBUG(("VbBootRecovery() "
                     "waiting for %d disks to be removed\n",
                     (int)disk_count));

            VbDisplayScreen(cparams, VB_SCREEN_RECOVERY_REMOVE,
                            0, &vnc);

            /*
             * Scan keyboard more frequently than media, since x86
             * platforms don't like to scan USB too rapidly.
             */
            for (i = 0; i < REC_DISK_DELAY; i += REC_KEY_DELAY) {
                VbCheckDisplayKey(cparams, VbExKeyboardRead(),
                                  &vnc);
                if (VbWantShutdown(cparams->gbb->flags))
                    return VBERROR_SHUTDOWN_REQUESTED;
                VbExSleepMs(REC_KEY_DELAY);
            }
        }
    }

    /* Loop and wait for a recovery image */
    while (1) {
        VBDEBUG(("VbBootRecovery() attempting to load kernel2\n"));
        retval = VbTryLoadKernel(cparams, p, VB_DISK_FLAG_REMOVABLE);

        /*
         * Clear recovery requests from failed kernel loading, since
         * we're already in recovery mode.  Do this now, so that
         * powering off after inserting an invalid disk doesn't leave
         * us stuck in recovery mode.
         */
        VbSetRecoveryRequest(VBNV_RECOVERY_NOT_REQUESTED);

        if (VBERROR_SUCCESS == retval)
            break; /* Found a recovery kernel */

        VbDisplayScreen(cparams, VBERROR_NO_DISK_FOUND == retval ?
                        VB_SCREEN_RECOVERY_INSERT :
                        VB_SCREEN_RECOVERY_NO_GOOD,
                        0, &vnc);

        /*
         * Scan keyboard more frequently than media, since x86
         * platforms don't like to scan USB too rapidly.
         */
        for (i = 0; i < REC_DISK_DELAY; i += REC_KEY_DELAY) {
            key = VbExKeyboardRead();
            /*
             * We might want to enter dev-mode from the Insert
             * screen if all of the following are true:
             *   - user pressed Ctrl-D
             *   - we can honor the virtual dev switch
             *   - not already in dev mode
             *   - user forced recovery mode
             *   - EC isn't pwned
             */
            if (key == 0x04 &&
                    shared->flags & VBSD_HONOR_VIRT_DEV_SWITCH &&
                    !(shared->flags & VBSD_BOOT_DEV_SWITCH_ON) &&
                    (shared->flags & VBSD_BOOT_REC_SWITCH_ON) &&
                    VbExTrustEC(0)) {
                if (!(shared->flags &
                        VBSD_BOOT_REC_SWITCH_VIRTUAL) &&
                        VbExGetSwitches(
                            VB_INIT_FLAG_REC_BUTTON_PRESSED)) {
                    /*
                     * Is the recovery button stuck?  In
                     * any case we don't like this.  Beep
                     * and ignore.
                     */
                    VBDEBUG(("%s() - ^D but rec switch "
                             "is pressed\n", __func__));
                    VbExBeep(120, 400);
                    continue;
                }

                /* Ask the user to confirm entering dev-mode */
                VbDisplayScreen(cparams,
                                VB_SCREEN_RECOVERY_TO_DEV,
                                0, &vnc);
                /* SPACE means no... */
                uint32_t vbc_flags =
                    VB_CONFIRM_SPACE_MEANS_NO |
                    VB_CONFIRM_MUST_TRUST_KEYBOARD;
                switch (VbUserConfirms(cparams, vbc_flags)) {
                case 1:
                    VBDEBUG(("%s() Enabling dev-mode...\n",
                             __func__));
                    if (TPM_SUCCESS != SetVirtualDevMode(1))
                        return VBERROR_TPM_SET_BOOT_MODE_STATE;
                    VBDEBUG(("%s() Reboot so it will take "
                             "effect\n", __func__));
                    if (VbExGetSwitches
                            (VB_INIT_FLAG_ALLOW_USB_BOOT))
                        VbAllowUsbBoot();
                    return VBERROR_TPM_REBOOT_REQUIRED;
                case -1:
                    VBDEBUG(("%s() - Shutdown requested\n",
                             __func__));
                    return VBERROR_SHUTDOWN_REQUESTED;
                default: /* zero, actually */
                    VBDEBUG(("%s() - Not enabling "
                             "dev-mode\n", __func__));
                    /*
                     * Jump out of the outer loop to
                     * refresh the display quickly.
                     */
                    i = 4;
                    break;
                }
            } else {
                VbCheckDisplayKey(cparams, key, &vnc);
            }
            if (VbWantShutdown(cparams->gbb->flags))
                return VBERROR_SHUTDOWN_REQUESTED;
            VbExSleepMs(REC_KEY_DELAY);
        }
    }

    return VBERROR_SUCCESS;
}
VbError_t VbBootDeveloper(VbCommonParams *cparams, LoadKernelParams *p)
{
    GoogleBinaryBlockHeader *gbb = cparams->gbb;
    VbSharedDataHeader *shared =
        (VbSharedDataHeader *)cparams->shared_data_blob;
    uint32_t allow_usb = 0, allow_legacy = 0, ctrl_d_pressed = 0;
    VbAudioContext *audio = 0;

    VBDEBUG(("Entering %s()\n", __func__));

    /* Check if USB booting is allowed */
    VbNvGet(&vnc, VBNV_DEV_BOOT_USB, &allow_usb);
    VbNvGet(&vnc, VBNV_DEV_BOOT_LEGACY, &allow_legacy);

    /* Handle GBB flag override */
    if (gbb->flags & GBB_FLAG_FORCE_DEV_BOOT_USB)
        allow_usb = 1;
    if (gbb->flags & GBB_FLAG_FORCE_DEV_BOOT_LEGACY)
        allow_legacy = 1;

    /* Show the dev mode warning screen */
    VbDisplayScreen(cparams, VB_SCREEN_DEVELOPER_WARNING, 0, &vnc);

    /* Get audio/delay context */
    audio = VbAudioOpen(cparams);

    /* We'll loop until we finish the delay or are interrupted */
    do {
        uint32_t key;

        if (VbWantShutdown(gbb->flags)) {
            VBDEBUG(("VbBootDeveloper() - shutdown requested!\n"));
            VbAudioClose(audio);
            return VBERROR_SHUTDOWN_REQUESTED;
        }

        key = VbExKeyboardRead();
        switch (key) {
        case 0:
            /* nothing pressed */
            break;
        case '\r':
            /* Only disable virtual dev switch if allowed by GBB */
            if (!(gbb->flags & GBB_FLAG_ENTER_TRIGGERS_TONORM))
                break;
        case ' ':
            /* See if we should disable virtual dev-mode switch. */
            VBDEBUG(("%s shared->flags=0x%x\n",
                     __func__, shared->flags));
            if (shared->flags & VBSD_HONOR_VIRT_DEV_SWITCH &&
                    shared->flags & VBSD_BOOT_DEV_SWITCH_ON) {
                /* Stop the countdown while we go ask... */
                VbAudioClose(audio);
                if (gbb->flags & GBB_FLAG_FORCE_DEV_SWITCH_ON) {
                    /*
                     * TONORM won't work (only for
                     * non-shipping devices).
                     */
                    VBDEBUG(("%s() - TONORM rejected by "
                             "FORCE_DEV_SWITCH_ON\n",
                             __func__));
                    VbExDisplayDebugInfo(
                        "WARNING: TONORM prohibited by "
                        "GBB FORCE_DEV_SWITCH_ON.\n\n");
                    VbExBeep(120, 400);
                    break;
                }
                VbDisplayScreen(cparams,
                                VB_SCREEN_DEVELOPER_TO_NORM,
                                0, &vnc);
                /* Ignore space in VbUserConfirms()... */
                switch (VbUserConfirms(cparams, 0)) {
                case 1:
                    VBDEBUG(("%s() - leaving dev-mode.\n",
                             __func__));
                    VbNvSet(&vnc, VBNV_DISABLE_DEV_REQUEST,
                            1);
                    VbDisplayScreen(
                        cparams,
                        VB_SCREEN_TO_NORM_CONFIRMED,
                        0, &vnc);
                    VbExSleepMs(5000);
                    return VBERROR_TPM_REBOOT_REQUIRED;
                case -1:
                    VBDEBUG(("%s() - shutdown requested\n",
                             __func__));
                    return VBERROR_SHUTDOWN_REQUESTED;
                default:
                    /* Stay in dev-mode */
                    VBDEBUG(("%s() - stay in dev-mode\n",
                             __func__));
                    VbDisplayScreen(
                        cparams,
                        VB_SCREEN_DEVELOPER_WARNING,
                        0, &vnc);
                    /* Start new countdown */
                    audio = VbAudioOpen(cparams);
                }
            } else {
                /*
                 * No virtual dev-mode switch, so go directly
                 * to recovery mode.
                 */
                VBDEBUG(("%s() - going to recovery\n",
                         __func__));
                VbSetRecoveryRequest(
                    VBNV_RECOVERY_RW_DEV_SCREEN);
                VbAudioClose(audio);
                return VBERROR_LOAD_KERNEL_RECOVERY;
            }
            break;
        case 0x04:
            /* Ctrl+D = dismiss warning; advance to timeout */
            VBDEBUG(("VbBootDeveloper() - "
                     "user pressed Ctrl+D; skip delay\n"));
            ctrl_d_pressed = 1;
            goto fallout;
            break;
        case 0x0c:
            VBDEBUG(("VbBootDeveloper() - "
                     "user pressed Ctrl+L; Try legacy boot\n"));
            VbTryLegacy(allow_legacy);
            break;

        case VB_KEY_CTRL_ENTER:
        /*
         * The Ctrl-Enter is special for Lumpy test purpose;
         * fall through to Ctrl+U handler.
         */
        case 0x15:
            /* Ctrl+U = try USB boot, or beep if failure */
            VBDEBUG(("VbBootDeveloper() - "
                     "user pressed Ctrl+U; try USB\n"));
            if (!allow_usb) {
                VBDEBUG(("VbBootDeveloper() - "
                         "USB booting is disabled\n"));
                VbExDisplayDebugInfo(
                    "WARNING: Booting from external media "
                    "(USB/SD) has not been enabled. Refer "
                    "to the developer-mode documentation "
                    "for details.\n");
                VbExBeep(120, 400);
                VbExSleepMs(120);
                VbExBeep(120, 400);
            } else {
                /*
                 * Clear the screen to show we get the Ctrl+U
                 * key press.
                 */
                VbDisplayScreen(cparams, VB_SCREEN_BLANK, 0,
                                &vnc);
                if (VBERROR_SUCCESS ==
                        VbTryLoadKernel(cparams, p,
                                        VB_DISK_FLAG_REMOVABLE)) {
                    VBDEBUG(("VbBootDeveloper() - "
                             "booting USB\n"));
                    VbAudioClose(audio);
                    return VBERROR_SUCCESS;
                } else {
                    VBDEBUG(("VbBootDeveloper() - "
                             "no kernel found on USB\n"));
                    VbExBeep(250, 200);
                    VbExSleepMs(120);
                    /*
                     * Clear recovery requests from failed
                     * kernel loading, so that powering off
                     * at this point doesn't put us into
                     * recovery mode.
                     */
                    VbSetRecoveryRequest(
                        VBNV_RECOVERY_NOT_REQUESTED);
                    /* Show dev mode warning screen again */
                    VbDisplayScreen(
                        cparams,
                        VB_SCREEN_DEVELOPER_WARNING,
                        0, &vnc);
                }
            }
            break;
        default:
            VBDEBUG(("VbBootDeveloper() - pressed key %d\n", key));
            VbCheckDisplayKey(cparams, key, &vnc);
            break;
        }
    } while(VbAudioLooping(audio));

fallout:

    /* If defaulting to legacy boot, try that unless Ctrl+D was pressed */
    if ((gbb->flags & GBB_FLAG_DEFAULT_DEV_BOOT_LEGACY) &&
            !ctrl_d_pressed) {
        VBDEBUG(("VbBootDeveloper() - defaulting to legacy\n"));
        VbTryLegacy(allow_legacy);
    }

    /* Timeout or Ctrl+D; attempt loading from fixed disk */
    VBDEBUG(("VbBootDeveloper() - trying fixed disk\n"));
    VbAudioClose(audio);
    return VbTryLoadKernel(cparams, p, VB_DISK_FLAG_FIXED);
}
int VbUserConfirms(VbCommonParams *cparams, uint32_t confirm_flags)
{
    VbSharedDataHeader *shared =
        (VbSharedDataHeader *)cparams->shared_data_blob;
    uint32_t key;
    uint32_t key_flags;
    uint32_t button;
    int rec_button_was_pressed = 0;

    VBDEBUG(("Entering %s(0x%x)\n", __func__, confirm_flags));

    /* Await further instructions */
    while (1) {
        if (VbWantShutdown(cparams->gbb->flags))
            return -1;
        key = VbExKeyboardReadWithFlags(&key_flags);
        button = VbExGetSwitches(VB_INIT_FLAG_REC_BUTTON_PRESSED);
        switch (key) {
        case '\r':
            /* If we require a trusted keyboard for confirmation,
             * but the keyboard may be faked (for instance, a USB
             * device), beep and keep waiting.
             */
            if (confirm_flags & VB_CONFIRM_MUST_TRUST_KEYBOARD &&
                    !(key_flags & VB_KEY_FLAG_TRUSTED_KEYBOARD)) {
                VbExBeep(120, 400);
                break;
            }

            VBDEBUG(("%s() - Yes (1)\n", __func__));
            return 1;
            break;
        case ' ':
            VBDEBUG(("%s() - Space (%d)\n", __func__,
                     confirm_flags & VB_CONFIRM_SPACE_MEANS_NO));
            if (confirm_flags & VB_CONFIRM_SPACE_MEANS_NO)
                return 0;
            break;
        case 0x1b:
            VBDEBUG(("%s() - No (0)\n", __func__));
            return 0;
            break;
        default:
            /* If the recovery button is physical, and is pressed,
             * this is also a YES, but must wait for release.
             */
            if (!(shared->flags & VBSD_BOOT_REC_SWITCH_VIRTUAL)) {
                if (button) {
                    VBDEBUG(("%s() - Rec button pressed\n",
                             __func__));
                    rec_button_was_pressed = 1;
                } else if (rec_button_was_pressed) {
                    VBDEBUG(("%s() - Rec button (1)\n",
                             __func__));
                    return 1;
                }
            }
            VbCheckDisplayKey(cparams, key, &vnc);
        }
        VbExSleepMs(CONFIRM_KEY_DELAY);
    }

    /* Not reached, but compiler will complain without it */
    return -1;
}