Example #1
0
/**
 * @brief Bootloader "C" entry point
 *
 * @param none
 *
 * @returns Nothing. Will launch/restart image if successful, halt if not.
 */
void bootrom_main(void) {
    chip_init();

    dbginit();

    init_last_error();

    dbgprint("gbboot Server\n");

    chip_wait_for_link_up();

    chip_unipro_attr_write(DME_ARA_BOOT_CONTROL,
                           FORCE_UNIPRO_BOOT,
                           0,
                           ATTR_PEER);

    while(1) {
        server_loop();
    }
}
Example #2
0
/**
 * @brief Stage 2 loader "C" entry point. Started from Stage 1
 * bootloader. Primary function is to load, validate, and start
 * executing a stage 3 image. Also will (when fully implemented)
 * perform startup negotiations with AP, cryptographic initialzations
 * and tests, module authentication, flash update, and other housekeeping.
 * Image load and validation are essntially identical to the crresponding
 * functions in stage 1, although different keys are used for signature
 * validation.
 *
 * @param none
 *
 * @returns Nothing. Will launch/restart image if successful, halt if not.
 */
void bootrom_main(void) {
    int rc;
    /* TA-20 R/W data in bufRAM */
    uint32_t    boot_status = INIT_STATUS_OPERATING;
    bool        boot_from_spi = true;
    bool        fallback_boot_unipro = false;
    uint32_t    is_secure_image;
    secondstage_cfgdata *cfgdata;

    chip_init();

    dbginit();

    /* Ensure that we start each boot with an assumption of success */
    init_last_error();

    crypto_init();

    dbgprint("\nHello world from s2fw\n");

    if (!get_2ndstage_cfgdata(&cfgdata)) {
        dbgprint("found valid config data\n");
        if (cfgdata->use_fake_ims) {
            /**
             * We don't really need to handle all the efuses as boot ROM
             * does. But we do want to update the EPUID according to the
             * fake IMS. And the rest of the efuse handling do no harm
             * anyway.
             */
            if (efuse_init() != 0) {
                halt_and_catch_fire(boot_status);
            }
        }
    }

    uint8_t ims[TSB_ISAA_NUM_IMS_BYTES];
    tsb_get_ims(ims, TSB_ISAA_NUM_IMS_BYTES);
    key_generation(ims);

    chip_unipro_init();

    boot_control(&boot_from_spi);

    /* Advertise our boot status */
    chip_advertise_boot_status(boot_status);
    /* Advertise our initialization type */
    rc = chip_advertise_boot_type();
    if (rc) {
        halt_and_catch_fire(boot_status);
    }

    if (boot_from_spi) {
        dbgprint("Boot from SPIROM\n");

        spi_ops.init();

        /**
         * Call locate_ffff_element_on_storage to locate next stage FW.
         * Do not care about the image length here so pass NULL.
         */
        if (locate_ffff_element_on_storage(&spi_ops,
                                           FFFF_ELEMENT_STAGE_3_FW,
                                           NULL) == 0) {
            boot_status = INIT_STATUS_SPI_BOOT_STARTED;
            chip_advertise_boot_status(boot_status);
            if (!load_tftf_image(&spi_ops, &is_secure_image)) {
                spi_ops.finish(true, is_secure_image);
                if (is_secure_image) {
                    boot_status = INIT_STATUS_TRUSTED_SPI_FLASH_BOOT_FINISHED;
                    dbgprintx32("SPI Trusted: (",
                                merge_errno_with_boot_status(boot_status),
                                ")\n");
                } else {
                    boot_status = INIT_STATUS_UNTRUSTED_SPI_FLASH_BOOT_FINISHED;
                    dbgprintx32("SPI Untrusted: (",
                                merge_errno_with_boot_status(boot_status),
                                ")\n");

                    /*
                     *  Disable IMS, CMS access before starting untrusted image.
                     *  NB. JTAG continues to be not enabled at this point
                     */
                    efuse_rig_for_untrusted();
                }

                /* Log that we're starting the boot-from-SPIROM */
                chip_advertise_boot_status(merge_errno_with_boot_status(boot_status));
                /* TA-16 jump to SPI code (BOOTRET_o = 0 && SPIBOOT_N = 0) */
                jump_to_image();
            }
        }
        spi_ops.finish(false, false);

        /* Fallback to UniPro boot */
        boot_from_spi = false;
        fallback_boot_unipro = true;

        chip_clear_image_loading_ram();
    } else {
        /* (Not boot-from-spi, */
        fallback_boot_unipro = false;
    }

    if (greybus_init()) {
        set_last_error(BRE_BOU_GBCTRL_CPORT);
        halt_and_catch_fire(boot_status);
    }

    /* Boot-Over-UniPro...
     * We get here if directed to do so by the bootselector, or as a fallback
     * for a failed SPIROM boot.
     */
    if (!boot_from_spi) {
       /* Boot over Unipro */
        if (fallback_boot_unipro) {
            boot_status = merge_errno_with_boot_status(
                            INIT_STATUS_FALLLBACK_UNIPRO_BOOT_STARTED);
            dbgprintx32("Spi boot failed (", boot_status, "), ");
        } else {
            boot_status = INIT_STATUS_UNIPRO_BOOT_STARTED;
        }
        chip_advertise_boot_status(boot_status);
        dbgprintx32("Boot over UniPro (",
                    merge_errno_with_boot_status(boot_status),
                    ")\n");
        advertise_ready();
#if RUN_SPI_TEST
        spi_gb_init();
        dbgprint("Running in loop to perform as SPI over Greybus\n");
        while (1) {
            if (greybus_loop()) {
                dbgprint("ERROR in greuybus loop\n");
                halt_and_catch_fire(boot_status);
            }
        }
#endif
        dbgprint("Ready-poked; download-ready\n");
        if (greybus_ops.init() != 0) {
            halt_and_catch_fire(boot_status);
        }
        if (!load_tftf_image(&greybus_ops, &is_secure_image)) {
            if (greybus_ops.finish(true, is_secure_image) != 0) {
                halt_and_catch_fire(boot_status);
            }
            if (is_secure_image) {
                boot_status = fallback_boot_unipro ?
                    INIT_STATUS_FALLLBACK_TRUSTED_UNIPRO_BOOT_FINISHED :
                    INIT_STATUS_TRUSTED_UNIPRO_BOOT_FINISHED;
                dbgprintx32("UP Trusted: (",
                            merge_errno_with_boot_status(boot_status),
                            ")\n");
            } else {
                boot_status = fallback_boot_unipro ?
                    INIT_STATUS_FALLLBACK_UNTRUSTED_UNIPRO_BOOT_FINISHED :
                    INIT_STATUS_UNTRUSTED_UNIPRO_BOOT_FINISHED;
                dbgprintx32("UP Trusted: (",
                            merge_errno_with_boot_status(boot_status),
                            ")\n");

                /*
                 *  Disable IMS, CMS access before starting
                 * untrusted image
                 *  NB. JTAG continues to be not enabled at this point
                 */
                efuse_rig_for_untrusted();
            }

            /* Log that we're starting the boot-from-UniPro */
            chip_advertise_boot_status(boot_status);
            /* TA-17 jump to Workram code (BOOTRET_o = 0 && SPIM_BOOT_N = 1) */
            jump_to_image();
        }
        if (greybus_ops.finish(false, is_secure_image) != 0) {
            halt_and_catch_fire(boot_status);
        }
    }

    /* If we reach here, we didn't find an image to boot - stop while we're
     * ahead...
     */
    halt_and_catch_fire(boot_status);
}