summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--futility/cmd_update.c6
-rw-r--r--futility/updater.c23
-rw-r--r--futility/updater.h11
-rw-r--r--futility/updater_manifest.c52
-rwxr-xr-xtests/futility/test_update.sh17
5 files changed, 108 insertions, 1 deletions
diff --git a/futility/cmd_update.c b/futility/cmd_update.c
index 57c54029..d501aca2 100644
--- a/futility/cmd_update.c
+++ b/futility/cmd_update.c
@@ -19,6 +19,7 @@ enum {
OPT_DUMMY = 0x100,
OPT_CCD,
+ OPT_DETECT_MODEL_ONLY,
OPT_EMULATE,
OPT_FACTORY,
OPT_FAST,
@@ -58,6 +59,7 @@ static struct option const long_opts[] = {
{"ccd", 0, NULL, OPT_CCD},
{"servo", 0, NULL, OPT_SERVO},
{"servo_port", 1, NULL, OPT_SERVO_PORT},
+ {"detect-model-only", 0, NULL, OPT_DETECT_MODEL_ONLY},
{"emulate", 1, NULL, OPT_EMULATE},
{"factory", 0, NULL, OPT_FACTORY},
{"fast", 0, NULL, OPT_FAST},
@@ -133,6 +135,7 @@ static void print_help(int argc, char *argv[])
" --host_only \tUpdate only AP (host) firmware\n"
" --emulate=FILE \tEmulate system firmware using file\n"
" --model=MODEL \tOverride system model for images\n"
+ " --detect-model-only\tDetect model by reading the FRID and exit\n"
" --gbb_flags=FLAG\tOverride new GBB flags\n"
" --ccd \tDo fast,force,wp=0,p=raiden_debug_spi\n"
" --servo \tFlash using Servo (v2, v4, micro, ...)\n"
@@ -226,6 +229,9 @@ static int do_update(int argc, char *argv[])
case OPT_MODEL:
args.model = optarg;
break;
+ case OPT_DETECT_MODEL_ONLY:
+ args.detect_model_only = true;
+ break;
case OPT_SIGNATURE:
args.signature_id = optarg;
break;
diff --git a/futility/updater.c b/futility/updater.c
index 941ef125..5b3eed61 100644
--- a/futility/updater.c
+++ b/futility/updater.c
@@ -1423,10 +1423,20 @@ static int updater_setup_archive(
return errorcnt;
}
- model = manifest_find_model(manifest, arg->model);
+ if (cfg->detect_model)
+ model = manifest_detect_model_from_frid(cfg, manifest);
+ else
+ model = manifest_find_model(manifest, arg->model);
+
if (!model)
return ++errorcnt;
+ if (arg->detect_model_only) {
+ puts(model->name);
+ /* No additional error. */
+ return errorcnt;
+ }
+
/* Load images now so we can get quirks in custom label checks. */
errorcnt += updater_load_images(
cfg, arg, model->image, model->ec_image,
@@ -1504,6 +1514,14 @@ int updater_setup_config(struct updater_config *cfg,
}
*do_update = 0;
}
+ if (arg->detect_model_only) {
+ if (!arg->archive) {
+ ERROR("--detect-model-only needs --archive.\n");
+ return ++errorcnt;
+ }
+ cfg->detect_model = true;
+ *do_update = 0;
+ }
/* Setup update mode. */
if (arg->try_update)
@@ -1545,6 +1563,9 @@ int updater_setup_config(struct updater_config *cfg,
cfg->original_programmer = arg->programmer;
VB2_DEBUG("AP (host) programmer changed to %s.\n",
arg->programmer);
+
+ if (arg->archive && !arg->model)
+ cfg->detect_model = true;
}
if (arg->emulation) {
VB2_DEBUG("Using file %s for emulation.\n", arg->emulation);
diff --git a/futility/updater.h b/futility/updater.h
index 3f77c332..4af2ccaf 100644
--- a/futility/updater.h
+++ b/futility/updater.h
@@ -88,6 +88,7 @@ struct updater_config {
const char *original_programmer;
int override_gbb_flags;
uint32_t gbb_flags;
+ bool detect_model;
};
struct updater_config_arguments {
@@ -103,6 +104,7 @@ struct updater_config_arguments {
int verbosity;
int override_gbb_flags;
uint32_t gbb_flags;
+ bool detect_model_only;
};
struct patch_config {
@@ -295,6 +297,15 @@ const struct model_config *manifest_find_model(const struct manifest *manifest,
const char *model_name);
/*
+ * Finds the first existing model_config from manifest that matches current
+ * system by reading RO_FRID from the existing host firmware.
+ * Returns a model_config from manifest, or NULL if not found.
+ */
+const struct model_config *
+manifest_detect_model_from_frid(struct updater_config *cfg,
+ struct manifest *manifest);
+
+/*
* Applies custom label information to an existing model configuration.
* Collects signature ID information from either parameter signature_id or
* image file (via VPD) and updates model.patches for key files.
diff --git a/futility/updater_manifest.c b/futility/updater_manifest.c
index 339bfd8a..ca338c40 100644
--- a/futility/updater_manifest.c
+++ b/futility/updater_manifest.c
@@ -706,6 +706,58 @@ const struct model_config *manifest_find_model(const struct manifest *manifest,
return model;
}
+const struct model_config *
+manifest_detect_model_from_frid(struct updater_config *cfg,
+ struct manifest *manifest)
+{
+ const struct model_config *result = NULL;
+ struct firmware_image current_ro_frid = {0};
+ current_ro_frid.programmer = cfg->image_current.programmer;
+ int error = flashrom_read_region(&current_ro_frid, FMAP_RO_FRID,
+ cfg->verbosity + 1);
+ const char *from_dot;
+ int len;
+
+ if (error)
+ return NULL;
+
+ current_ro_frid.data[current_ro_frid.size - 1] = '\0';
+ from_dot = strchr((const char *)current_ro_frid.data, '.');
+ if (!from_dot) {
+ VB2_DEBUG("Missing dot (%s)\n",
+ (const char *)current_ro_frid.data);
+ goto cleanup;
+ }
+ len = from_dot - (const char *)current_ro_frid.data + 1;
+
+ for (int i = 0; i < manifest->num && !result; ++i) {
+ struct model_config *m = &manifest->models[i];
+ struct firmware_image image = {0};
+
+ if (load_firmware_image(&image, m->image, manifest->archive))
+ return NULL;
+
+ VB2_DEBUG("Comparing '%*.*s' with '%*.*s'\n", len, len,
+ (const char *)current_ro_frid.data, len, len,
+ image.ro_version);
+ if (strncasecmp((const char *)current_ro_frid.data,
+ image.ro_version, len) == 0) {
+ result = m;
+ }
+ free_firmware_image(&image);
+ }
+ if (result) {
+ INFO("Detected model: '%s'\n", result->name);
+ } else {
+ ERROR("Unsupported FRID: '%*.*s'.\n", len - 1, len - 1,
+ (const char *)current_ro_frid.data);
+ }
+cleanup:
+ free_firmware_image(&current_ro_frid);
+
+ return result;
+}
+
/*
* Determines the signature ID to use for custom label.
* Returns the signature ID for looking up rootkey and vblock files.
diff --git a/tests/futility/test_update.sh b/tests/futility/test_update.sh
index 41dd3608..9724659d 100755
--- a/tests/futility/test_update.sh
+++ b/tests/futility/test_update.sh
@@ -33,6 +33,7 @@ test "$(test_quirks " enlarge_image, enlarge_image=2")" = \
# Test data files
LINK_BIOS="${SCRIPT_DIR}/futility/data/bios_link_mp.bin"
PEPPY_BIOS="${SCRIPT_DIR}/futility/data/bios_peppy_mp.bin"
+VOXEL_BIOS="${SCRIPT_DIR}/futility/data/bios_voxel_dev.bin"
RO_VPD_BLOB="${SCRIPT_DIR}/futility/data/ro_vpd.bin"
# Work in scratch directory
@@ -475,8 +476,10 @@ cp -f "${TMP}.to/VBLOCK_A" "${A}/keyset/vblock_A.customtip-cl"
cp -f "${TMP}.to/VBLOCK_B" "${A}/keyset/vblock_B.customtip-cl"
cp -f "${PEPPY_BIOS}" "${FROM_IMAGE}.ap"
cp -f "${LINK_BIOS}" "${FROM_IMAGE}.al"
+cp -f "${VOXEL_BIOS}" "${FROM_IMAGE}.av"
patch_file "${FROM_IMAGE}.ap" FW_MAIN_A 0 "corrupted"
patch_file "${FROM_IMAGE}.al" FW_MAIN_A 0 "corrupted"
+patch_file "${FROM_IMAGE}.av" FW_MAIN_A 0 "corrupted"
test_update "Full update (--archive, model=link)" \
"${FROM_IMAGE}.al" "${LINK_BIOS}" \
-a "${A}" --wp=0 --sys_props 0,0x10001,1,3 --model=link
@@ -491,6 +494,20 @@ test_update "Full update (--archive, model=customtip, signature_id=CL)" \
-a "${A}" --wp=0 --sys_props 0,0x10001,1,3 --model=customtip \
--signature_id=customtip-cl
+test_update "Full update (--archive, detect-model)" \
+ "${FROM_IMAGE}.ap" "${PEPPY_BIOS}" \
+ -a "${A}" --wp=0 --sys_props 0,0x10001,1,3 \
+ --programmer raiden_debug_spi:target=AP
+test_update "Full update (--archive, detect-model, unsupported FRID)" \
+ "${FROM_IMAGE}.av" "!Unsupported FRID: 'Google_Voxel'" \
+ -a "${A}" --wp=0 --sys_props 0,0x10001,1,3 \
+ --programmer raiden_debug_spi:target=AP
+
+echo "*** Test Item: Detect model (--archive, --detect-model-only)"
+"${FUTILITY}" update -a "${A}" \
+ --emulate "${FROM_IMAGE}.ap" --detect-model-only >"${TMP}.model.out"
+cmp "${TMP}.model.out" <(echo peppy)
+
CL_TAG="cl" PATH="${A}/bin:${PATH}" \
test_update "Full update (-a, model=customtip, fake VPD)" \
"${FROM_IMAGE}.al" "${LINK_BIOS}" \