Exemple #1
2
int program_flash_dword(const uint64_t *dword)
{
    int rv;

    dbgprintx32("program_flash_dword ", PARTITION_FLASHMODE_START, "\r\n");
    rv = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, PARTITION_FLASHMODE_START, *dword);
    return rv;
}
Exemple #2
0
void dump_partitions(void)
{
  dbgprintx32("FLASH_BOUNDARY            0x", FLASH_BOUNDARY           , "\r\n");
  dbgprintx32("PARTITION_BOOT_START      0x", PARTITION_BOOT_START     , "\r\n");
  dbgprintx32("PARTITION_BOOT_END        0x", PARTITION_BOOT_END       , "\r\n");
  dbgprintx32("PARTITION_TFTF_START      0x", PARTITION_TFTF_START     , "\r\n");
  dbgprintx32("PARTITION_TFTF_END        0x", PARTITION_TFTF_END       , "\r\n");
  dbgprintx32("PARTITION_MAIN_START      0x", PARTITION_MAIN_START     , "\r\n");
  dbgprintx32("PARTITION_MAIN_END        0x", PARTITION_MAIN_END       , "\r\n");
  dbgprintx32("PARTITION_FLASHMODE_START 0x", PARTITION_FLASHMODE_START, "\r\n");
  dbgprintx32("PARTITION_FLASHMODE_END   0x", PARTITION_FLASHMODE_END  , "\r\n");
}
Exemple #3
0
static int find_public_key(tftf_signature *signature, const unsigned char **key) {
    uint32_t *ps, *pk;
    int i, k;
    uint32_t size = (sizeof(public_keys[0]) -
                     sizeof(public_keys[0].key)) /
                    sizeof(uint32_t);

    ps = (uint32_t *)&(signature->type);

    for (k = 0; k < number_of_public_keys; k++) {
        if (chip_is_key_revoked(k)) {
            dbgprintx32("Key ", k, " revoked\n");
            continue;
        }
        pk = (uint32_t *)&public_keys[k];
        for (i = 0; i < size; i++) {
            if (ps[i] != pk[i]) {
                break;
            }
        }
        if (i >= size) {
            dbgprint("Found pub. key for this sig.\n");
            *key = public_keys[k].key;
            return 0;
        }
    }

    dbgprint("Failed to find pub. key for this sig.\n");
    return -1;
}
Exemple #4
0
static int gbboot_get_firmware_size(uint32_t cportid,
                                    gb_operation_header *op_header) {
    int rc;
    uint8_t *payload = (uint8_t *)op_header + sizeof(*op_header);
    uint32_t size;
    spi_ops.init();

    stage_to_load = *payload - 1;
    rc = locate_ffff_element_on_storage(&spi_ops, stage_to_load, &size);

    dbgprintx32("image size: ", size, "\n");

#if _SPECIAL_TEST == SPECIAL_GEAR_CHANGE_TEST
    switch_gear_change(GEAR_HS_G2,
                       TERMINATION_ON,
                       HS_MODE_A,
                       1,
                       POWERMODE_FAST);
#endif

    return greybus_op_response(cportid,
                               op_header,
                               (rc == 0) ? GB_OP_SUCCESS : GB_OP_UNKNOWN_ERROR,
                               (unsigned char*)&size,
                               sizeof(size));
}
Exemple #5
0
int spi_write_calc_total_len(void *data)
{
    tftf_header *tf_header = (tftf_header *)data;
    tftf_section_descriptor *section = tf_header->sections;
    uint32_t num_sections = 0;

    total_section_length = 0;
    while (section->section_type != TFTF_SECTION_END) {
        total_section_length += section->section_length;
        num_sections++;
        section++;
    }
#ifdef CONFIG_DEBUG_SPI_FLASH
    dbgprintx32("spi flash tftf num_sections ",  num_sections, "\r\n");
    dbgprintx32("spi flash tftf total_section_length ", total_section_length, "\r\n");
#endif

    return total_section_length;
}
static int gbboot_ready_to_boot(uint32_t cportid,
                                gb_operation_header *op_header) {
    uint8_t *payload = (uint8_t *)op_header + sizeof(*op_header);
    dbgprintx32("ready-to-boot, status: ", *payload, "\n");

    image_download_finished = true;
    return greybus_op_response(cportid,
                               op_header,
                               (*payload != 0) ? GB_OP_SUCCESS : GB_OP_UNKNOWN_ERROR,
                               NULL,
                               0);
}
Exemple #7
0
int spi_write_to_flash_data(const data_write_ops *ops, void *src, uint32_t len)
{
    int result = 0;

#ifdef CONFIG_DEBUG_SPI_FLASH
    dbgprintx32("spi_write_to_flash_data dst ", dst, "\r\n");
#endif
    ops->write(dst, src, len);
    result = ops->verify(dst, src, len);

    dst += len;
    return result;
}
/**
 * @brief Wrapper to set the bootloader-specific "errno" value
 *
 * Note: The first error is sticky (subsequent settings are ignored)
 *
 * @param errno A BRE_xxx error code to save
 */
