mirror of
https://github.com/linux-msm/qdl.git
synced 2026-10-07 06:29:17 -07:00
When distributing builds the user/developer is forced to determine which programmer, program, patch files should be passed to QDL, to which storage device each set should be programmed. This isn't user friendly and it's prone of various forms of mistakes. A solution to this problem can be found in the build artifacts of a Qualcomm Windows-releases where a "flashmap" file describes the very aspects we're looking for. Implement support for parsing this json blob, populate the Sahara images list based on the "programmer" information, parse the "program" and "patch" files for each memory type and populate the firehose operations queue with "configure", "program", and "patch" operations. Introduce a new "flash" subcommand to trigger this new implementation: qdl flash flashmap.json In certain cases the user might want to only flash the subset of images pertaining to a particular storage media - such as recovering their spinor content. The user can through a suffix operation select which storage media to flash, e.g.: qdl flash flashmap.json::spinor,ufs The json parser is derived from the implementation previously in use in the pd-mapper userspace service, to avoid adding additional library dependencies. Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
85 lines
2.0 KiB
C
85 lines
2.0 KiB
C
// SPDX-License-Identifier: BSD-3-Clause
|
|
/*
|
|
* Copyright (c) 2016-2017, Linaro Ltd.
|
|
* All rights reserved.
|
|
*/
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <libxml/parser.h>
|
|
#include <libxml/tree.h>
|
|
#include <unistd.h>
|
|
|
|
#include "patch.h"
|
|
#include "firehose.h"
|
|
#include "qdl.h"
|
|
|
|
static bool patches_loaded;
|
|
|
|
int patch_load_xml(struct list_head *ops, xmlDoc *doc, const char *patch_file)
|
|
{
|
|
struct firehose_op *patch;
|
|
xmlNode *node;
|
|
xmlNode *root;
|
|
int errors;
|
|
|
|
root = xmlDocGetRootElement(doc);
|
|
for (node = root->children; node ; node = node->next) {
|
|
if (node->type != XML_ELEMENT_NODE)
|
|
continue;
|
|
|
|
if (xmlStrcmp(node->name, (xmlChar *)"patch")) {
|
|
ux_err("unrecognized tag \"%s\" in patch-type file, ignoring\n", node->name);
|
|
continue;
|
|
}
|
|
|
|
errors = 0;
|
|
|
|
patch = firehose_alloc_op(FIREHOSE_OP_PATCH);
|
|
|
|
patch->sector_size = attr_as_unsigned(node, "SECTOR_SIZE_IN_BYTES", &errors);
|
|
patch->byte_offset = attr_as_unsigned(node, "byte_offset", &errors);
|
|
patch->filename = attr_as_string(node, "filename", &errors);
|
|
patch->partition = attr_as_unsigned(node, "physical_partition_number", &errors);
|
|
patch->size_in_bytes = attr_as_unsigned(node, "size_in_bytes", &errors);
|
|
patch->start_sector = attr_as_string(node, "start_sector", &errors);
|
|
patch->value = attr_as_string(node, "value", &errors);
|
|
patch->what = attr_as_string(node, "what", &errors);
|
|
|
|
if (errors) {
|
|
ux_err("errors while parsing patch-type file \"%s\"\n", patch_file);
|
|
free((void *)patch->filename);
|
|
free((void *)patch->start_sector);
|
|
free((void *)patch->value);
|
|
free((void *)patch->what);
|
|
free(patch);
|
|
continue;
|
|
}
|
|
|
|
list_append(ops, &patch->node);
|
|
}
|
|
|
|
patches_loaded = true;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int patch_load(struct list_head *ops, const char *patch_file)
|
|
{
|
|
xmlDoc *doc;
|
|
int ret;
|
|
|
|
doc = xmlReadFile(patch_file, NULL, 0);
|
|
if (!doc) {
|
|
ux_err("failed to parse patch-type file \"%s\"\n", patch_file);
|
|
return -EINVAL;
|
|
}
|
|
|
|
ret = patch_load_xml(ops, doc, patch_file);
|
|
|
|
xmlFreeDoc(doc);
|
|
|
|
return ret;
|
|
}
|