blob: b1e9810ebd6e80eef3930f7641b770eeb25cc430 [file] [log] [blame]
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001// SPDX-License-Identifier: BSD-2-Clause
2/*
3 * Copyright (C) 2016 The Android Open Source Project
4 */
5
6#include <common.h>
Simon Glass288b29e2019-11-14 12:57:43 -07007#include <command.h>
Simon Glassc7694dd2019-08-01 09:46:46 -06008#include <env.h>
Alex Kiernanf73a7df2018-05-29 15:30:53 +00009#include <fastboot.h>
10#include <fastboot-internal.h>
11#include <fb_mmc.h>
12#include <fb_nand.h>
13#include <part.h>
14#include <stdlib.h>
Xindong Xud9441422024-01-18 10:20:45 +080015#ifdef CONFIG_AMLOGIC_MODIFY
16#include <amlogic/emmc_partitions.h>
17#include <amlogic/storage.h>
18#include <amlogic/aml_efuse.h>
19#include <amlogic/aml_mmc.h>
20
21#include <android_image.h>
22#include <image.h>
23#include <amlogic/store_wrapper.h>
24#include <malloc.h>
25#include <amlogic/image_check.h>
26#include <fs.h>
27#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
28#include <amlogic/anti-rollback.h>
29#endif
30#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +000031
32/**
33 * image_size - final fastboot image size
34 */
35static u32 image_size;
36
37/**
38 * fastboot_bytes_received - number of bytes received in the current download
39 */
40static u32 fastboot_bytes_received;
41
42/**
43 * fastboot_bytes_expected - number of bytes expected in the current download
44 */
45static u32 fastboot_bytes_expected;
46
Xindong Xud9441422024-01-18 10:20:45 +080047#ifdef CONFIG_AMLOGIC_MODIFY
48int busy_flag;
49#endif
50
Alex Kiernanf73a7df2018-05-29 15:30:53 +000051static void okay(char *, char *);
52static void getvar(char *, char *);
Xindong Xud9441422024-01-18 10:20:45 +080053
54#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +000055static void download(char *, char *);
56#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
57static void flash(char *, char *);
58static void erase(char *, char *);
59#endif
Xindong Xud9441422024-01-18 10:20:45 +080060#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +000061static void reboot_bootloader(char *, char *);
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +030062static void reboot_fastbootd(char *, char *);
63static void reboot_recovery(char *, char *);
Xindong Xud9441422024-01-18 10:20:45 +080064#ifdef CONFIG_FASTBOOT_WRITING_CMD
65#ifdef CONFIG_AMLOGIC_MODIFY
66static void fetch(char *, char *);
67#if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
68static void flashing(char *, char *);
69#endif
70#endif
Alex Kiernan3845b902018-05-29 15:30:54 +000071#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
72static void oem_format(char *, char *);
73#endif
Patrick Delaunayb2f6b972021-01-27 14:46:48 +010074#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
75static void oem_partconf(char *, char *);
76#endif
Patrick Delaunay0c0394b2021-01-27 14:46:49 +010077#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
78static void oem_bootbus(char *, char *);
79#endif
Xindong Xud9441422024-01-18 10:20:45 +080080static void set_active_cmd(char *, char *);
81#endif
82
83#ifdef CONFIG_AMLOGIC_MODIFY
84extern int is_partition_logical(char* partition_name);
85#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +000086
Heiko Schocherbc820d52021-02-10 09:29:03 +010087#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
88static void run_ucmd(char *, char *);
89static void run_acmd(char *, char *);
90#endif
91
Alex Kiernanf73a7df2018-05-29 15:30:53 +000092static const struct {
93 const char *command;
94 void (*dispatch)(char *cmd_parameter, char *response);
95} commands[FASTBOOT_COMMAND_COUNT] = {
96 [FASTBOOT_COMMAND_GETVAR] = {
97 .command = "getvar",
98 .dispatch = getvar
99 },
Xindong Xud9441422024-01-18 10:20:45 +0800100#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000101 [FASTBOOT_COMMAND_DOWNLOAD] = {
102 .command = "download",
103 .dispatch = download
104 },
Xindong Xud9441422024-01-18 10:20:45 +0800105#ifdef CONFIG_AMLOGIC_MODIFY
106#if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
107 [FASTBOOT_COMMAND_FLASHING] = {
108 .command = "flashing",
109 .dispatch = flashing
110 },
111#endif
112 [FASTBOOT_COMMAND_FETCH] = {
113 .command = "fetch",
114 .dispatch = fetch
115 },
116#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000117#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
118 [FASTBOOT_COMMAND_FLASH] = {
119 .command = "flash",
120 .dispatch = flash
121 },
122 [FASTBOOT_COMMAND_ERASE] = {
123 .command = "erase",
124 .dispatch = erase
125 },
126#endif
127 [FASTBOOT_COMMAND_BOOT] = {
128 .command = "boot",
129 .dispatch = okay
130 },
Xindong Xud9441422024-01-18 10:20:45 +0800131#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000132 [FASTBOOT_COMMAND_CONTINUE] = {
133 .command = "continue",
134 .dispatch = okay
135 },
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000136 [FASTBOOT_COMMAND_REBOOT_BOOTLOADER] = {
137 .command = "reboot-bootloader",
138 .dispatch = reboot_bootloader
139 },
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +0300140 [FASTBOOT_COMMAND_REBOOT_FASTBOOTD] = {
141 .command = "reboot-fastboot",
142 .dispatch = reboot_fastbootd
143 },
144 [FASTBOOT_COMMAND_REBOOT_RECOVERY] = {
145 .command = "reboot-recovery",
146 .dispatch = reboot_recovery
147 },
Xindong Xud9441422024-01-18 10:20:45 +0800148 [FASTBOOT_COMMAND_REBOOT] = {
149 .command = "reboot",
150 .dispatch = okay
151 },
152#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000153 [FASTBOOT_COMMAND_SET_ACTIVE] = {
154 .command = "set_active",
Xindong Xud9441422024-01-18 10:20:45 +0800155#ifdef CONFIG_AMLOGIC_MODIFY
156 .dispatch = set_active_cmd
157#else
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000158 .dispatch = okay
Xindong Xud9441422024-01-18 10:20:45 +0800159#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000160 },
Alex Kiernan3845b902018-05-29 15:30:54 +0000161#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
162 [FASTBOOT_COMMAND_OEM_FORMAT] = {
163 .command = "oem format",
164 .dispatch = oem_format,
165 },
166#endif
Patrick Delaunayb2f6b972021-01-27 14:46:48 +0100167#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
168 [FASTBOOT_COMMAND_OEM_PARTCONF] = {
169 .command = "oem partconf",
170 .dispatch = oem_partconf,
171 },
172#endif
Patrick Delaunay0c0394b2021-01-27 14:46:49 +0100173#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
174 [FASTBOOT_COMMAND_OEM_BOOTBUS] = {
175 .command = "oem bootbus",
176 .dispatch = oem_bootbus,
177 },
178#endif
Xindong Xud9441422024-01-18 10:20:45 +0800179#endif
Heiko Schocherbc820d52021-02-10 09:29:03 +0100180#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
181 [FASTBOOT_COMMAND_UCMD] = {
182 .command = "UCmd",
183 .dispatch = run_ucmd,
184 },
185 [FASTBOOT_COMMAND_ACMD] = {
186 .command = "ACmd",
187 .dispatch = run_acmd,
188 },
189#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000190};
191
Xindong Xud9441422024-01-18 10:20:45 +0800192#ifdef CONFIG_AMLOGIC_MODIFY
193struct fastboot_read fastboot_readInfo;
194
195static int strcmp_l1(const char *s1, const char *s2)
196{
197 if (!s1 || !s2)
198 return -1;
199 return strncmp(s1, s2, strlen(s1));
200}
201#endif
202
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000203/**
204 * fastboot_handle_command - Handle fastboot command
205 *
206 * @cmd_string: Pointer to command string
207 * @response: Pointer to fastboot response buffer
208 *
209 * Return: Executed command, or -1 if not recognized
210 */
211int fastboot_handle_command(char *cmd_string, char *response)
212{
213 int i;
214 char *cmd_parameter;
215
216 cmd_parameter = cmd_string;
217 strsep(&cmd_parameter, ":");
218
219 for (i = 0; i < FASTBOOT_COMMAND_COUNT; i++) {
Xindong Xud9441422024-01-18 10:20:45 +0800220#ifdef CONFIG_AMLOGIC_MODIFY
221 if (!strcmp_l1(commands[i].command, cmd_string)) {
222 if (commands[i].dispatch) {
223 if (cmd_parameter) {
224 commands[i].dispatch(cmd_parameter,
225 response);
226 } else {
227 commands[i].dispatch(cmd_string,
228 response);
229 }
230 return i;
231 } else {
232 break;
233 }
234 }
235#else
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000236 if (!strcmp(commands[i].command, cmd_string)) {
237 if (commands[i].dispatch) {
238 commands[i].dispatch(cmd_parameter,
239 response);
240 return i;
241 } else {
242 break;
243 }
244 }
Xindong Xud9441422024-01-18 10:20:45 +0800245#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000246 }
247
248 pr_err("command %s not recognized.\n", cmd_string);
249 fastboot_fail("unrecognized command", response);
250 return -1;
251}
252
253/**
254 * okay() - Send bare OKAY response
255 *
256 * @cmd_parameter: Pointer to command parameter
257 * @response: Pointer to fastboot response buffer
258 *
259 * Send a bare OKAY fastboot response. This is used where the command is
260 * valid, but all the work is done after the response has been sent (e.g.
261 * boot, reboot etc.)
262 */
263static void okay(char *cmd_parameter, char *response)
264{
265 fastboot_okay(NULL, response);
266}
267
Xindong Xud9441422024-01-18 10:20:45 +0800268#ifdef CONFIG_AMLOGIC_MODIFY
269void dump_lock_info(LockData_t info)
270{
271#if 0
272 printf("info.version_major = %d\n", info.version_major);
273 printf("info.version_minor = %d\n", info.version_minor);
274 printf("info.unlock_ability = %d\n", info.unlock_ability);
275 printf("info.lock_state = %d\n", info.lock_state);
276 printf("info.lock_critical_state = %d\n", info.lock_critical_state);
277 printf("info.lock_bootloader = %d\n", info.lock_bootloader);
278#endif
279}
280
281static const char* getvar_list[] = {
282 "version-baseband", "version-bootloader", "version", "hw-revision", "max-download-size",
283 "serialno", "product", "off-mode-charge", "variant", "battery-soc-ok",
284 "battery-voltage", "partition-type:boot", "partition-size:boot",
285 "partition-type:system", "partition-size:system", "partition-type:vendor", "partition-size:vendor",
286 "partition-type:odm", "partition-size:odm", "partition-type:data", "partition-size:data",
287 "erase-block-size", "logical-block-size", "secure", "unlocked",
288};
289
290static const char* getvar_list_dynamic[] = {
291 "hw-revision", "battery-voltage", "is-userspace", "is-logical:data",
292 "is-logical:metadata", "is-logical:misc", "is-logical:super", "is-logical:boot",
293 "is-logical:system", "is-logical:vendor", "is-logical:product", "is-logical:odm",
294 "slot-count", "max-download-size", "serialno", "product", "unlocked",
295 "secure", "super-partition-name", "version-baseband", "version-bootloader",
296 "partition-size:boot", "partition-size:metadata", "partition-size:misc",
297 "partition-size:super", "partition-size:data", "version",
298};
299
300static const char* getvar_list_dynamic_ab[] = {
301 "hw-revision", "battery-voltage", "is-userspace", "is-logical:data",
302 "is-logical:misc", "is-logical:super",
303 "is-logical:boot_a", "is-logical:boot_b", "is-logical:system_a", "is-logical:system_b",
304 "is-logical:vendor_a", "is-logical:vendor_b", "is-logical:product_a", "is-logical:product_b",
305 "is-logical:odm_a", "is-logical:odm_b",
306 "slot-count", "max-download-size", "serialno", "product", "unlocked", "has-slot:data",
307 "has-slot:metadata", "has-slot:misc", "has-slot:super", "has-slot:boot",
308 "has-slot:system", "has-slot:vendor", "has-slot:product", "has-slot:odm", "current-slot",
309 "secure", "super-partition-name", "version-baseband", "version-bootloader",
310 "partition-size:super",
311 "partition-size:boot_a", "partition-size:boot_b", "partition-size:misc",
312 "partition-size:data", "version",
313};
314
315
316static const char* getvar_list_ab[] = {
317 "version-baseband", "version-bootloader", "version", "hw-revision", "max-download-size",
318 "serialno", "product", "off-mode-charge", "variant", "battery-soc-ok",
319 "battery-voltage", "partition-type:boot_a", "partition-size:boot_a",
320 "partition-type:system_a", "partition-size:system_a", "partition-type:vendor_a", "partition-size:vendor_a",
321 "partition-type:odm_a", "partition-size:odm_a", "partition-type:data", "partition-size:data",
322 "erase-block-size", "logical-block-size", "secure", "unlocked",
323 "slot-count", "slot-suffixes","current-slot", "has-slot:bootloader", "has-slot:boot",
324 "has-slot:system", "has-slot:vendor", "has-slot:odm", "has-slot:vbmeta",
325 "has-slot:metadata", "has-slot:product", "has-slot:dtbo",
326 "slot-successful:a", "slot-unbootable:a", "slot-retry-count:a",
327 "slot-successful:b", "slot-unbootable:b", "slot-retry-count:b",
328};
329#endif
330
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000331/**
332 * getvar() - Read a config/version variable
333 *
334 * @cmd_parameter: Pointer to command parameter
335 * @response: Pointer to fastboot response buffer
336 */
337static void getvar(char *cmd_parameter, char *response)
338{
Xindong Xud9441422024-01-18 10:20:45 +0800339#ifdef CONFIG_AMLOGIC_MODIFY
340 run_command("get_valid_slot", 0);
341 if (!strncmp(cmd_parameter, "all", 3)) {
342 static int cmdIndex = 0;
343 int getvar_num = 0;
344 char* cmd=cmd_parameter;
345
346 busy_flag = 1;
347
348 if (dynamic_partition && has_boot_slot == 1 && strlen(getvar_list_dynamic_ab[cmdIndex]) < 64) {
349 strncpy(cmd, getvar_list_dynamic_ab[cmdIndex], 64);
350 getvar_num = (sizeof(getvar_list_dynamic_ab) / sizeof(getvar_list_dynamic_ab[0]));
351 } else if (has_boot_slot == 1 && strlen(getvar_list_ab[cmdIndex]) < 64) {
352 strncpy(cmd, getvar_list_ab[cmdIndex], 64);
353 getvar_num = (sizeof(getvar_list_ab) / sizeof(getvar_list_ab[0]));
354 } else if (dynamic_partition && strlen(getvar_list_dynamic[cmdIndex]) < 64) {
355 strncpy(cmd, getvar_list_dynamic[cmdIndex], 64);//only support no-arg cmd
356 getvar_num = (sizeof(getvar_list_dynamic) / sizeof(getvar_list_dynamic[0]));
357 } else if (strlen(getvar_list[cmdIndex]) < 64) {
358 strncpy(cmd, getvar_list[cmdIndex], 64);//only support no-arg cmd
359 getvar_num = (sizeof(getvar_list) / sizeof(getvar_list[0]));
360 }
361 //printf("getvar_num: %d\n", getvar_num);
362 //printf("all cmd:%s\n", cmd);
363 if ( ++cmdIndex >= getvar_num) {
364 cmdIndex = 0;
365 busy_flag = 0;
366 fastboot_okay(NULL, response);
367 } else {
368 fastboot_getvar(cmd, response);
369 }
370
371 }else {
372#endif
373 fastboot_getvar(cmd_parameter, response);
374#ifdef CONFIG_AMLOGIC_MODIFY
375 }
376#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000377}
378
379/**
380 * fastboot_download() - Start a download transfer from the client
381 *
382 * @cmd_parameter: Pointer to command parameter
383 * @response: Pointer to fastboot response buffer
384 */
Xindong Xud9441422024-01-18 10:20:45 +0800385#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000386static void download(char *cmd_parameter, char *response)
387{
388 char *tmp;
389
Xindong Xud9441422024-01-18 10:20:45 +0800390#ifdef CONFIG_AMLOGIC_MODIFY
391 if (check_lock() == 1) {
392 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
393 fastboot_fail("locked device", response);
394 return;
395 }
396#endif
397
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000398 if (!cmd_parameter) {
399 fastboot_fail("Expected command parameter", response);
400 return;
401 }
402 fastboot_bytes_received = 0;
Simon Glass7e5f4602021-07-24 09:03:29 -0600403 fastboot_bytes_expected = hextoul(cmd_parameter, &tmp);
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000404 if (fastboot_bytes_expected == 0) {
405 fastboot_fail("Expected nonzero image size", response);
406 return;
407 }
408 /*
409 * Nothing to download yet. Response is of the form:
410 * [DATA|FAIL]$cmd_parameter
411 *
412 * where cmd_parameter is an 8 digit hexadecimal number
413 */
414 if (fastboot_bytes_expected > fastboot_buf_size) {
Xindong Xud9441422024-01-18 10:20:45 +0800415#ifdef CONFIG_AMLOGIC_MODIFY
416 char str[128] = {0};
417
418 printf("fastboot_bytes_expected %d > fastboot_buf_size %d\n",
419 fastboot_bytes_expected, fastboot_buf_size);
420 sprintf(str, "data too large, please add -S %dM",
421 (fastboot_buf_size / 1024 / 1024));
422 fastboot_fail(str, response);
423#else
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000424 fastboot_fail(cmd_parameter, response);
Xindong Xud9441422024-01-18 10:20:45 +0800425#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000426 } else {
427 printf("Starting download of %d bytes\n",
428 fastboot_bytes_expected);
429 fastboot_response("DATA", response, "%s", cmd_parameter);
430 }
431}
Xindong Xud9441422024-01-18 10:20:45 +0800432#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000433/**
434 * fastboot_data_remaining() - return bytes remaining in current transfer
435 *
436 * Return: Number of bytes left in the current download
437 */
438u32 fastboot_data_remaining(void)
439{
440 return fastboot_bytes_expected - fastboot_bytes_received;
441}
442
443/**
444 * fastboot_data_download() - Copy image data to fastboot_buf_addr.
445 *
446 * @fastboot_data: Pointer to received fastboot data
447 * @fastboot_data_len: Length of received fastboot data
448 * @response: Pointer to fastboot response buffer
449 *
450 * Copies image data from fastboot_data to fastboot_buf_addr. Writes to
451 * response. fastboot_bytes_received is updated to indicate the number
452 * of bytes that have been transferred.
453 *
454 * On completion sets image_size and ${filesize} to the total size of the
455 * downloaded image.
456 */
457void fastboot_data_download(const void *fastboot_data,
458 unsigned int fastboot_data_len,
459 char *response)
460{
461#define BYTES_PER_DOT 0x20000
462 u32 pre_dot_num, now_dot_num;
463
464 if (fastboot_data_len == 0 ||
465 (fastboot_bytes_received + fastboot_data_len) >
466 fastboot_bytes_expected) {
467 fastboot_fail("Received invalid data length",
468 response);
469 return;
470 }
471 /* Download data to fastboot_buf_addr */
472 memcpy(fastboot_buf_addr + fastboot_bytes_received,
473 fastboot_data, fastboot_data_len);
474
475 pre_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
476 fastboot_bytes_received += fastboot_data_len;
477 now_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
478
479 if (pre_dot_num != now_dot_num) {
480 putc('.');
481 if (!(now_dot_num % 74))
482 putc('\n');
483 }
484 *response = '\0';
485}
486
487/**
488 * fastboot_data_complete() - Mark current transfer complete
489 *
490 * @response: Pointer to fastboot response buffer
491 *
492 * Set image_size and ${filesize} to the total size of the downloaded image.
493 */
494void fastboot_data_complete(char *response)
495{
496 /* Download complete. Respond with "OKAY" */
497 fastboot_okay(NULL, response);
498 printf("\ndownloading of %d bytes finished\n", fastboot_bytes_received);
499 image_size = fastboot_bytes_received;
500 env_set_hex("filesize", image_size);
501 fastboot_bytes_expected = 0;
502 fastboot_bytes_received = 0;
503}
504
Xindong Xud9441422024-01-18 10:20:45 +0800505#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000506#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
Xindong Xud9441422024-01-18 10:20:45 +0800507
508#ifdef CONFIG_AMLOGIC_MODIFY
509static void write_dts_reserve(void)
510{
511 int ret;
512 void *addr = NULL;
513 char *mem_addr;
514
515 if (run_command("imgread dtb ${boot_part} ${dtb_mem_addr}", 0)) {
516 printf("Fail in load dtb\n");
517 } else {
518 mem_addr = env_get("dtb_mem_addr");
519
520 if (mem_addr) {
521 addr = (void *)simple_strtoul(mem_addr, NULL, 16);
522 ret = dtb_write(addr);
523 if (ret)
524 printf("write dtb error\n");
525 else
526 printf("write dtb ok\n");
527 }
528 }
529}
530
531static void set_fastboot_flag(void)
532{
533 env_set("default_env", "1");
534 env_set("fastboot_step", "1");
535#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
536 run_command("update_env_part -p default_env;", 0);
537 run_command("update_env_part -p fastboot_step;", 0);
538#else
539 run_command("defenv_reserve;", 0);
540 run_command("setenv default_env 1;", 0);
541 run_command("setenv fastboot_step 1;", 0);
542 run_command("saveenv;", 0);
543#endif//#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
544}
545#endif
546
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000547/**
548 * flash() - write the downloaded image to the indicated partition.
549 *
550 * @cmd_parameter: Pointer to partition name
551 * @response: Pointer to fastboot response buffer
552 *
553 * Writes the previously downloaded image to the partition indicated by
554 * cmd_parameter. Writes to response.
555 */
556static void flash(char *cmd_parameter, char *response)
557{
Xindong Xud9441422024-01-18 10:20:45 +0800558#ifdef CONFIG_AMLOGIC_MODIFY
559 char name[32] = {0};
560 u64 rc = 0;
561 int gpt_flag = -1;
562 int ret = -1;
563
564 if (check_lock() == 1) {
565 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
566 fastboot_fail("locked device", response);
567 return;
568 }
569
570 printf("cmd_parameter: %s\n", cmd_parameter);
571
572#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
573 struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
574 if (mmc && strcmp(cmd_parameter, "bootloader") == 0) {
575 printf("try to read gpt data from bootloader.img\n");
576 struct blk_desc *dev_desc;
577 int erase_flag = 0;
578
579 rc = store_part_size("bootloader_a");
580 if (rc != -1) {
581 fastboot_mmc_erase("bootloader_a", response);
582 fastboot_mmc_flash_write("bootloader_a", fastboot_buf_addr, image_size,
583 response);
584 }
585
586 /* the max size of bootloader.img is 4M, we reserve 128k for gpt.bin
587 * so we put gpt.bin at offset 0x3DFE00
588 * 0 ~ 512 bootloader secure boot, we don't care it here.
589 * 512 ~ 0x3DFDFF original bootloader.img and 0
590 * 0x3DFE00 ~ end gpt.bin
591 */
592
593 dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
594 if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
595 printf("invalid mmc device\n");
596 fastboot_fail("invalid mmc device", response);
597 return;
598 }
599
600 if (is_valid_gpt_buf(dev_desc, fastboot_buf_addr + 0x3DFE00)) {
601 printf("printf normal bootloader.img, no gpt partition table\n");
602 } else {
603 printf("find gpt partition table, update it\n"
604 "and write bootloader to boot0/boot1\n");
605
606 erase_flag = check_gpt_part(dev_desc, fastboot_buf_addr + 0x3DFE00);
607
608 if (erase_flag == 1) {
609 printf("partition changes, erase emmc\n");
610 //run_command("store erase.chip 0;", 0);
611 if (usb_burn_erase_data(0x3)) {
612 printf("partition erase failed!\n");
613 return;
614 }
615 }
616
617 if (write_mbr_and_gpt_partitions(dev_desc, fastboot_buf_addr + 0x3DFE00)) {
618 printf("%s: writing GPT partitions failed\n", __func__);
619 fastboot_fail("writing GPT partitions failed", response);
620 return;
621 }
622
623 if (mmc_device_init(mmc) != 0) {
624 printf(" update gpt partition table fail\n");
625 fastboot_fail("fastboot update gpt partition fail", response);
626 return;
627 }
628 printf("%s: writing GPT partitions ok\n", __func__);
629
630 char *mem_addr;
631 void *addr = NULL;
632 int ret;
633
634 mem_addr = env_get("dtb_mem_addr");
635
636 if (mem_addr && erase_flag == 1) {
637 printf("partition changes, erase emmc\n");
638 //run_command("store erase.chip 0;", 0);
639 if (usb_burn_erase_data(0x3)) {
640 printf("partition erase failed!\n");
641 return;
642 }
643 printf("write _aml_dtb\n");
644 addr = (void *)simple_strtoul(mem_addr, NULL, 16);
645 ret = dtb_write(addr);
646 if (ret)
647 printf("write _aml_dtb error\n");
648 else
649 printf("write _aml_dtb ok\n");
650 }
651 }
652
653 gpt_flag = aml_gpt_valid(mmc);
654 if (gpt_flag == 0)
655 ret = 0;
656
657#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
658 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
659
660 if (*efuse_field.data == 1) {
661 wrnP("efuse_field.data == 1\n");
662 ret = 0;
663 env_set("nocs_mode", "true");
664 } else {
665 wrnP("efuse_field.data != 1\n");
666 env_set("nocs_mode", "false");
667 }
668#endif//#ifdef CONFIG_EFUSE_OBJ_API
669
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000670#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
Xindong Xud9441422024-01-18 10:20:45 +0800671 fastboot_mmc_flash_write("bootloader-boot0", fastboot_buf_addr, image_size,
672 response);
673 fastboot_mmc_flash_write("bootloader-boot1", fastboot_buf_addr, image_size,
674 response);
675 run_command("mmc dev 1 0;", 0);
676#endif
677 set_fastboot_flag();
678 }
679#endif
680
681 if (strcmp(cmd_parameter, "avb_custom_key") == 0) {
682 char* buffer = NULL;
683 char *partition = "misc";
684 AvbKey_t key;
685 printf("avb_custom_key image_size: %d\n", image_size);
686
687 if (image_size > AVB_CUSTOM_KEY_LEN_MAX - sizeof(AvbKey_t)) {
688 printf("key size is too large\n");
689 fastboot_fail("size error", response);
690 return;
691 }
692
693 memcpy(key.magic_name, "AVBK", 4);
694 key.size = image_size;
695 rc = store_part_size(partition);
696
697 buffer = (char *)malloc(AVB_CUSTOM_KEY_LEN_MAX);
698 if (!buffer) {
699 printf("malloc error\n");
700 fastboot_fail("malloc error", response);
701 return;
702 }
703 memset(buffer, 0, AVB_CUSTOM_KEY_LEN_MAX);
704 memcpy(buffer, &key, sizeof(AvbKey_t));
705 memcpy(buffer + sizeof(AvbKey_t), fastboot_buf_addr, image_size);
706
707 store_write((const char *)partition, rc - AVB_CUSTOM_KEY_LEN_MAX,
708 AVB_CUSTOM_KEY_LEN_MAX, (unsigned char *)buffer);
709
710 fastboot_okay(NULL, response);
711 free(buffer);
712 return;
713 }
714
715 if (strcmp(cmd_parameter, "userdata") == 0 || strcmp(cmd_parameter, "data") == 0) {
716 fastboot_okay(NULL, response);
717 return;
718 } else if (strcmp(cmd_parameter, "dts") == 0) {
719 strcpy(name, "dtb");
720 } else {
721 strncpy(name, cmd_parameter, 31);
722 }
723 strcat(name, "\0");
724
725#ifdef CONFIG_BOOTLOADER_CONTROL_BLOCK
726 if (dynamic_partition) {
727 if (is_partition_logical(name) == 0) {
728 printf("logic partition, can not write here.......\n");
729 fastboot_fail("logic partition", response);
730 return;
731 }
732 }
733#endif
734
735#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
736 fastboot_mmc_flash_write(name, fastboot_buf_addr, image_size,
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000737 response);
738#endif
739#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
Xindong Xud9441422024-01-18 10:20:45 +0800740 fastboot_nand_flash_write(name, fastboot_buf_addr, image_size,
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000741 response);
742#endif
Xindong Xud9441422024-01-18 10:20:45 +0800743
744 if (strcmp(name, "bootloader") == 0) {
745 env_set("default_env", "1");
746#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
747 run_command("update_env_part -p default_env;", 0);
748#else
749 run_command("defenv_reserve;saveenv;", 0);
750#endif// #if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
751 }
752
753 if (strcmp(name, "bootloader-boot0") == 0 ||
754 strcmp(name, "bootloader-boot1") == 0) {
755 printf("try to switch back to user\n");
756 run_command("mmc dev 1 0;", 0);
757 }
758
759#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
760 if (mmc && aml_gpt_valid(mmc) == 0) {
761 if (vendor_boot_partition) {
762 if (strcmp_l1("vendor_boot", name) == 0) {
763 printf("gpt mode, write dts to reserve\n");
764 write_dts_reserve();
765 }
766 } else {
767 if (strcmp_l1("boot", name) == 0) {
768 printf("gpt mode, write dts to reserve\n");
769 write_dts_reserve();
770 }
771 }
772 }
773#endif
774
775#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000776}
777
778/**
779 * erase() - erase the indicated partition.
780 *
781 * @cmd_parameter: Pointer to partition name
782 * @response: Pointer to fastboot response buffer
783 *
784 * Erases the partition indicated by cmd_parameter (clear to 0x00s). Writes
785 * to response.
786 */
787static void erase(char *cmd_parameter, char *response)
788{
Xindong Xud9441422024-01-18 10:20:45 +0800789#ifdef CONFIG_AMLOGIC_MODIFY
790 char name[32] = {0};
791 u64 rc = 0;
792
793 if (check_lock() == 1) {
794 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
795 fastboot_fail("locked device", response);
796 return;
797 }
798
799 printf("cmd_parameter: %s\n", cmd_parameter);
800
801#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
802 struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
803 if ((mmc != NULL) && strcmp(cmd_parameter, "bootloader") == 0 && (aml_gpt_valid(mmc) == 0)) {
804 printf("we write gpt partition table to bootloader now\n");
805 printf("plese write bootloader to bootloader-boot0/bootloader-boot1\n");
806 fastboot_okay("gpt mode, skip", response);
807 return;
808 }
809#endif
810
811 if (strcmp(cmd_parameter, "avb_custom_key") == 0) {
812 char* buffer = NULL;
813 char *partition = "misc";
814
815 rc = store_part_size(partition);
816 buffer = (char *)malloc(AVB_CUSTOM_KEY_LEN_MAX);
817 if (!buffer) {
818 printf("malloc error\n");
819 fastboot_fail("malloc error", response);
820 return;
821 }
822 memset(buffer, 0, AVB_CUSTOM_KEY_LEN_MAX);
823
824 store_write((const char *)partition, rc - AVB_CUSTOM_KEY_LEN_MAX,
825 AVB_CUSTOM_KEY_LEN_MAX, (unsigned char *)buffer);
826
827 fastboot_okay(NULL, response);
828 free(buffer);
829 return;
830 }
831
832 if (strcmp(cmd_parameter, "env") == 0) {
833 char *fastboot_step = env_get("fastboot_step");
834
835 if (fastboot_step && strcmp(fastboot_step, "0")) {
836 printf("fastboot_step: %s, run defenv_reserv\n", fastboot_step);
837 run_command("defenv_reserv; setenv upgrade_step 2; saveenv;", 0);
838 run_command("run bcb_cmd", 0);
839 fastboot_okay(NULL, response);
840 return;
841 }
842 }
843
844 if (strcmp(cmd_parameter, "misc") == 0) {
845 char* buffer = NULL;
846 char *partition = "misc";
847
848 rc = store_part_size(partition);
849 buffer = (char *)malloc(rc - AVB_CUSTOM_KEY_LEN_MAX);
850 if (!buffer) {
851 printf("malloc error\n");
852 fastboot_fail("malloc error", response);
853 return;
854 }
855 memset(buffer, 0, rc - AVB_CUSTOM_KEY_LEN_MAX);
856
857 store_write((const char *)partition, 0, rc - AVB_CUSTOM_KEY_LEN_MAX,
858 (unsigned char *)buffer);
859
860 fastboot_okay(NULL, response);
861 free(buffer);
862 return;
863 }
864
865 if (strcmp(cmd_parameter, "userdata") == 0 || strcmp(cmd_parameter, "data") == 0) {
866 rc = store_part_size("userdata");
867 if (-1 == rc)
868 strcpy(name, "data");
869 else
870 strcpy(name, "userdata");
871 } else if (strcmp(cmd_parameter, "dts") == 0) {
872 strcpy(name, "dtb");
873 } else {
874 strncpy(name, cmd_parameter, 31);
875 }
876 strcat(name, "\0");
877
878#ifdef CONFIG_BOOTLOADER_CONTROL_BLOCK
879 if (dynamic_partition) {
880 if (is_partition_logical(name) == 0) {
881 printf("logic partition, can not erase here.......\n");
882 fastboot_fail("logic partition", response);
883 return;
884 }
885 }
886#endif
887
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000888#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
Xindong Xud9441422024-01-18 10:20:45 +0800889 fastboot_mmc_erase(name, response);
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000890#endif
891#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
Xindong Xud9441422024-01-18 10:20:45 +0800892 fastboot_nand_erase(name, response);
893#endif
894
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000895#endif
896}
897#endif
Xindong Xud9441422024-01-18 10:20:45 +0800898#endif
899
900#ifdef CONFIG_FASTBOOT_WRITING_CMD
901
902#ifdef CONFIG_AMLOGIC_MODIFY
903static u64 my_ato11(const char *str)
904{
905 u64 result = 0;
906 int len, i;
907
908 len = strlen(str);
909 for (i = 0; i < len; i++) {
910 if (*str >= '0' && *str <= '9')
911 result = result * 16 + (*str - '0');
912 else if (*str >= 'A' && *str <= 'F')
913 result = result * 16 + (*str - 'A') + 10;
914 else if (*str >= 'a' && *str <= 'f')
915 result = result * 16 + (*str - 'a') + 10;
916 str++;
917 }
918
919 return result;
920}
921
922static void fetch(char *cmd_parameter, char *response)
923{
924 int len;
925 int i = 0;
926 char *cmd;
927 char name[32] = {0};
928 u64 offset = 0;
929 u64 read_size = 0;
930 size_t size = 0;
931
932 if (check_lock() == 1) {
933 printf("device is locked, can not run this cmd\n");
934 fastboot_fail("locked device", response);
935 return;
936 }
937
938 cmd = cmd_parameter;
939 len = strlen(cmd_parameter);
940 while (strsep(&cmd, ":"))
941 i++;
942
943 for (cmd = cmd_parameter, i = 0; cmd < (cmd_parameter + len); i++) {
944 /* Skip to next assignment */
945 if (i == 0) {
946 strncpy(name, cmd, 31);
947 strcat(name, "\0");
948 } else if (i == 1) {
949 offset = my_ato11(cmd);
950 } else if (i == 2) {
951 read_size = my_ato11(cmd);
952 }
953
954 for (cmd += strlen(cmd); cmd < (cmd_parameter + len) && !*cmd;)
955 cmd++;
956 }
957
958 printf("name: %s\n", name);
959 if (strncmp("vendor_boot", name, strlen("vendor_boot")) != 0) {
960 printf("We can only %s vendor_boot\n", __func__);
961 fastboot_fail("Fetch is only allowed on vendor_boot", response);
962 return;
963 }
964
965#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
966 struct blk_desc *dev_desc;
967 disk_partition_t part_info;
968 int r;
969
970 r = fastboot_mmc_get_part_info(name, &dev_desc, &part_info,
971 response);
972 if (r >= 0)
973 size = part_info.size * 512;
974#endif
975#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
976 struct part_info *part_info;
977 int r;
978
979 r = fastboot_nand_get_part_info(name, &part_info, response);
980 if (r >= 0)
981 size = part_info->size * 512;
982#endif
983
984 if (offset > size) {
985 printf("Invalid offset: 0x%llx, partition size is 0x%lx\n",
986 offset, size);
987 fastboot_fail("Invalid offset", response);
988 return;
989 }
990
991 if (read_size == 0 || read_size > size - offset ||
992 read_size > kMaxFetchSizeDefault) {
993 printf("Invalid read size: 0x%llx, partition size is 0x%lx\n",
994 offset, size);
995 fastboot_fail("Invalid read size", response);
996 return;
997 }
998
999 printf("Start read %s partition datas!\n", name);
1000 void *buffer;
1001 char str[128] = {0};
1002
1003 buffer = (void *)CONFIG_FASTBOOT_BUF_ADDR;
1004 sprintf(str, "DATA%12llx", read_size);
1005 printf("str: %s, len: %ld\n", str, strlen(str));
1006 memcpy(buffer, str, strlen(str));
1007
1008 if (store_read((const char *)name, offset, read_size,
1009 (unsigned char *)buffer + strlen(str)) < 0) {
1010 printf("failed to store read %s.\n", name);
1011 fastboot_fail("read partition data error", response);
1012 return;
1013 }
1014
1015 fastboot_readInfo.transferredBytes = 0;
1016 fastboot_readInfo.totalBytes = read_size + strlen(str);
1017 fastboot_response("DATA", response, "%12llx", read_size);
1018}
1019
1020static void set_active_cmd(char *cmd_parameter, char *response)
1021{
1022 char *cmd;
1023 int ret = 0;
1024 char str[128];
1025
1026 printf("cmd cb_set_active is %s\n", cmd_parameter);
1027 cmd = cmd_parameter;
1028
1029 if (check_lock() == 1) {
1030 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
1031 fastboot_fail("locked device", response);
1032 return;
1033 }
1034
1035 sprintf(str, "set_active_slot %s", cmd);
1036 printf("command: %s\n", str);
1037 ret = run_command(str, 0);
1038 printf("ret = %d\n", ret);
1039 if (ret == 0)
1040 fastboot_okay(NULL, response);
1041 else
1042 fastboot_fail("set slot error", response);
1043}
1044
1045#if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
1046static void try_unlock_dev(u64 rc)
1047{
1048#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
1049 if (is_avb_arb_available()) {
1050 if (avb_unlock()) {
1051 if (-1 == rc) {
1052 printf("unlocking device. Erasing data partition!\n");
1053 run_command("store erase data 0 0", 0);
1054 } else {
1055 printf("unlocking device. Erasing userdata partition!\n");
1056 run_command("store erase userdata 0 0", 0);
1057 }
1058 printf("unlocking device. Erasing metadata partition!\n");
1059 run_command("store erase metadata 0 0", 0);
1060 } else {
1061 printf("unlock failed!\n");
1062 }
1063
1064 return;
1065 }
1066#endif
1067 if (-1 == rc) {
1068 printf("unlocking device. Erasing data partition!\n");
1069 run_command("store erase data 0 0", 0);
1070 } else {
1071 printf("unlocking device. Erasing userdata partition!\n");
1072 run_command("store erase userdata 0 0", 0);
1073 }
1074 printf("unlocking device. Erasing metadata partition!\n");
1075 run_command("store erase metadata 0 0", 0);
1076}
1077
1078static void try_lock_dev(u64 rc)
1079{
1080#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
1081 if (is_avb_arb_available()) {
1082 if (avb_lock()) {
1083 if (-1 == rc) {
1084 printf("locking device. Erasing data partition!\n");
1085 run_command("store erase data 0 0", 0);
1086 } else {
1087 printf("locking device. Erasing userdata partition!\n");
1088 run_command("store erase userdata 0 0", 0);
1089 }
1090 printf("locking device. Erasing metadata partition!\n");
1091 run_command("store erase metadata 0 0", 0);
1092 } else {
1093 printf("lock failed!\n");
1094 }
1095
1096 return;
1097 }
1098#endif
1099 if (-1 == rc) {
1100 printf("locking device. Erasing data partition!\n");
1101 run_command("store erase data 0 0", 0);
1102 } else {
1103 printf("locking device. Erasing userdata partition!\n");
1104 run_command("store erase userdata 0 0", 0);
1105 }
1106 printf("locking device. Erasing metadata partition!\n");
1107 run_command("store erase metadata 0 0", 0);
1108}
1109
1110/**
1111 * flashing() - lock/unlock.
1112 *
1113 * @cmd_parameter: Pointer to partition name
1114 * @response: Pointer to fastboot response buffer
1115 *
1116 * Writes the previously downloaded image to the partition indicated by
1117 * cmd_parameter. Writes to response.
1118 */
1119static void flashing(char *cmd_parameter, char *response)
1120{
1121 char *cmd;
1122 char* lock_s;
1123 LockData_t info = {0};
1124 char lock_d[LOCK_DATA_SIZE];
1125 u64 rc;
1126 int debug_flag = 0;
1127
1128 if (IS_FEAT_BOOT_VERIFY()) {
1129 printf("device is secure mode, can not run this cmd.\n");
1130 fastboot_fail("secure boot device", response);
1131 return;
1132 }
1133
1134 lock_s = env_get("lock");
1135 if (!lock_s) {
1136 printf("lock state is NULL \n");
1137 memcpy(lock_d, "10101000", 8);
1138 lock_s = "10101000";
1139 env_set("lock", "10101000");
1140#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1141 run_command("update_env_part -p lock;", 0);
1142#else
1143 run_command("defenv_reserv; saveenv;", 0);
1144#endif//#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1145 } else {
1146 printf("lock state: %s\n", lock_s);
1147 if (strlen(lock_s) > 15)
1148 strncpy(lock_d, lock_s, 15);
1149 else
1150 strncpy(lock_d, lock_s, strlen(lock_s));
1151 }
1152
1153 info.version_major = (int)(lock_d[0] - '0');
1154 info.version_minor = (int)(lock_d[1] - '0');
1155 info.unlock_ability = (int)(lock_d[2] - '0');
1156 info.lock_state = (int)(lock_d[4] - '0');
1157 info.lock_critical_state = (int)(lock_d[5] - '0');
1158 info.lock_bootloader = (int)(lock_d[6] - '0');
1159 dump_lock_info(info);
1160
1161 printf("cb_flashing cmd_parameter: %s\n", cmd_parameter);
1162 cmd = cmd_parameter;
1163 strsep(&cmd, " ");
1164 printf("cb_flashing: %s\n", cmd);
1165 if (!cmd) {
1166 printf("missing variable\n");
1167 fastboot_fail("missing var", response);
1168 return;
1169 }
1170
1171 boot_img_hdr_t *hdr_addr = NULL;
1172 const int preloadsz = 0x1000 * 2;//4k not enough for signed
1173 unsigned char *pbuffpreload = 0;
1174 char partname[32] = {0};
1175 char *slot_name;
1176 char cmdline[4096];
1177 char *result = NULL;
1178
1179 slot_name = env_get("slot-suffixes");
1180 if (slot_name && (strcmp(slot_name, "0") == 0))
1181 strcpy((char *)partname, "boot_a");
1182 else if (slot_name && (strcmp(slot_name, "1") == 0))
1183 strcpy((char *)partname, "boot_b");
1184 else
1185 strcpy((char *)partname, "boot");
1186
1187 pbuffpreload = malloc(preloadsz);
1188 if (!pbuffpreload) {
1189 printf("Fail to allocate memory!\n");
1190 goto next;
1191 }
1192
1193 hdr_addr = (boot_img_hdr_t *)pbuffpreload;
1194
1195 printf("read from part: %s\n", partname);
1196 rc = store_logic_read(partname, 0, preloadsz, pbuffpreload);
1197 if (rc) {
1198 printf("Fail to read 0x%xB from part[%s] at offset 0\n",
1199 preloadsz, partname);
1200 free(pbuffpreload);
1201 pbuffpreload = 0;
1202 goto next;
1203 }
1204
1205 if (is_android_r_image((void *)hdr_addr)) {
1206 char partname_r[32] = {0};
1207 const int preloadsz_r = 0x1000 * 2;//4k not enough for signed
1208 unsigned char *pbuffpreload_r = 0;
1209 int ret_r = __LINE__;
1210
1211 if (slot_name && (strcmp(slot_name, "0") == 0))
1212 strcpy((char *)partname_r, "vendor_boot_a");
1213 else if (slot_name && (strcmp(slot_name, "1") == 0))
1214 strcpy((char *)partname_r, "vendor_boot_b");
1215 else
1216 strcpy((char *)partname_r, "vendor_boot");
1217
1218 pbuffpreload_r = malloc(preloadsz_r);
1219
1220 if (!pbuffpreload_r) {
1221 printf("Fail to allocate memory for %s!\n",
1222 partname_r);
1223 goto next;
1224 }
1225
1226 printf("read from part: %s\n", partname_r);
1227 ret_r = store_logic_read(partname_r, 0,
1228 preloadsz_r, pbuffpreload_r);
1229 if (ret_r) {
1230 printf("Fail to read 0x%xB from part[%s] at offset 0\n",
1231 preloadsz_r, partname_r);
1232 free(pbuffpreload_r);
1233 pbuffpreload_r = 0;
1234 goto next;
1235 }
1236
1237 p_vendor_boot_img_hdr_t vb_hdr = (p_vendor_boot_img_hdr_t)pbuffpreload_r;
1238
1239 if (*vb_hdr->cmdline) {
1240 printf("Kernel command line: %s\n", vb_hdr->cmdline);
1241 sprintf(cmdline, "%s", vb_hdr->cmdline);
1242 }
1243 free(pbuffpreload_r);
1244 pbuffpreload_r = 0;
1245 } else {
1246 if (*hdr_addr->cmdline) {
1247 printf("Kernel command line: %s\n", hdr_addr->cmdline);
1248 sprintf(cmdline, "%s", hdr_addr->cmdline);
1249 }
1250 }
1251
1252 free(pbuffpreload);
1253 pbuffpreload = 0;
1254
1255 result = strtok(cmdline, " ");
1256 while (result) {
1257 printf("result: %s\n", result);
1258 if (strcmp(result, "buildvariant=userdebug") == 0 ||
1259 strcmp(result, "buildvariant=eng") == 0)
1260 debug_flag = 1;
1261 result = strtok(NULL, " ");
1262 }
1263
1264 if (info.unlock_ability == 0 && debug_flag == 1) {
1265 printf("userdebug mode can ignore\n");
1266 info.unlock_ability = 1;
1267 }
1268
1269next:
1270 rc = store_part_size("userdata");
1271
1272 if (!strcmp_l1("unlock_critical", cmd)) {
1273 info.lock_critical_state = 0;
1274 fastboot_okay(NULL, response);
1275 } else if (!strcmp_l1("lock_critical", cmd)) {
1276 info.lock_critical_state = 1;
1277 fastboot_okay(NULL, response);
1278 } else if (!strcmp_l1("get_unlock_ability", cmd)) {
1279 char str[32];
1280 static bool is_unlock_ability_sent = false;
1281 if (is_unlock_ability_sent) {
1282 is_unlock_ability_sent = false;
1283 fastboot_okay(NULL, response);
1284 busy_flag = 0;
1285 } else {
1286 sprintf(str, "get_unlock_ability: %d",
1287 info.unlock_ability);
1288 fastboot_response("INFO", response, "%s", str);
1289 is_unlock_ability_sent = true;
1290 busy_flag = 1;
1291 }
1292 return;
1293 } else if (!strcmp_l1("get_unlock_bootloader_nonce", cmd)) {
1294 char str_num[8];
1295 sprintf(str_num, "%d", info.lock_critical_state);
1296 fastboot_response("OKAY", response, "%s", str_num);
1297 } else if (!strcmp_l1("lock_bootloader", cmd)) {
1298 info.lock_bootloader = 1;
1299 } else if (!strcmp_l1("unlock", cmd)) {
1300 if (info.unlock_ability == 1) {
1301 if (info.lock_state == 1) {
1302 char *avb_s;
1303
1304 run_command("get_avb_mode;", 0);
1305 avb_s = env_get("avb2");
1306 printf("avb2: %s\n", avb_s);
1307 if (strcmp(avb_s, "1") == 0) {
1308 try_unlock_dev(rc);
1309 }
1310 }
1311 info.lock_state = 0;
1312 info.lock_critical_state = 0;
1313 env_set("lock_state", "green");
1314 fastboot_okay(NULL, response);
1315 } else {
1316 printf("unlock_ability is 0, can not unlock, please set it in android setting\n");
1317 fastboot_response("FAIL", response, "%s", "unlock_ability is 0, can not unlock");
1318 }
1319 } else if (!strcmp_l1("lock", cmd)) {
1320 if (info.lock_state == 0) {
1321 char *avb_s;
1322
1323 run_command("get_avb_mode;", 0);
1324 avb_s = env_get("avb2");
1325 printf("avb2: %s\n", avb_s);
1326 if (strcmp(avb_s, "1") == 0) {
1327 try_lock_dev(rc);
1328 }
1329 }
1330 info.lock_state = 1;
1331 env_set("lock_state", "orange");
1332 fastboot_okay(NULL, response);
1333 } else {
1334 printf("unknown variable: %s\n", cmd);
1335 fastboot_response("FAIL", response, "%s", "Variable not implemented");
1336 }
1337
1338 sprintf(lock_d, "%d%d%d0%d%d%d0", info.version_major, info.version_minor,
1339 info.unlock_ability, info.lock_state, info.lock_critical_state,
1340 info.lock_bootloader);
1341 printf("lock_d state: %s\n", lock_d);
1342 env_set("lock", lock_d);
1343#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1344 run_command("update_env_part -p lock;", 0);
1345#else
1346 run_command("defenv_reserv; saveenv;", 0);
1347#endif//#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1348 return;
1349}
1350#endif// #if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
1351#endif
1352#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001353
Heiko Schocherbc820d52021-02-10 09:29:03 +01001354#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
1355/**
1356 * run_ucmd() - Execute the UCmd command
1357 *
1358 * @cmd_parameter: Pointer to command parameter
1359 * @response: Pointer to fastboot response buffer
1360 */
1361static void run_ucmd(char *cmd_parameter, char *response)
1362{
1363 if (!cmd_parameter) {
1364 pr_err("missing slot suffix\n");
1365 fastboot_fail("missing command", response);
1366 return;
1367 }
1368
1369 if (run_command(cmd_parameter, 0))
1370 fastboot_fail("", response);
1371 else
1372 fastboot_okay(NULL, response);
1373}
1374
1375static char g_a_cmd_buff[64];
1376
1377void fastboot_acmd_complete(void)
1378{
1379 run_command(g_a_cmd_buff, 0);
1380}
1381
1382/**
1383 * run_acmd() - Execute the ACmd command
1384 *
1385 * @cmd_parameter: Pointer to command parameter
1386 * @response: Pointer to fastboot response buffer
1387 */
1388static void run_acmd(char *cmd_parameter, char *response)
1389{
1390 if (!cmd_parameter) {
1391 pr_err("missing slot suffix\n");
1392 fastboot_fail("missing command", response);
1393 return;
1394 }
1395
1396 if (strlen(cmd_parameter) > sizeof(g_a_cmd_buff)) {
1397 pr_err("too long command\n");
1398 fastboot_fail("too long command", response);
1399 return;
1400 }
1401
1402 strcpy(g_a_cmd_buff, cmd_parameter);
1403 fastboot_okay(NULL, response);
1404}
1405#endif
1406
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001407/**
1408 * reboot_bootloader() - Sets reboot bootloader flag.
1409 *
1410 * @cmd_parameter: Pointer to command parameter
1411 * @response: Pointer to fastboot response buffer
1412 */
1413static void reboot_bootloader(char *cmd_parameter, char *response)
1414{
Xindong Xud9441422024-01-18 10:20:45 +08001415#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi851737a2020-07-28 23:35:32 +03001416 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_BOOTLOADER))
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001417 fastboot_fail("Cannot set reboot flag", response);
1418 else
Xindong Xud9441422024-01-18 10:20:45 +08001419#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001420 fastboot_okay(NULL, response);
1421}
Alex Kiernan3845b902018-05-29 15:30:54 +00001422
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001423/**
1424 * reboot_fastbootd() - Sets reboot fastboot flag.
1425 *
1426 * @cmd_parameter: Pointer to command parameter
1427 * @response: Pointer to fastboot response buffer
1428 */
1429static void reboot_fastbootd(char *cmd_parameter, char *response)
1430{
Xindong Xud9441422024-01-18 10:20:45 +08001431#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001432 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_FASTBOOTD))
Xindong Xud9441422024-01-18 10:20:45 +08001433 fastboot_fail("Cannot set reboot flag", response);
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001434 else
Xindong Xud9441422024-01-18 10:20:45 +08001435#endif
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001436 fastboot_okay(NULL, response);
1437}
1438
1439/**
1440 * reboot_recovery() - Sets reboot recovery flag.
1441 *
1442 * @cmd_parameter: Pointer to command parameter
1443 * @response: Pointer to fastboot response buffer
1444 */
1445static void reboot_recovery(char *cmd_parameter, char *response)
1446{
Xindong Xud9441422024-01-18 10:20:45 +08001447#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001448 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_RECOVERY))
Xindong Xud9441422024-01-18 10:20:45 +08001449 fastboot_fail("Cannot set reboot flag", response);
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001450 else
Xindong Xud9441422024-01-18 10:20:45 +08001451#endif
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001452 fastboot_okay(NULL, response);
1453}
1454
Xindong Xud9441422024-01-18 10:20:45 +08001455#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernan3845b902018-05-29 15:30:54 +00001456#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
1457/**
1458 * oem_format() - Execute the OEM format command
1459 *
1460 * @cmd_parameter: Pointer to command parameter
1461 * @response: Pointer to fastboot response buffer
1462 */
1463static void oem_format(char *cmd_parameter, char *response)
1464{
1465 char cmdbuf[32];
1466
Xindong Xud9441422024-01-18 10:20:45 +08001467#ifdef CONFIG_AMLOGIC_MODIFY
1468 if (IS_FEAT_BOOT_VERIFY()) {
1469 printf("device is secure mode, can not run this cmd.\n");
1470 fastboot_fail("secure boot device", response);
1471 return;
1472 }
1473
1474 if (check_lock() == 1) {
1475 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
1476 fastboot_fail("locked device", response);
1477 return;
1478 }
1479#endif
1480
Alex Kiernan3845b902018-05-29 15:30:54 +00001481 if (!env_get("partitions")) {
1482 fastboot_fail("partitions not set", response);
1483 } else {
1484 sprintf(cmdbuf, "gpt write mmc %x $partitions",
1485 CONFIG_FASTBOOT_FLASH_MMC_DEV);
1486 if (run_command(cmdbuf, 0))
1487 fastboot_fail("", response);
1488 else
1489 fastboot_okay(NULL, response);
1490 }
1491}
1492#endif
Patrick Delaunayb2f6b972021-01-27 14:46:48 +01001493
1494#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
1495/**
1496 * oem_partconf() - Execute the OEM partconf command
1497 *
1498 * @cmd_parameter: Pointer to command parameter
1499 * @response: Pointer to fastboot response buffer
1500 */
1501static void oem_partconf(char *cmd_parameter, char *response)
1502{
1503 char cmdbuf[32];
1504
1505 if (!cmd_parameter) {
1506 fastboot_fail("Expected command parameter", response);
1507 return;
1508 }
1509
1510 /* execute 'mmc partconfg' command with cmd_parameter arguments*/
1511 snprintf(cmdbuf, sizeof(cmdbuf), "mmc partconf %x %s 0",
1512 CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
1513 printf("Execute: %s\n", cmdbuf);
1514 if (run_command(cmdbuf, 0))
1515 fastboot_fail("Cannot set oem partconf", response);
1516 else
1517 fastboot_okay(NULL, response);
1518}
1519#endif
Patrick Delaunay0c0394b2021-01-27 14:46:49 +01001520
1521#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
1522/**
1523 * oem_bootbus() - Execute the OEM bootbus command
1524 *
1525 * @cmd_parameter: Pointer to command parameter
1526 * @response: Pointer to fastboot response buffer
1527 */
1528static void oem_bootbus(char *cmd_parameter, char *response)
1529{
1530 char cmdbuf[32];
1531
1532 if (!cmd_parameter) {
1533 fastboot_fail("Expected command parameter", response);
1534 return;
1535 }
1536
1537 /* execute 'mmc bootbus' command with cmd_parameter arguments*/
1538 snprintf(cmdbuf, sizeof(cmdbuf), "mmc bootbus %x %s",
1539 CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
1540 printf("Execute: %s\n", cmdbuf);
1541 if (run_command(cmdbuf, 0))
1542 fastboot_fail("Cannot set oem bootbus", response);
1543 else
1544 fastboot_okay(NULL, response);
1545}
1546#endif
Xindong Xud9441422024-01-18 10:20:45 +08001547#endif