void set_last_error(uint32_t err) {
    if (br_errno == BRE_OK) {
        uint32_t    err_group = err & BRE_GROUP_MASK;

        /* Save the error */
        br_errno = err;
        /* Print out the error */
        dbgprintx32((err_group == BRE_EFUSE_BASE)? "e-Fuse err: ":
                    (err_group == BRE_TFTF_BASE)? "TFTF err: ":
                    (err_group == BRE_FFFF_BASE)? "FFFF err: " :
                    (err_group == BRE_CRYPTO_BASE)? "Crypto err: " : "error: ",
                    err, "\n");
    }
}
static int gbboot_get_firmware_size(uint32_t cportid,
                                    gb_operation_header *op_header) {
    int rc;
    uint8_t *payload = (uint8_t *)op_header + sizeof(*op_header);
    uint32_t size;
    spi_ops.init();

    stage_to_load = *payload - 1;
    rc = locate_ffff_element_on_storage(&spi_ops, stage_to_load, &size);

    dbgprintx32("image size: ", size, "\n");
    return greybus_op_response(cportid,
                               op_header,
                               (rc == 0) ? GB_OP_SUCCESS : GB_OP_UNKNOWN_ERROR,
                               (unsigned char*)&size,
                               sizeof(size));
}
Exemple #10
0
static int gbboot_ready_to_boot(uint32_t cportid,
                                gb_operation_header *op_header) {
    uint8_t *payload = (uint8_t *)op_header + sizeof(*op_header);
    dbgprintx32("ready-to-boot, status: ", *payload, "\n");

    image_download_finished = true;
#if _SPECIAL_TEST == SPECIAL_GEAR_CHANGE_TEST
    switch_gear_change(GEAR_HS_G3,
                       TERMINATION_ON,
                       HS_MODE_A,
                       2,
                       POWERMODE_FAST);
#endif
    return greybus_op_response(cportid,
                               op_header,
                               (*payload != 0) ? GB_OP_SUCCESS : GB_OP_UNKNOWN_ERROR,
                               NULL,
                               0);
}
Exemple #11
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);
}
Exemple #12
0
static int es2_fixup_mphy(void)
{
    uint32_t debug_0720 = tsb_get_debug_reg(0x0720);
    uint32_t urc;
    const struct tsb_mphy_fixup *fu;

    /*
     * Apply the "register 2" map fixups.
     */
    unipro_attr_local_write(TSB_MPHY_MAP, TSB_MPHY_MAP_TSB_REGISTER_2, 0,
                            &urc);
    if (urc) {
        dbgprint((char*)__func__);
        dbgprintx32(": failed to switch to register 2 map:", urc, "\r\n");
        return urc;
    }
    fu = tsb_register_2_map_mphy_fixups;
    do {
        unipro_attr_local_write(fu->attrid, fu->value, fu->select_index,
                                &urc);
        if (urc) {
            dbgprint((char*)__func__);
            dbgprintx32(": failed to switch to register 2 map:", urc, "\r\n");
            return urc;
        }
    } while (!tsb_mphy_fixup_is_last(fu++));

    /*
     * Switch to "normal" map.
     */
    unipro_attr_local_write(TSB_MPHY_MAP, TSB_MPHY_MAP_NORMAL, 0,
                            &urc);
    if (urc) {
        dbgprint((char*)__func__);
        dbgprintx32(": failed to switch to normal map: ", urc, "\r\n");
        return urc;
    }

    /*
     * Apply the "register 1" map fixups.
     */
    unipro_attr_local_write(TSB_MPHY_MAP, TSB_MPHY_MAP_TSB_REGISTER_1, 0,
                            &urc);
    if (urc) {
        dbgprint((char*)__func__);
        dbgprintx32(": failed to switch to register 1 map: ", urc, "\r\n");
        return urc;
    }
    fu = tsb_register_1_map_mphy_fixups;
    do {
        if (tsb_mphy_r1_fixup_is_magic(fu)) {
            /*
             * The magic R1 fixups come from the mysterious and solemn
             * debug register 0x0720.
             * */
            unipro_attr_local_write(0x8002, (debug_0720 >> 1) & 0x1f, 0, &urc);
        } else {
            unipro_attr_local_write(fu->attrid, fu->value, fu->select_index,
                                    &urc);
        }
        if (urc) {
            dbgprint((char*)__func__);
            dbgprintx32(": failed to switch to register 1 map: ", urc, "\r\n");
            return urc;
        }
    } while (!tsb_mphy_fixup_is_last(fu++));