Загрузка данных


/* Function of sending firmware to M7 in fragments */
int imx_rproc_flash_firmware(struct udevice *dev, ulong src_image_addr, ulong image_size)
{
    struct imx_rproc *priv = dev_get_priv(dev);
    const struct imx_rproc_dcfg *dcfg = priv->dcfg;
    volatile struct rproc_update_ipc_a55 *ipc = (struct rproc_update_ipc_a55 *)IMX95_M7_TCM_IPC_A55_BASE;
    uint8_t *src_ptr = (uint8_t *)src_image_addr;
    uint32_t bytes_left = image_size;
    uint32_t chunk_len = 204800;
    uint32_t current_target_ddr = 0x80000000U;
    
    printf("RPROC: Starting flash of %lu bytes to M7 via TCM...\n", image_size);
    
    /* 1. We calculate the full CRC32 of the reference image using the built-in U-Boot function */
    uint32_t total_expected_crc = crc32(0, src_ptr, image_size);
    printf("RPROC: Calculated image CRC32: 0x%08X\n", total_expected_crc);

    /* 2. Cycle-by-cycle sending of fragments */
    while (bytes_left > 0)
    {
        if (bytes_left < chunk_len) {
            chunk_len = bytes_left;
        }
        while (ipc->status == STAT_BUSY);

        printf("RPROC: Sending chunk of %d bytes...\n", chunk_len);
        /* Copy the data packet to the M7 firmware TCM buffer */
        memcpy((void *)ipc->buffer, src_ptr, chunk_len);

        ipc->chunk_size = chunk_len;
        ipc->target_ddr = current_target_ddr;
        ipc->command = CMD_DATA_READY;
        
        /* Pinging the M7 via the hardware Mailbox (MU) (optional if the M7 is sleeping) */
        // imx_mu_send_signal(); 

        /* Waiting for confirmation (ACK) from M7 */
        while (ipc->status == STAT_BUSY || ipc->command == CMD_DATA_READY);

        if (ipc->status != STAT_ACK) {
            printf("RPROC: Error! M7 rejected chunk at DDR 0x%08X\n", current_target_ddr);
            return -1;
        }
        src_ptr += chunk_len;
        current_target_ddr += chunk_len;
        bytes_left -= chunk_len;
    }

    /* 3. Sending the final CRC check command */
    printf("RPROC: All chunks sent. Verifying total CRC...\n");
    ipc->expected_crc = total_expected_crc;
    ipc->command = CMD_VERIFY_CRC;

    while (ipc->status == STAT_BUSY || ipc->command == CMD_VERIFY_CRC);

    if (ipc->status == STAT_ACK) {
        printf("RPROC: SUCCESS! CRC matches. M7 booted into DDR 0x80000000!\n");
        return 0;
    } else {
        printf("RPROC: CRC VERIFICATION FAILED! Firmware corrupted.\n");
        return -1;
    }
}