mirror of
https://github.com/linux-msm/qdl.git
synced 2026-02-25 13:12:25 -08:00
This extends the Firehose protocol implementation to support the VIP extension. It implements a state machine that counts the number of packets sent, then injects the VIP table as the next RAW packet when the Firehose programmer runs out of provided digests and needs a new table of digests to validate the next packets. For example: Packet 0: DigestsTableToSign.bin.mbn (53 digest + 1 digest of next table) Packet 1: <configure> Packet 2: <program> Packet 3: ... ... Packet 54: ChainedTableOfDigests0.bin (255 digests + digest of next table) Packet 55: <program> ... Packet 309: ChainedTableOfDigests1.bin To enable VIP extension provide a path where previously generated VIP tables are stored using "--vip-table-path" param: $ qdl --vip-table-path "<vip-table-path>" prog_firehose_ddr.elf \ rawprogram*.xml patch*.xml Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
93 lines
1.8 KiB
C
93 lines
1.8 KiB
C
// SPDX-License-Identifier: BSD-3-Clause
|
|
/*
|
|
* Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved.
|
|
*/
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "sim.h"
|
|
|
|
struct qdl_device_sim {
|
|
struct qdl_device base;
|
|
struct vip_table_generator *vip_gen;
|
|
bool create_digests;
|
|
};
|
|
|
|
static int sim_open(struct qdl_device *qdl, const char *serial)
|
|
{
|
|
ux_info("This is a dry-run execution of QDL. No actual flashing has been performed\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void sim_close(struct qdl_device *qdl)
|
|
{
|
|
return;
|
|
}
|
|
|
|
static int sim_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout)
|
|
{
|
|
return len;
|
|
}
|
|
|
|
static int sim_write(struct qdl_device *qdl, const void *buf, size_t len)
|
|
{
|
|
return len;
|
|
}
|
|
|
|
static void sim_set_out_chunk_size(struct qdl_device *qdl, long size)
|
|
{
|
|
return;
|
|
}
|
|
|
|
struct qdl_device *sim_init(void)
|
|
{
|
|
struct qdl_device *qdl = malloc(sizeof(struct qdl_device_sim));
|
|
|
|
if (!qdl)
|
|
return NULL;
|
|
|
|
memset(qdl, 0, sizeof(struct qdl_device_sim));
|
|
|
|
qdl->dev_type = QDL_DEVICE_SIM;
|
|
qdl->open = sim_open;
|
|
qdl->read = sim_read;
|
|
qdl->write = sim_write;
|
|
qdl->close = sim_close;
|
|
qdl->set_out_chunk_size = sim_set_out_chunk_size;
|
|
qdl->max_payload_size = 1048576;
|
|
|
|
return qdl;
|
|
}
|
|
|
|
struct vip_table_generator *sim_get_vip_generator(struct qdl_device *qdl)
|
|
{
|
|
struct qdl_device_sim *qdl_sim;
|
|
|
|
if (qdl->dev_type != QDL_DEVICE_SIM)
|
|
return NULL;
|
|
|
|
qdl_sim = container_of(qdl, struct qdl_device_sim, base);
|
|
|
|
if (!qdl_sim->create_digests)
|
|
return NULL;
|
|
|
|
return qdl_sim->vip_gen;
|
|
}
|
|
|
|
bool sim_set_digest_generation(bool create_digests, struct qdl_device *qdl,
|
|
struct vip_table_generator *vip_gen)
|
|
{
|
|
struct qdl_device_sim *qdl_sim;
|
|
|
|
if (qdl->dev_type != QDL_DEVICE_SIM)
|
|
return false;
|
|
|
|
qdl_sim = container_of(qdl, struct qdl_device_sim, base);
|
|
|
|
qdl_sim->create_digests = create_digests;
|
|
qdl_sim->vip_gen = vip_gen;
|
|
|
|
return true;
|
|
}
|