1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2018 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker *
5*8617a60dSAndroid Build Coastguard Worker * The board-specific quirks needed by firmware updater.
6*8617a60dSAndroid Build Coastguard Worker */
7*8617a60dSAndroid Build Coastguard Worker
8*8617a60dSAndroid Build Coastguard Worker #include <assert.h>
9*8617a60dSAndroid Build Coastguard Worker #include <stdio.h>
10*8617a60dSAndroid Build Coastguard Worker #include <string.h>
11*8617a60dSAndroid Build Coastguard Worker #include <sys/types.h>
12*8617a60dSAndroid Build Coastguard Worker #include <sys/stat.h>
13*8617a60dSAndroid Build Coastguard Worker
14*8617a60dSAndroid Build Coastguard Worker #include "cbfstool.h"
15*8617a60dSAndroid Build Coastguard Worker #include "crossystem.h"
16*8617a60dSAndroid Build Coastguard Worker #include "futility.h"
17*8617a60dSAndroid Build Coastguard Worker #include "host_misc.h"
18*8617a60dSAndroid Build Coastguard Worker #include "platform_csme.h"
19*8617a60dSAndroid Build Coastguard Worker #include "updater.h"
20*8617a60dSAndroid Build Coastguard Worker
21*8617a60dSAndroid Build Coastguard Worker struct quirks_record {
22*8617a60dSAndroid Build Coastguard Worker const char * const match;
23*8617a60dSAndroid Build Coastguard Worker const char * const quirks;
24*8617a60dSAndroid Build Coastguard Worker };
25*8617a60dSAndroid Build Coastguard Worker
26*8617a60dSAndroid Build Coastguard Worker /*
27*8617a60dSAndroid Build Coastguard Worker * The 'match by firmware name' is now deprecated. Please do not add any
28*8617a60dSAndroid Build Coastguard Worker * new records below. We now support reading quirks from CBFS, which is
29*8617a60dSAndroid Build Coastguard Worker * easier and more reliable. To do that, create a text file 'updater_quirks'
30*8617a60dSAndroid Build Coastguard Worker * and install to the CBFS.
31*8617a60dSAndroid Build Coastguard Worker *
32*8617a60dSAndroid Build Coastguard Worker * Examples: CL:*3365287, CL:*3351831, CL:*4441527
33*8617a60dSAndroid Build Coastguard Worker */
34*8617a60dSAndroid Build Coastguard Worker static const struct quirks_record quirks_records[] = {
35*8617a60dSAndroid Build Coastguard Worker { .match = "Google_Eve.",
36*8617a60dSAndroid Build Coastguard Worker .quirks = "unlock_csme_eve,eve_smm_store" },
37*8617a60dSAndroid Build Coastguard Worker
38*8617a60dSAndroid Build Coastguard Worker { .match = "Google_Poppy.", .quirks = "min_platform_version=6" },
39*8617a60dSAndroid Build Coastguard Worker { .match = "Google_Scarlet.", .quirks = "min_platform_version=1" },
40*8617a60dSAndroid Build Coastguard Worker { .match = "Google_Trogdor.", .quirks = "min_platform_version=2" },
41*8617a60dSAndroid Build Coastguard Worker
42*8617a60dSAndroid Build Coastguard Worker /* Legacy custom label units. */
43*8617a60dSAndroid Build Coastguard Worker
44*8617a60dSAndroid Build Coastguard Worker /* reference design: octopus */
45*8617a60dSAndroid Build Coastguard Worker { .match = "Google_Phaser.", .quirks = "override_custom_label" },
46*8617a60dSAndroid Build Coastguard Worker };
47*8617a60dSAndroid Build Coastguard Worker
48*8617a60dSAndroid Build Coastguard Worker /*
49*8617a60dSAndroid Build Coastguard Worker * Returns True if the system has EC software sync enabled.
50*8617a60dSAndroid Build Coastguard Worker */
is_ec_software_sync_enabled(struct updater_config * cfg)51*8617a60dSAndroid Build Coastguard Worker static int is_ec_software_sync_enabled(struct updater_config *cfg)
52*8617a60dSAndroid Build Coastguard Worker {
53*8617a60dSAndroid Build Coastguard Worker const struct vb2_gbb_header *gbb;
54*8617a60dSAndroid Build Coastguard Worker
55*8617a60dSAndroid Build Coastguard Worker int vdat_flags = dut_get_property_int("vdat_flags", cfg);
56*8617a60dSAndroid Build Coastguard Worker if (vdat_flags < 0) {
57*8617a60dSAndroid Build Coastguard Worker WARN("Failed to identify DUT vdat_flags.\n");
58*8617a60dSAndroid Build Coastguard Worker return 0;
59*8617a60dSAndroid Build Coastguard Worker }
60*8617a60dSAndroid Build Coastguard Worker
61*8617a60dSAndroid Build Coastguard Worker /* Check if current system has disabled software sync or no support. */
62*8617a60dSAndroid Build Coastguard Worker if (!(vdat_flags & VBSD_EC_SOFTWARE_SYNC)) {
63*8617a60dSAndroid Build Coastguard Worker INFO("EC Software Sync is not available.\n");
64*8617a60dSAndroid Build Coastguard Worker return 0;
65*8617a60dSAndroid Build Coastguard Worker }
66*8617a60dSAndroid Build Coastguard Worker
67*8617a60dSAndroid Build Coastguard Worker /* Check if the system has been updated to disable software sync. */
68*8617a60dSAndroid Build Coastguard Worker gbb = find_gbb(&cfg->image);
69*8617a60dSAndroid Build Coastguard Worker if (!gbb) {
70*8617a60dSAndroid Build Coastguard Worker WARN("Invalid AP firmware image.\n");
71*8617a60dSAndroid Build Coastguard Worker return 0;
72*8617a60dSAndroid Build Coastguard Worker }
73*8617a60dSAndroid Build Coastguard Worker if (gbb->flags & VB2_GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC) {
74*8617a60dSAndroid Build Coastguard Worker INFO("EC Software Sync will be disabled in next boot.\n");
75*8617a60dSAndroid Build Coastguard Worker return 0;
76*8617a60dSAndroid Build Coastguard Worker }
77*8617a60dSAndroid Build Coastguard Worker return 1;
78*8617a60dSAndroid Build Coastguard Worker }
79*8617a60dSAndroid Build Coastguard Worker
80*8617a60dSAndroid Build Coastguard Worker /*
81*8617a60dSAndroid Build Coastguard Worker * Schedules an EC RO software sync (in next boot) if applicable.
82*8617a60dSAndroid Build Coastguard Worker */
ec_ro_software_sync(struct updater_config * cfg)83*8617a60dSAndroid Build Coastguard Worker static int ec_ro_software_sync(struct updater_config *cfg)
84*8617a60dSAndroid Build Coastguard Worker {
85*8617a60dSAndroid Build Coastguard Worker const char *ec_ro_path;
86*8617a60dSAndroid Build Coastguard Worker uint8_t *ec_ro_data;
87*8617a60dSAndroid Build Coastguard Worker uint32_t ec_ro_len;
88*8617a60dSAndroid Build Coastguard Worker int is_same_ec_ro;
89*8617a60dSAndroid Build Coastguard Worker struct firmware_section ec_ro_sec;
90*8617a60dSAndroid Build Coastguard Worker const char *image_file = get_firmware_image_temp_file(
91*8617a60dSAndroid Build Coastguard Worker &cfg->image, &cfg->tempfiles);
92*8617a60dSAndroid Build Coastguard Worker
93*8617a60dSAndroid Build Coastguard Worker if (!image_file)
94*8617a60dSAndroid Build Coastguard Worker return 1;
95*8617a60dSAndroid Build Coastguard Worker find_firmware_section(&ec_ro_sec, &cfg->ec_image, "EC_RO");
96*8617a60dSAndroid Build Coastguard Worker if (!ec_ro_sec.data || !ec_ro_sec.size) {
97*8617a60dSAndroid Build Coastguard Worker ERROR("EC image has invalid section '%s'.\n", "EC_RO");
98*8617a60dSAndroid Build Coastguard Worker return 1;
99*8617a60dSAndroid Build Coastguard Worker }
100*8617a60dSAndroid Build Coastguard Worker
101*8617a60dSAndroid Build Coastguard Worker ec_ro_path = create_temp_file(&cfg->tempfiles);
102*8617a60dSAndroid Build Coastguard Worker if (!ec_ro_path) {
103*8617a60dSAndroid Build Coastguard Worker ERROR("Failed to create temp file.\n");
104*8617a60dSAndroid Build Coastguard Worker return 1;
105*8617a60dSAndroid Build Coastguard Worker }
106*8617a60dSAndroid Build Coastguard Worker if (cbfstool_extract(image_file, FMAP_RO_CBFS, "ecro", ec_ro_path) ||
107*8617a60dSAndroid Build Coastguard Worker !cbfstool_file_exists(image_file, FMAP_RO_CBFS, "ecro.hash")) {
108*8617a60dSAndroid Build Coastguard Worker INFO("No valid EC RO for software sync in AP firmware.\n");
109*8617a60dSAndroid Build Coastguard Worker return 1;
110*8617a60dSAndroid Build Coastguard Worker }
111*8617a60dSAndroid Build Coastguard Worker if (vb2_read_file(ec_ro_path, &ec_ro_data, &ec_ro_len) != VB2_SUCCESS) {
112*8617a60dSAndroid Build Coastguard Worker ERROR("Failed to read EC RO.\n");
113*8617a60dSAndroid Build Coastguard Worker return 1;
114*8617a60dSAndroid Build Coastguard Worker }
115*8617a60dSAndroid Build Coastguard Worker
116*8617a60dSAndroid Build Coastguard Worker is_same_ec_ro = (ec_ro_len <= ec_ro_sec.size &&
117*8617a60dSAndroid Build Coastguard Worker memcmp(ec_ro_sec.data, ec_ro_data, ec_ro_len) == 0);
118*8617a60dSAndroid Build Coastguard Worker free(ec_ro_data);
119*8617a60dSAndroid Build Coastguard Worker
120*8617a60dSAndroid Build Coastguard Worker if (!is_same_ec_ro) {
121*8617a60dSAndroid Build Coastguard Worker /* TODO(hungte) If change AP RO is not a problem (hash will be
122*8617a60dSAndroid Build Coastguard Worker * different, which may be a problem to factory and HWID), or if
123*8617a60dSAndroid Build Coastguard Worker * we can be be sure this is for developers, extract EC RO and
124*8617a60dSAndroid Build Coastguard Worker * update AP RO CBFS to trigger EC RO sync with new EC.
125*8617a60dSAndroid Build Coastguard Worker */
126*8617a60dSAndroid Build Coastguard Worker ERROR("The EC RO contents specified from AP (--image) and EC "
127*8617a60dSAndroid Build Coastguard Worker "(--ec_image) firmware images are different, cannot "
128*8617a60dSAndroid Build Coastguard Worker "update by EC RO software sync.\n");
129*8617a60dSAndroid Build Coastguard Worker return 1;
130*8617a60dSAndroid Build Coastguard Worker }
131*8617a60dSAndroid Build Coastguard Worker dut_set_property_int("try_ro_sync", 1, cfg);
132*8617a60dSAndroid Build Coastguard Worker return 0;
133*8617a60dSAndroid Build Coastguard Worker }
134*8617a60dSAndroid Build Coastguard Worker
135*8617a60dSAndroid Build Coastguard Worker /*
136*8617a60dSAndroid Build Coastguard Worker * Returns True if EC is running in RW.
137*8617a60dSAndroid Build Coastguard Worker */
is_ec_in_rw(struct updater_config * cfg)138*8617a60dSAndroid Build Coastguard Worker static int is_ec_in_rw(struct updater_config *cfg)
139*8617a60dSAndroid Build Coastguard Worker {
140*8617a60dSAndroid Build Coastguard Worker char buf[VB_MAX_STRING_PROPERTY];
141*8617a60dSAndroid Build Coastguard Worker return (dut_get_property_string("ecfw_act", buf, sizeof(buf), cfg) == 0
142*8617a60dSAndroid Build Coastguard Worker && strcasecmp(buf, "RW") == 0);
143*8617a60dSAndroid Build Coastguard Worker }
144*8617a60dSAndroid Build Coastguard Worker
145*8617a60dSAndroid Build Coastguard Worker /*
146*8617a60dSAndroid Build Coastguard Worker * Quirk to enlarge a firmware image to match flash size. This is needed by
147*8617a60dSAndroid Build Coastguard Worker * devices using multiple SPI flash with different sizes, for example 8M and
148*8617a60dSAndroid Build Coastguard Worker * 16M. The image_to will be padded with 0xFF using the size of image_from.
149*8617a60dSAndroid Build Coastguard Worker * Returns 0 on success, otherwise failure.
150*8617a60dSAndroid Build Coastguard Worker */
quirk_enlarge_image(struct updater_config * cfg)151*8617a60dSAndroid Build Coastguard Worker static int quirk_enlarge_image(struct updater_config *cfg)
152*8617a60dSAndroid Build Coastguard Worker {
153*8617a60dSAndroid Build Coastguard Worker struct firmware_image *image_from = &cfg->image_current,
154*8617a60dSAndroid Build Coastguard Worker *image_to = &cfg->image;
155*8617a60dSAndroid Build Coastguard Worker const char *tmp_path;
156*8617a60dSAndroid Build Coastguard Worker size_t to_write;
157*8617a60dSAndroid Build Coastguard Worker FILE *fp;
158*8617a60dSAndroid Build Coastguard Worker
159*8617a60dSAndroid Build Coastguard Worker if (image_from->size <= image_to->size)
160*8617a60dSAndroid Build Coastguard Worker return 0;
161*8617a60dSAndroid Build Coastguard Worker
162*8617a60dSAndroid Build Coastguard Worker tmp_path = get_firmware_image_temp_file(image_to, &cfg->tempfiles);
163*8617a60dSAndroid Build Coastguard Worker if (!tmp_path)
164*8617a60dSAndroid Build Coastguard Worker return -1;
165*8617a60dSAndroid Build Coastguard Worker
166*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Resize image from %u to %u.\n",
167*8617a60dSAndroid Build Coastguard Worker image_to->size, image_from->size);
168*8617a60dSAndroid Build Coastguard Worker to_write = image_from->size - image_to->size;
169*8617a60dSAndroid Build Coastguard Worker fp = fopen(tmp_path, "ab");
170*8617a60dSAndroid Build Coastguard Worker if (!fp) {
171*8617a60dSAndroid Build Coastguard Worker ERROR("Cannot open temporary file %s.\n", tmp_path);
172*8617a60dSAndroid Build Coastguard Worker return -1;
173*8617a60dSAndroid Build Coastguard Worker }
174*8617a60dSAndroid Build Coastguard Worker while (to_write-- > 0)
175*8617a60dSAndroid Build Coastguard Worker fputc('\xff', fp);
176*8617a60dSAndroid Build Coastguard Worker fclose(fp);
177*8617a60dSAndroid Build Coastguard Worker return reload_firmware_image(tmp_path, image_to);
178*8617a60dSAndroid Build Coastguard Worker }
179*8617a60dSAndroid Build Coastguard Worker
180*8617a60dSAndroid Build Coastguard Worker /*
181*8617a60dSAndroid Build Coastguard Worker * Platform specific quirks to unlock a firmware image with SI_ME (management
182*8617a60dSAndroid Build Coastguard Worker * engine). This may be useful when updating so the system has a chance to make
183*8617a60dSAndroid Build Coastguard Worker * sure SI_ME won't be corrupted on next boot before locking the Flash Master
184*8617a60dSAndroid Build Coastguard Worker * values in SI_DESC.
185*8617a60dSAndroid Build Coastguard Worker *
186*8617a60dSAndroid Build Coastguard Worker * Returns 0 on success, otherwise failure.
187*8617a60dSAndroid Build Coastguard Worker */
quirk_unlock_csme_eve(struct updater_config * cfg)188*8617a60dSAndroid Build Coastguard Worker static int quirk_unlock_csme_eve(struct updater_config *cfg)
189*8617a60dSAndroid Build Coastguard Worker {
190*8617a60dSAndroid Build Coastguard Worker return unlock_csme_eve(&cfg->image);
191*8617a60dSAndroid Build Coastguard Worker }
192*8617a60dSAndroid Build Coastguard Worker
quirk_unlock_csme(struct updater_config * cfg)193*8617a60dSAndroid Build Coastguard Worker static int quirk_unlock_csme(struct updater_config *cfg)
194*8617a60dSAndroid Build Coastguard Worker {
195*8617a60dSAndroid Build Coastguard Worker return unlock_csme(cfg);
196*8617a60dSAndroid Build Coastguard Worker }
197*8617a60dSAndroid Build Coastguard Worker
198*8617a60dSAndroid Build Coastguard Worker /*
199*8617a60dSAndroid Build Coastguard Worker * Checks and returns 0 if the platform version of current system is larger
200*8617a60dSAndroid Build Coastguard Worker * or equal to given number, otherwise non-zero.
201*8617a60dSAndroid Build Coastguard Worker */
quirk_min_platform_version(struct updater_config * cfg)202*8617a60dSAndroid Build Coastguard Worker static int quirk_min_platform_version(struct updater_config *cfg)
203*8617a60dSAndroid Build Coastguard Worker {
204*8617a60dSAndroid Build Coastguard Worker int min_version = get_config_quirk(QUIRK_MIN_PLATFORM_VERSION, cfg);
205*8617a60dSAndroid Build Coastguard Worker int platform_version = dut_get_property(DUT_PROP_PLATFORM_VER, cfg);
206*8617a60dSAndroid Build Coastguard Worker
207*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Minimum required version=%d, current platform version=%d\n",
208*8617a60dSAndroid Build Coastguard Worker min_version, platform_version);
209*8617a60dSAndroid Build Coastguard Worker
210*8617a60dSAndroid Build Coastguard Worker if (platform_version >= min_version)
211*8617a60dSAndroid Build Coastguard Worker return 0;
212*8617a60dSAndroid Build Coastguard Worker ERROR("Need platform version >= %d (current is %d). "
213*8617a60dSAndroid Build Coastguard Worker "This firmware will only run on newer systems.\n",
214*8617a60dSAndroid Build Coastguard Worker min_version, platform_version);
215*8617a60dSAndroid Build Coastguard Worker return -1;
216*8617a60dSAndroid Build Coastguard Worker }
217*8617a60dSAndroid Build Coastguard Worker
218*8617a60dSAndroid Build Coastguard Worker /*
219*8617a60dSAndroid Build Coastguard Worker * Quirk to help preserving SMM store on devices without a dedicated "SMMSTORE"
220*8617a60dSAndroid Build Coastguard Worker * FMAP section. These devices will store "smm_store" file in same CBFS where
221*8617a60dSAndroid Build Coastguard Worker * the legacy boot loader lives (i.e, FMAP RW_LEGACY).
222*8617a60dSAndroid Build Coastguard Worker * Note this currently has dependency on external program "cbstool".
223*8617a60dSAndroid Build Coastguard Worker * Returns 0 if the SMM store is properly preserved, or if the system is not
224*8617a60dSAndroid Build Coastguard Worker * available to do that (problem in cbfstool, or no "smm_store" in current
225*8617a60dSAndroid Build Coastguard Worker * system firmware). Otherwise non-zero as failure.
226*8617a60dSAndroid Build Coastguard Worker */
quirk_eve_smm_store(struct updater_config * cfg)227*8617a60dSAndroid Build Coastguard Worker static int quirk_eve_smm_store(struct updater_config *cfg)
228*8617a60dSAndroid Build Coastguard Worker {
229*8617a60dSAndroid Build Coastguard Worker const char *smm_store_name = "smm_store";
230*8617a60dSAndroid Build Coastguard Worker const char *old_store;
231*8617a60dSAndroid Build Coastguard Worker char *command;
232*8617a60dSAndroid Build Coastguard Worker const char *temp_image = get_firmware_image_temp_file(
233*8617a60dSAndroid Build Coastguard Worker &cfg->image_current, &cfg->tempfiles);
234*8617a60dSAndroid Build Coastguard Worker
235*8617a60dSAndroid Build Coastguard Worker if (!temp_image)
236*8617a60dSAndroid Build Coastguard Worker return -1;
237*8617a60dSAndroid Build Coastguard Worker
238*8617a60dSAndroid Build Coastguard Worker old_store = create_temp_file(&cfg->tempfiles);
239*8617a60dSAndroid Build Coastguard Worker if (!old_store) {
240*8617a60dSAndroid Build Coastguard Worker ERROR("Failed to create temp file.\n");
241*8617a60dSAndroid Build Coastguard Worker return 1;
242*8617a60dSAndroid Build Coastguard Worker }
243*8617a60dSAndroid Build Coastguard Worker if (cbfstool_extract(temp_image, FMAP_RW_LEGACY, smm_store_name,
244*8617a60dSAndroid Build Coastguard Worker old_store)) {
245*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("cbfstool failure or SMM store not available. "
246*8617a60dSAndroid Build Coastguard Worker "Don't preserve.\n");
247*8617a60dSAndroid Build Coastguard Worker return 0;
248*8617a60dSAndroid Build Coastguard Worker }
249*8617a60dSAndroid Build Coastguard Worker
250*8617a60dSAndroid Build Coastguard Worker /* Reuse temp_image */
251*8617a60dSAndroid Build Coastguard Worker temp_image = get_firmware_image_temp_file(&cfg->image, &cfg->tempfiles);
252*8617a60dSAndroid Build Coastguard Worker if (!temp_image)
253*8617a60dSAndroid Build Coastguard Worker return -1;
254*8617a60dSAndroid Build Coastguard Worker
255*8617a60dSAndroid Build Coastguard Worker /* crosreview.com/1165109: The offset is fixed at 0x1bf000. */
256*8617a60dSAndroid Build Coastguard Worker ASPRINTF(&command,
257*8617a60dSAndroid Build Coastguard Worker "cbfstool \"%s\" remove -r %s -n \"%s\" 2>/dev/null; "
258*8617a60dSAndroid Build Coastguard Worker "cbfstool \"%s\" add -r %s -n \"%s\" -f \"%s\" "
259*8617a60dSAndroid Build Coastguard Worker " -t raw -b 0x1bf000", temp_image, FMAP_RW_LEGACY,
260*8617a60dSAndroid Build Coastguard Worker smm_store_name, temp_image, FMAP_RW_LEGACY,
261*8617a60dSAndroid Build Coastguard Worker smm_store_name, old_store);
262*8617a60dSAndroid Build Coastguard Worker free(host_shell(command));
263*8617a60dSAndroid Build Coastguard Worker free(command);
264*8617a60dSAndroid Build Coastguard Worker
265*8617a60dSAndroid Build Coastguard Worker return reload_firmware_image(temp_image, &cfg->image);
266*8617a60dSAndroid Build Coastguard Worker }
267*8617a60dSAndroid Build Coastguard Worker
268*8617a60dSAndroid Build Coastguard Worker /*
269*8617a60dSAndroid Build Coastguard Worker * Update EC (RO+RW) in most reliable way.
270*8617a60dSAndroid Build Coastguard Worker *
271*8617a60dSAndroid Build Coastguard Worker * Some EC will reset TCPC when doing sysjump, and will make rootfs unavailable
272*8617a60dSAndroid Build Coastguard Worker * if the system was boot from USB, or other unexpected issues even if the
273*8617a60dSAndroid Build Coastguard Worker * system was boot from internal disk. To prevent that, try to partial update
274*8617a60dSAndroid Build Coastguard Worker * only RO and expect EC software sync to update RW later, or perform EC RO
275*8617a60dSAndroid Build Coastguard Worker * software sync.
276*8617a60dSAndroid Build Coastguard Worker *
277*8617a60dSAndroid Build Coastguard Worker * Note: EC RO software sync was not fully tested and may cause problems
278*8617a60dSAndroid Build Coastguard Worker * (b/218612817, b/187789991).
279*8617a60dSAndroid Build Coastguard Worker * RO-update (without extra sysjump) needs support from flashrom and is
280*8617a60dSAndroid Build Coastguard Worker * currently disabled.
281*8617a60dSAndroid Build Coastguard Worker *
282*8617a60dSAndroid Build Coastguard Worker * Returns:
283*8617a60dSAndroid Build Coastguard Worker * EC_RECOVERY_FULL to indicate a full recovery is needed.
284*8617a60dSAndroid Build Coastguard Worker * EC_RECOVERY_RO to indicate partial update (WP_RO) is needed.
285*8617a60dSAndroid Build Coastguard Worker * EC_RECOVERY_DONE to indicate EC RO software sync is applied.
286*8617a60dSAndroid Build Coastguard Worker * Other values to report failure.
287*8617a60dSAndroid Build Coastguard Worker */
quirk_ec_partial_recovery(struct updater_config * cfg)288*8617a60dSAndroid Build Coastguard Worker static int quirk_ec_partial_recovery(struct updater_config *cfg)
289*8617a60dSAndroid Build Coastguard Worker {
290*8617a60dSAndroid Build Coastguard Worker /*
291*8617a60dSAndroid Build Coastguard Worker * http://crbug.com/1024401: Some EC needs extra header outside EC_RO so
292*8617a60dSAndroid Build Coastguard Worker * we have to update whole WP_RO, not just EC_RO.
293*8617a60dSAndroid Build Coastguard Worker */
294*8617a60dSAndroid Build Coastguard Worker const char *ec_ro = "WP_RO";
295*8617a60dSAndroid Build Coastguard Worker struct firmware_image *ec_image = &cfg->ec_image;
296*8617a60dSAndroid Build Coastguard Worker int do_partial = get_config_quirk(QUIRK_EC_PARTIAL_RECOVERY, cfg);
297*8617a60dSAndroid Build Coastguard Worker
298*8617a60dSAndroid Build Coastguard Worker if (!do_partial) {
299*8617a60dSAndroid Build Coastguard Worker /* Need full update. */
300*8617a60dSAndroid Build Coastguard Worker } else if (!firmware_section_exists(ec_image, ec_ro)) {
301*8617a60dSAndroid Build Coastguard Worker INFO("EC image does not have section '%s'.\n", ec_ro);
302*8617a60dSAndroid Build Coastguard Worker /* Need full update. */
303*8617a60dSAndroid Build Coastguard Worker } else if (!is_ec_software_sync_enabled(cfg)) {
304*8617a60dSAndroid Build Coastguard Worker /* Message already printed, need full update. */
305*8617a60dSAndroid Build Coastguard Worker } else if (is_ec_in_rw(cfg)) {
306*8617a60dSAndroid Build Coastguard Worker WARN("EC Software Sync detected, will only update EC RO. "
307*8617a60dSAndroid Build Coastguard Worker "The contents in EC RW will be updated after reboot.\n");
308*8617a60dSAndroid Build Coastguard Worker return EC_RECOVERY_RO;
309*8617a60dSAndroid Build Coastguard Worker } else if (ec_ro_software_sync(cfg) == 0) {
310*8617a60dSAndroid Build Coastguard Worker INFO("EC RO and RW should be updated after reboot.\n");
311*8617a60dSAndroid Build Coastguard Worker return EC_RECOVERY_DONE;
312*8617a60dSAndroid Build Coastguard Worker }
313*8617a60dSAndroid Build Coastguard Worker
314*8617a60dSAndroid Build Coastguard Worker WARN("Update EC RO+RW and may cause unexpected error later. "
315*8617a60dSAndroid Build Coastguard Worker "See http://crbug.com/782427#c4 for more information.\n");
316*8617a60dSAndroid Build Coastguard Worker return EC_RECOVERY_FULL;
317*8617a60dSAndroid Build Coastguard Worker }
318*8617a60dSAndroid Build Coastguard Worker
319*8617a60dSAndroid Build Coastguard Worker /*
320*8617a60dSAndroid Build Coastguard Worker * Preserve ME during firmware update.
321*8617a60dSAndroid Build Coastguard Worker *
322*8617a60dSAndroid Build Coastguard Worker * Updating ME region while SoC is in S0 state is an unsupported use-case. On
323*8617a60dSAndroid Build Coastguard Worker * recent platforms, we are seeing issues more frequently because of this use-
324*8617a60dSAndroid Build Coastguard Worker * case. For the firmware updates performed for autoupdate firmware updates,
325*8617a60dSAndroid Build Coastguard Worker * preserve the ME region so that it gets updated in the successive boot.
326*8617a60dSAndroid Build Coastguard Worker *
327*8617a60dSAndroid Build Coastguard Worker * Returns:
328*8617a60dSAndroid Build Coastguard Worker * 1 to signal ME needs to be preserved.
329*8617a60dSAndroid Build Coastguard Worker * 0 to signal ME does not need to be preserved.
330*8617a60dSAndroid Build Coastguard Worker */
quirk_preserve_me(struct updater_config * cfg)331*8617a60dSAndroid Build Coastguard Worker static int quirk_preserve_me(struct updater_config *cfg)
332*8617a60dSAndroid Build Coastguard Worker {
333*8617a60dSAndroid Build Coastguard Worker /*
334*8617a60dSAndroid Build Coastguard Worker * Only preserve the ME if performing an autoupdate-mode firmware
335*8617a60dSAndroid Build Coastguard Worker * update. Recovery, factory and any other update modes cannot leave the
336*8617a60dSAndroid Build Coastguard Worker * ME as is. Otherwise, a recovery firmware update cannot be relied upon
337*8617a60dSAndroid Build Coastguard Worker * to update the ME to a valid version for WP-disabled devices.
338*8617a60dSAndroid Build Coastguard Worker */
339*8617a60dSAndroid Build Coastguard Worker if (cfg->try_update == TRY_UPDATE_OFF) {
340*8617a60dSAndroid Build Coastguard Worker INFO("No auto-update requested. Not preserving ME.\n");
341*8617a60dSAndroid Build Coastguard Worker return 0;
342*8617a60dSAndroid Build Coastguard Worker }
343*8617a60dSAndroid Build Coastguard Worker INFO("Auto-update requested. Preserving ME.\n");
344*8617a60dSAndroid Build Coastguard Worker
345*8617a60dSAndroid Build Coastguard Worker /*
346*8617a60dSAndroid Build Coastguard Worker * b/213706510: subratabanik@ confirmed CSE may modify itself while we
347*8617a60dSAndroid Build Coastguard Worker * are doing system update, and currently the 'preserve' is done by
348*8617a60dSAndroid Build Coastguard Worker * flashing the same (e.g., "previously read") contents to skip erasing
349*8617a60dSAndroid Build Coastguard Worker * and writing; so we have to use the diff image to prevent contents
350*8617a60dSAndroid Build Coastguard Worker * being changed when writing.
351*8617a60dSAndroid Build Coastguard Worker */
352*8617a60dSAndroid Build Coastguard Worker cfg->use_diff_image = 1;
353*8617a60dSAndroid Build Coastguard Worker
354*8617a60dSAndroid Build Coastguard Worker return 1;
355*8617a60dSAndroid Build Coastguard Worker }
356*8617a60dSAndroid Build Coastguard Worker
quirk_clear_mrc_data(struct updater_config * cfg)357*8617a60dSAndroid Build Coastguard Worker static int quirk_clear_mrc_data(struct updater_config *cfg)
358*8617a60dSAndroid Build Coastguard Worker {
359*8617a60dSAndroid Build Coastguard Worker struct firmware_section section;
360*8617a60dSAndroid Build Coastguard Worker struct firmware_image *image = &cfg->image_current;
361*8617a60dSAndroid Build Coastguard Worker int i, count = 0;
362*8617a60dSAndroid Build Coastguard Worker int flash_now = 0;
363*8617a60dSAndroid Build Coastguard Worker
364*8617a60dSAndroid Build Coastguard Worker /*
365*8617a60dSAndroid Build Coastguard Worker * Devices with multiple MRC caches (RECOVERY, RW, RW_VAR) will have the
366*8617a60dSAndroid Build Coastguard Worker * UNIFIED_MRC_CACHE; and devices with single RW cache will only have
367*8617a60dSAndroid Build Coastguard Worker * RW_MRC_CACHE (for example MediaTek devices).
368*8617a60dSAndroid Build Coastguard Worker */
369*8617a60dSAndroid Build Coastguard Worker const char * const mrc_names[] = {
370*8617a60dSAndroid Build Coastguard Worker "UNIFIED_MRC_CACHE",
371*8617a60dSAndroid Build Coastguard Worker "RW_MRC_CACHE",
372*8617a60dSAndroid Build Coastguard Worker };
373*8617a60dSAndroid Build Coastguard Worker
374*8617a60dSAndroid Build Coastguard Worker if (is_ap_write_protection_enabled(cfg) || cfg->try_update)
375*8617a60dSAndroid Build Coastguard Worker flash_now = 1;
376*8617a60dSAndroid Build Coastguard Worker
377*8617a60dSAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(mrc_names); i++) {
378*8617a60dSAndroid Build Coastguard Worker const char *name = mrc_names[i];
379*8617a60dSAndroid Build Coastguard Worker
380*8617a60dSAndroid Build Coastguard Worker find_firmware_section(§ion, image, name);
381*8617a60dSAndroid Build Coastguard Worker if (!section.size)
382*8617a60dSAndroid Build Coastguard Worker continue;
383*8617a60dSAndroid Build Coastguard Worker
384*8617a60dSAndroid Build Coastguard Worker WARN("Wiping memory training data: %s\n", name);
385*8617a60dSAndroid Build Coastguard Worker memset(section.data, 0xff, section.size);
386*8617a60dSAndroid Build Coastguard Worker if (flash_now) {
387*8617a60dSAndroid Build Coastguard Worker const char *write_names[] = {name};
388*8617a60dSAndroid Build Coastguard Worker write_system_firmware(cfg, image, write_names,
389*8617a60dSAndroid Build Coastguard Worker ARRAY_SIZE(write_names));
390*8617a60dSAndroid Build Coastguard Worker }
391*8617a60dSAndroid Build Coastguard Worker count++;
392*8617a60dSAndroid Build Coastguard Worker break;
393*8617a60dSAndroid Build Coastguard Worker }
394*8617a60dSAndroid Build Coastguard Worker
395*8617a60dSAndroid Build Coastguard Worker if (count)
396*8617a60dSAndroid Build Coastguard Worker WARN("Next boot will take a few mins for memory training.\n");
397*8617a60dSAndroid Build Coastguard Worker else
398*8617a60dSAndroid Build Coastguard Worker ERROR("No known memory training data in the firmware image.\n");
399*8617a60dSAndroid Build Coastguard Worker
400*8617a60dSAndroid Build Coastguard Worker return 0;
401*8617a60dSAndroid Build Coastguard Worker }
402*8617a60dSAndroid Build Coastguard Worker
403*8617a60dSAndroid Build Coastguard Worker /*
404*8617a60dSAndroid Build Coastguard Worker * Disable checking platform compatibility.
405*8617a60dSAndroid Build Coastguard Worker */
quirk_no_check_platform(struct updater_config * cfg)406*8617a60dSAndroid Build Coastguard Worker static int quirk_no_check_platform(struct updater_config *cfg)
407*8617a60dSAndroid Build Coastguard Worker {
408*8617a60dSAndroid Build Coastguard Worker WARN("Disabled checking platform. You are on your own.\n");
409*8617a60dSAndroid Build Coastguard Worker cfg->check_platform = 0;
410*8617a60dSAndroid Build Coastguard Worker return 0;
411*8617a60dSAndroid Build Coastguard Worker }
412*8617a60dSAndroid Build Coastguard Worker
413*8617a60dSAndroid Build Coastguard Worker /*
414*8617a60dSAndroid Build Coastguard Worker * Disable verifying contents after flashing.
415*8617a60dSAndroid Build Coastguard Worker */
quirk_no_verify(struct updater_config * cfg)416*8617a60dSAndroid Build Coastguard Worker static int quirk_no_verify(struct updater_config *cfg)
417*8617a60dSAndroid Build Coastguard Worker {
418*8617a60dSAndroid Build Coastguard Worker WARN("Disabled verifying flashed contents. You are on your own.\n");
419*8617a60dSAndroid Build Coastguard Worker cfg->do_verify = 0;
420*8617a60dSAndroid Build Coastguard Worker return 0;
421*8617a60dSAndroid Build Coastguard Worker }
422*8617a60dSAndroid Build Coastguard Worker
updater_register_quirks(struct updater_config * cfg)423*8617a60dSAndroid Build Coastguard Worker void updater_register_quirks(struct updater_config *cfg)
424*8617a60dSAndroid Build Coastguard Worker {
425*8617a60dSAndroid Build Coastguard Worker struct quirk_entry *quirks;
426*8617a60dSAndroid Build Coastguard Worker
427*8617a60dSAndroid Build Coastguard Worker assert(ARRAY_SIZE(cfg->quirks) == QUIRK_MAX);
428*8617a60dSAndroid Build Coastguard Worker quirks = &cfg->quirks[QUIRK_ENLARGE_IMAGE];
429*8617a60dSAndroid Build Coastguard Worker quirks->name = "enlarge_image";
430*8617a60dSAndroid Build Coastguard Worker quirks->help = "Enlarge firmware image by flash size.";
431*8617a60dSAndroid Build Coastguard Worker quirks->apply = quirk_enlarge_image;
432*8617a60dSAndroid Build Coastguard Worker
433*8617a60dSAndroid Build Coastguard Worker quirks = &cfg->quirks[QUIRK_MIN_PLATFORM_VERSION];
434*8617a60dSAndroid Build Coastguard Worker quirks->name = "min_platform_version";
435*8617a60dSAndroid Build Coastguard Worker quirks->help = "Minimum compatible platform version "
436*8617a60dSAndroid Build Coastguard Worker "(also known as Board ID version).";
437*8617a60dSAndroid Build Coastguard Worker quirks->apply = quirk_min_platform_version;
438*8617a60dSAndroid Build Coastguard Worker
439*8617a60dSAndroid Build Coastguard Worker quirks = &cfg->quirks[QUIRK_UNLOCK_CSME_EVE];
440*8617a60dSAndroid Build Coastguard Worker quirks->name = "unlock_csme_eve";
441*8617a60dSAndroid Build Coastguard Worker quirks->help = "b/35568719; (skl, kbl) only lock management engine in board-postinst.";
442*8617a60dSAndroid Build Coastguard Worker quirks->apply = quirk_unlock_csme_eve;
443*8617a60dSAndroid Build Coastguard Worker
444*8617a60dSAndroid Build Coastguard Worker quirks = &cfg->quirks[QUIRK_UNLOCK_CSME];
445*8617a60dSAndroid Build Coastguard Worker quirks->name = "unlock_csme";
446*8617a60dSAndroid Build Coastguard Worker quirks->help = "b/273168873; unlock the Intel management engine. "
447*8617a60dSAndroid Build Coastguard Worker "Applies to all recent Intel platforms (CML onwards)";
448*8617a60dSAndroid Build Coastguard Worker quirks->apply = quirk_unlock_csme;
449*8617a60dSAndroid Build Coastguard Worker
450*8617a60dSAndroid Build Coastguard Worker quirks = &cfg->quirks[QUIRK_EVE_SMM_STORE];
451*8617a60dSAndroid Build Coastguard Worker quirks->name = "eve_smm_store";
452*8617a60dSAndroid Build Coastguard Worker quirks->help = "b/70682365; preserve UEFI SMM store without "
453*8617a60dSAndroid Build Coastguard Worker "dedicated FMAP section.";
454*8617a60dSAndroid Build Coastguard Worker quirks->apply = quirk_eve_smm_store;
455*8617a60dSAndroid Build Coastguard Worker
456*8617a60dSAndroid Build Coastguard Worker quirks = &cfg->quirks[QUIRK_EC_PARTIAL_RECOVERY];
457*8617a60dSAndroid Build Coastguard Worker quirks->name = "ec_partial_recovery";
458*8617a60dSAndroid Build Coastguard Worker quirks->help = "chromium/1024401; recover EC by partial RO update.";
459*8617a60dSAndroid Build Coastguard Worker quirks->apply = quirk_ec_partial_recovery;
460*8617a60dSAndroid Build Coastguard Worker
461*8617a60dSAndroid Build Coastguard Worker quirks = &cfg->quirks[QUIRK_OVERRIDE_CUSTOM_LABEL];
462*8617a60dSAndroid Build Coastguard Worker quirks->name = "override_custom_label";
463*8617a60dSAndroid Build Coastguard Worker quirks->help = "b/146876241; override custom label name for "
464*8617a60dSAndroid Build Coastguard Worker "devices shipped with different root key.";
465*8617a60dSAndroid Build Coastguard Worker quirks->apply = NULL; /* Simple config. */
466*8617a60dSAndroid Build Coastguard Worker
467*8617a60dSAndroid Build Coastguard Worker quirks = &cfg->quirks[QUIRK_PRESERVE_ME];
468*8617a60dSAndroid Build Coastguard Worker quirks->name = "preserve_me";
469*8617a60dSAndroid Build Coastguard Worker quirks->help = "b/165590952; Preserve ME during firmware update except "
470*8617a60dSAndroid Build Coastguard Worker "for factory update or developer images.";
471*8617a60dSAndroid Build Coastguard Worker quirks->apply = quirk_preserve_me;
472*8617a60dSAndroid Build Coastguard Worker
473*8617a60dSAndroid Build Coastguard Worker quirks = &cfg->quirks[QUIRK_NO_CHECK_PLATFORM];
474*8617a60dSAndroid Build Coastguard Worker quirks->name = "no_check_platform";
475*8617a60dSAndroid Build Coastguard Worker quirks->help = "Do not check platform name.";
476*8617a60dSAndroid Build Coastguard Worker quirks->apply = quirk_no_check_platform;
477*8617a60dSAndroid Build Coastguard Worker
478*8617a60dSAndroid Build Coastguard Worker quirks = &cfg->quirks[QUIRK_NO_VERIFY];
479*8617a60dSAndroid Build Coastguard Worker quirks->name = "no_verify";
480*8617a60dSAndroid Build Coastguard Worker quirks->help = "Do not verify when flashing.";
481*8617a60dSAndroid Build Coastguard Worker quirks->apply = quirk_no_verify;
482*8617a60dSAndroid Build Coastguard Worker
483*8617a60dSAndroid Build Coastguard Worker quirks = &cfg->quirks[QUIRK_EXTRA_RETRIES];
484*8617a60dSAndroid Build Coastguard Worker quirks->name = "extra_retries";
485*8617a60dSAndroid Build Coastguard Worker quirks->help = "Extra retries when writing to system firmware.";
486*8617a60dSAndroid Build Coastguard Worker quirks->apply = NULL; /* Simple config. */
487*8617a60dSAndroid Build Coastguard Worker
488*8617a60dSAndroid Build Coastguard Worker quirks = &cfg->quirks[QUIRK_CLEAR_MRC_DATA];
489*8617a60dSAndroid Build Coastguard Worker quirks->name = "clear_mrc_data";
490*8617a60dSAndroid Build Coastguard Worker quirks->help = "b/255617349: Clear memory training data (MRC).";
491*8617a60dSAndroid Build Coastguard Worker quirks->apply = quirk_clear_mrc_data;
492*8617a60dSAndroid Build Coastguard Worker }
493*8617a60dSAndroid Build Coastguard Worker
updater_get_model_quirks(struct updater_config * cfg)494*8617a60dSAndroid Build Coastguard Worker const char * const updater_get_model_quirks(struct updater_config *cfg)
495*8617a60dSAndroid Build Coastguard Worker {
496*8617a60dSAndroid Build Coastguard Worker const char *pattern = cfg->image.ro_version;
497*8617a60dSAndroid Build Coastguard Worker int i;
498*8617a60dSAndroid Build Coastguard Worker
499*8617a60dSAndroid Build Coastguard Worker if (!pattern) {
500*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Cannot identify system for default quirks.\n");
501*8617a60dSAndroid Build Coastguard Worker return NULL;
502*8617a60dSAndroid Build Coastguard Worker }
503*8617a60dSAndroid Build Coastguard Worker
504*8617a60dSAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(quirks_records); i++) {
505*8617a60dSAndroid Build Coastguard Worker const struct quirks_record *r = &quirks_records[i];
506*8617a60dSAndroid Build Coastguard Worker if (strncmp(r->match, pattern, strlen(r->match)) != 0)
507*8617a60dSAndroid Build Coastguard Worker continue;
508*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Found system default quirks: %s\n", r->quirks);
509*8617a60dSAndroid Build Coastguard Worker return r->quirks;
510*8617a60dSAndroid Build Coastguard Worker }
511*8617a60dSAndroid Build Coastguard Worker return NULL;
512*8617a60dSAndroid Build Coastguard Worker }
513*8617a60dSAndroid Build Coastguard Worker
updater_get_cbfs_quirks(struct updater_config * cfg)514*8617a60dSAndroid Build Coastguard Worker char *updater_get_cbfs_quirks(struct updater_config *cfg)
515*8617a60dSAndroid Build Coastguard Worker {
516*8617a60dSAndroid Build Coastguard Worker const char *entry_name = "updater_quirks";
517*8617a60dSAndroid Build Coastguard Worker const char *cbfs_region = "FW_MAIN_A";
518*8617a60dSAndroid Build Coastguard Worker struct firmware_section cbfs_section;
519*8617a60dSAndroid Build Coastguard Worker
520*8617a60dSAndroid Build Coastguard Worker /* Before invoking cbfstool, try to search for CBFS file name. */
521*8617a60dSAndroid Build Coastguard Worker find_firmware_section(&cbfs_section, &cfg->image, cbfs_region);
522*8617a60dSAndroid Build Coastguard Worker if (!cbfs_section.size || !memmem(cbfs_section.data, cbfs_section.size,
523*8617a60dSAndroid Build Coastguard Worker entry_name, strlen(entry_name))) {
524*8617a60dSAndroid Build Coastguard Worker if (!cbfs_section.size)
525*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Missing region: %s\n", cbfs_region);
526*8617a60dSAndroid Build Coastguard Worker else
527*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Cannot find entry: %s\n", entry_name);
528*8617a60dSAndroid Build Coastguard Worker return NULL;
529*8617a60dSAndroid Build Coastguard Worker }
530*8617a60dSAndroid Build Coastguard Worker
531*8617a60dSAndroid Build Coastguard Worker const char *image_file = get_firmware_image_temp_file(
532*8617a60dSAndroid Build Coastguard Worker &cfg->image, &cfg->tempfiles);
533*8617a60dSAndroid Build Coastguard Worker uint8_t *data = NULL;
534*8617a60dSAndroid Build Coastguard Worker uint32_t size = 0;
535*8617a60dSAndroid Build Coastguard Worker const char *entry_file;
536*8617a60dSAndroid Build Coastguard Worker
537*8617a60dSAndroid Build Coastguard Worker /* Although the name exists, it may not be a real file. */
538*8617a60dSAndroid Build Coastguard Worker if (!cbfstool_file_exists(image_file, cbfs_region, entry_name)) {
539*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Found string '%s' but not a file.\n", entry_name);
540*8617a60dSAndroid Build Coastguard Worker return NULL;
541*8617a60dSAndroid Build Coastguard Worker }
542*8617a60dSAndroid Build Coastguard Worker
543*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Found %s from CBFS %s\n", entry_name, cbfs_region);
544*8617a60dSAndroid Build Coastguard Worker entry_file = create_temp_file(&cfg->tempfiles);
545*8617a60dSAndroid Build Coastguard Worker if (!entry_file) {
546*8617a60dSAndroid Build Coastguard Worker ERROR("Failed to create temp file.\n");
547*8617a60dSAndroid Build Coastguard Worker return NULL;
548*8617a60dSAndroid Build Coastguard Worker }
549*8617a60dSAndroid Build Coastguard Worker if (cbfstool_extract(image_file, cbfs_region, entry_name, entry_file) ||
550*8617a60dSAndroid Build Coastguard Worker vb2_read_file(entry_file, &data, &size) != VB2_SUCCESS) {
551*8617a60dSAndroid Build Coastguard Worker ERROR("Failed to read [%s] from CBFS [%s].\n",
552*8617a60dSAndroid Build Coastguard Worker entry_name, cbfs_region);
553*8617a60dSAndroid Build Coastguard Worker return NULL;
554*8617a60dSAndroid Build Coastguard Worker }
555*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Got quirks (%u bytes): %s\n", size, data);
556*8617a60dSAndroid Build Coastguard Worker return (char *)data;
557*8617a60dSAndroid Build Coastguard Worker }
558*8617a60dSAndroid Build Coastguard Worker
quirk_override_custom_label(struct updater_config * cfg,const struct manifest * manifest,const struct model_config * model)559*8617a60dSAndroid Build Coastguard Worker const struct model_config *quirk_override_custom_label(
560*8617a60dSAndroid Build Coastguard Worker struct updater_config *cfg,
561*8617a60dSAndroid Build Coastguard Worker const struct manifest *manifest,
562*8617a60dSAndroid Build Coastguard Worker const struct model_config *model)
563*8617a60dSAndroid Build Coastguard Worker {
564*8617a60dSAndroid Build Coastguard Worker /* If not write protected, no need to apply the hack. */
565*8617a60dSAndroid Build Coastguard Worker if (!is_ap_write_protection_enabled(cfg)) {
566*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Skipped because AP not write protected.\n");
567*8617a60dSAndroid Build Coastguard Worker return NULL;
568*8617a60dSAndroid Build Coastguard Worker }
569*8617a60dSAndroid Build Coastguard Worker
570*8617a60dSAndroid Build Coastguard Worker const struct firmware_image *image = &cfg->image_current;
571*8617a60dSAndroid Build Coastguard Worker assert(image && image->data);
572*8617a60dSAndroid Build Coastguard Worker
573*8617a60dSAndroid Build Coastguard Worker if (strcmp(model->name, "phaser360") == 0) {
574*8617a60dSAndroid Build Coastguard Worker /* b/146876241 */
575*8617a60dSAndroid Build Coastguard Worker const char *key_hash = get_firmware_rootkey_hash(image);
576*8617a60dSAndroid Build Coastguard Worker const char * const DOPEFISH_KEY_HASH =
577*8617a60dSAndroid Build Coastguard Worker "9a1f2cc319e2f2e61237dc51125e35ddd4d20984";
578*8617a60dSAndroid Build Coastguard Worker
579*8617a60dSAndroid Build Coastguard Worker if (key_hash && strcmp(key_hash, DOPEFISH_KEY_HASH) == 0) {
580*8617a60dSAndroid Build Coastguard Worker const char * const dopefish = "phaser360-dopefish";
581*8617a60dSAndroid Build Coastguard Worker WARN("A Phaser360 with Dopefish rootkey - "
582*8617a60dSAndroid Build Coastguard Worker "override custom label to '%s'.\n", dopefish);
583*8617a60dSAndroid Build Coastguard Worker model = manifest_find_model(cfg, manifest, dopefish);
584*8617a60dSAndroid Build Coastguard Worker if (model)
585*8617a60dSAndroid Build Coastguard Worker INFO("Model changed to '%s'.\n", model->name);
586*8617a60dSAndroid Build Coastguard Worker else
587*8617a60dSAndroid Build Coastguard Worker ERROR("No model defined for '%s'.\n", dopefish);
588*8617a60dSAndroid Build Coastguard Worker
589*8617a60dSAndroid Build Coastguard Worker return model;
590*8617a60dSAndroid Build Coastguard Worker }
591*8617a60dSAndroid Build Coastguard Worker }
592*8617a60dSAndroid Build Coastguard Worker return NULL;
593*8617a60dSAndroid Build Coastguard Worker }
594