__asm__ volatile()

in nimble/drivers/dialog_cmac/src/ble_hw.c [253:337]


        __asm__ volatile (".syntax unified                      \n"
                          "   ldm  %[ptr]!, {r1, r2, r3, r4}    \n"
                          "   ldr  %[ptr], =%[reg]              \n"
                          "   stm  %[ptr]!, {r1, r2, r3, r4}    \n"
                          : [ptr] "+l" (src)
                          : [reg] "i" (&CMAC->CM_CRYPTO_KEY_31_0_REG)
                          : "r1", "r2", "r3", "r4", "memory");

        CMAC->CM_EV_SET_REG = CMAC_CM_EV_SET_REG_EV_CRYPTO_START_Msk;
    }
}

void
ble_hw_resolv_proc_enable(void)
{
    assert(!g_ble_hw_resolv_proc.f_active);

    CMAC->CM_CRYPTO_CTRL_REG = CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_SW_REQ_ABORT_Msk;

    CMAC->CM_CRYPTO_CTRL_REG = CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_ECB_ENC_EN_Msk |
                               CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_IN_SEL_Msk |
                               CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_OUT_SEL_Msk |
                               CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_ENC_DECN_Msk;

    CMAC->CM_CRYPTO_IN_ADR2_REG = (uint32_t)g_ble_hw_resolv_proc.crypto_prand_in;
    CMAC->CM_CRYPTO_OUT_ADR_REG = (uint32_t)g_ble_hw_resolv_proc.crypto_e_out;

    g_ble_hw_resolv_proc.irk = g_ble_hw_resolv_list.irk;
    g_ble_hw_resolv_proc.irk_end = g_ble_hw_resolv_list.irk +
                                   g_ble_hw_resolv_list.count;
    g_ble_hw_resolv_proc.f_configured = 1;
    g_ble_hw_resolv_proc.f_active = 0;

    /*
     * It would be better to enable IRQ in ble_hw_resolv_proc_start, but this
     * would introduce a bit of latency when starting resolving procedure and
     * we need to save every us possible there in order to be able to resolve
     * RPA on time.
     */
    NVIC_ClearPendingIRQ(CRYPTO_IRQn);
    NVIC_EnableIRQ(CRYPTO_IRQn);
}

void
ble_hw_resolv_proc_disable(void)
{
    g_ble_hw_resolv_proc.f_configured = 0;
    g_ble_hw_resolv_proc.f_active = 0;
    g_ble_hw_resolv_proc.f_match = 0;
    g_ble_hw_resolv_proc.f_done = 1;

    NVIC_DisableIRQ(CRYPTO_IRQn);
}

void
ble_hw_resolv_proc_reset(const uint8_t *addr)
{
    g_ble_hw_resolv_proc.f_match = 0;
}

void
ble_hw_resolv_proc_start(const uint8_t *addr)
{
    assert(g_ble_hw_resolv_proc.f_configured);

    /* crypto_prand_in is already zeroed so prand is properly padded */
    g_ble_hw_resolv_proc.crypto_prand_in[3] = get_be24(&addr[3]) << 8;
    g_ble_hw_resolv_proc.hash = get_be24(&addr[0]);

    g_ble_hw_resolv_proc.f_match = 0;
    g_ble_hw_resolv_proc.f_done = 0;
    g_ble_hw_resolv_proc.f_active = 1;

    ble_hw_resolv_proc_next();
}

void
CRYPTO_IRQHandler(void)
{
    uint32_t hash;

    CMAC->CM_EXC_STAT_REG = CMAC_CM_EXC_STAT_REG_EXC_CRYPTO_Msk;

    hash = g_ble_hw_resolv_proc.crypto_e_out[3] >> 8;
    if (g_ble_hw_resolv_proc.hash == hash) {