int wait_for_mailbox_ack(uint32_t wval, int peer) {
    int rc;
    uint32_t val = 0;
    do {
        rc = chip_unipro_attr_read(MBOX_ACK_ATTR, &val, 0, peer);
    } while (!rc && val != wval);
    if (rc) {
        return rc;
    }

    val = 0;
    chip_unipro_attr_write(MBOX_ACK_ATTR, val, 0, peer);
    return 0;
}
Exemple #2
0
/**
 * @brief control boot behavior
 * @param boot_from_spi
 * This function has to be called before second stage loader overrides the
 * DME_ARA_INIT_STATUS
 */
static void boot_control(bool *boot_from_spi) {
    uint32_t    boot_status = INIT_STATUS_OPERATING;
    uint32_t    prev_boot_status;
    uint32_t    bootctrl;
    int rc;

    *boot_from_spi = false;
    prev_boot_status = chip_get_boot_status();

    rc = chip_unipro_attr_read(DME_ARA_BOOT_CONTROL,
                               &bootctrl,
                               0,
                               ATTR_LOCAL);
    if (rc) {
        halt_and_catch_fire(boot_status);
    }

    if (prev_boot_status & INIT_STATUS_FAILED) {
        /**
         * We are in second stage loader at this moment, so the boot status
         * should never been "FAILED".
         * The check here is just for safety.
         **/
        halt_and_catch_fire(boot_status);
    }

    prev_boot_status &= INIT_STATUS_STATUS_MASK;

    if (prev_boot_status == INIT_STATUS_TRUSTED_SPI_FLASH_BOOT_FINISHED ||
        prev_boot_status == INIT_STATUS_UNTRUSTED_SPI_FLASH_BOOT_FINISHED) {
        *boot_from_spi = true;
    }

    if (bootctrl & FORCE_UNIPRO_BOOT) {
        *boot_from_spi = false;
    }
}