blob: 8fdc0c8992a87ba54615ccf934b8ad40ea360bd9 [file] [log] [blame]
Brian Swetland9c4c0752009-01-25 16:23:50 -08001/*
2 * Copyright (c) 2009, Google Inc.
3 * All rights reserved.
4 *
Mayank Grover98c4c742019-04-25 17:21:37 +05305 * Copyright (c) 2009-2019, The Linux Foundation. All rights reserved.
Brian Swetland9c4c0752009-01-25 16:23:50 -08006 *
Chandan Uddaraju5fa471a2009-12-02 17:31:34 -08007 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070014 * * Neither the name of The Linux Foundation nor
Chandan Uddaraju5fa471a2009-12-02 17:31:34 -080015 * the names of its contributors may be used to endorse or promote
16 * products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
Brian Swetland9c4c0752009-01-25 16:23:50 -080031 */
32
33#include <app.h>
34#include <debug.h>
35#include <arch/arm.h>
Brian Swetland9c4c0752009-01-25 16:23:50 -080036#include <string.h>
Channagoud Kadabi132ff552013-04-19 14:34:44 -070037#include <stdlib.h>
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -070038#include <limits.h>
Brian Swetland9c4c0752009-01-25 16:23:50 -080039#include <kernel/thread.h>
40#include <arch/ops.h>
41
Dima Zavin214cc642009-01-26 11:16:21 -080042#include <dev/flash.h>
Tanya Brokhman1c94f1a2015-02-15 09:05:03 +020043#include <dev/flash-ubi.h>
Dima Zavin214cc642009-01-26 11:16:21 -080044#include <lib/ptable.h>
Dima Zavinb4283602009-01-26 16:36:57 -080045#include <dev/keys.h>
Shashank Mittal4f99a882010-02-01 13:58:50 -080046#include <dev/fbcon.h>
Ajay Dudanid04110c2011-01-17 23:55:07 -080047#include <baseband.h>
Greg Griscod6250552011-06-29 14:40:23 -070048#include <target.h>
49#include <mmc.h>
Kinson Chikf1a43512011-07-14 11:28:39 -070050#include <partition_parser.h>
Mayank Grover351a75e2017-05-30 20:06:08 +053051#include <ab_partition_parser.h>
Monika Singh292b3e92018-03-17 22:40:23 +053052#include <verifiedboot.h>
Greg Griscod6250552011-06-29 14:40:23 -070053#include <platform.h>
Shashank Mittalcd98d472011-08-02 14:29:24 -070054#include <crypto_hash.h>
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070055#include <malloc.h>
Amol Jadi492d5a52013-03-15 16:12:34 -070056#include <boot_stats.h>
Amir Samuelov57a6fa22013-06-05 16:36:43 +030057#include <sha.h>
Sundarajan Srinivasan3827a102013-09-10 13:57:40 -070058#include <platform/iomap.h>
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -070059#include <boot_device.h>
Shashank Mittald3e54dd2014-08-28 15:24:02 -070060#include <boot_verifier.h>
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +053061#include <image_verify.h>
Matthew Qinbb7923d2015-02-09 10:56:09 +080062#include <decompress.h>
Unnati Gandhi17b3bfc2015-05-11 12:58:16 +053063#include <platform/timer.h>
lijuang511a2b52015-08-14 20:50:51 +080064#include <sys/types.h>
Channagoud Kadabi036c6052015-02-09 15:19:59 -080065#if USE_RPMB_FOR_DEVINFO
66#include <rpmb.h>
67#endif
Dima Zavin214cc642009-01-26 11:16:21 -080068
Channagoud Kadabi90869ce2015-04-27 11:15:14 -070069#if ENABLE_WBC
Umang Chheda4c140de2019-12-19 14:30:38 +053070#include <pm_smbchg_common.h>
Channagoud Kadabi90869ce2015-04-27 11:15:14 -070071#endif
72
Neeti Desai17379b82012-06-04 18:42:53 -070073#if DEVICE_TREE
74#include <libfdt.h>
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070075#include <dev_tree.h>
Neeti Desai17379b82012-06-04 18:42:53 -070076#endif
77
Aparna Mallavarapu118ccae2015-06-03 13:47:11 +053078#if WDOG_SUPPORT
79#include <wdog.h>
80#endif
81
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -070082#include <reboot.h>
Shashank Mittalcd98d472011-08-02 14:29:24 -070083#include "image_verify.h"
Shashank Mittal024c0332010-02-03 11:44:00 -080084#include "recovery.h"
Brian Swetland9c4c0752009-01-25 16:23:50 -080085#include "bootimg.h"
86#include "fastboot.h"
Ajay Dudani5c761132011-04-07 20:19:04 -070087#include "sparse_format.h"
Ajay Dudanide984792015-03-02 09:57:41 -080088#include "meta_format.h"
Greg Grisco6e754772011-06-23 12:19:39 -070089#include "mmc.h"
Shashank Mittal162244e2011-08-08 19:01:25 -070090#include "devinfo.h"
Neeti Desai465491e2012-07-31 12:53:35 -070091#include "board.h"
Shashank Mittal162244e2011-08-08 19:01:25 -070092#include "scm.h"
Amit Blay6281ebc2015-01-11 14:44:08 +020093#include "mdtp.h"
Sridhar Parasuram32b30662015-07-10 13:33:22 -070094#include "secapp_loader.h"
lijuanga40d6302015-07-20 20:10:13 +080095#include <menu_keys_detect.h>
96#include <display_menu.h>
Channagoud Kadabi736c4962015-08-21 11:56:52 -070097#include "fastboot_test.h"
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -070098
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070099extern bool target_use_signed_kernel(void);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700100extern void platform_uninit(void);
Channagoud Kadabi33defe22013-06-18 18:35:40 -0700101extern void target_uninit(void);
Joonwoo Park61112782013-10-02 19:50:39 -0700102extern int get_target_boot_params(const char *cmdline, const char *part,
vijay kumar870515d2015-08-31 16:37:24 +0530103 char **buf);
AnilKumar Chimata7fb62f92017-07-11 12:30:17 +0530104extern int qseecom_test_cmd_handler(const char *arg);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700105
Sridhar Parasuram7e16d172015-07-05 11:35:23 -0700106void *info_buf;
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700107void write_device_info_mmc(device_info *dev);
108void write_device_info_flash(device_info *dev);
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -0700109static int aboot_save_boot_hash_mmc(uint32_t image_addr, uint32_t image_size);
Channagoud Kadabiad259832015-05-29 11:14:17 -0700110static int aboot_frp_unlock(char *pname, void *data, unsigned sz);
Kishor PK38ed93d2017-04-25 14:19:26 +0530111static inline uint64_t validate_partition_size();
Parth Dixit54ac3bb2017-03-07 15:52:48 +0530112bool pwr_key_is_pressed = false;
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530113static bool is_systemd_present=false;
Mayank Grover351a75e2017-05-30 20:06:08 +0530114static void publish_getvar_multislot_vars();
Sridhar Parasurame94e8152014-10-24 14:06:03 -0700115/* fastboot command function pointer */
116typedef void (*fastboot_cmd_fn) (const char *, void *, unsigned);
Monika Singh292b3e92018-03-17 22:40:23 +0530117bool get_perm_attr_status();
Sridhar Parasurame94e8152014-10-24 14:06:03 -0700118
119struct fastboot_cmd_desc {
120 char * name;
121 fastboot_cmd_fn cb;
122};
123
Subbaraman Narayanamurthyeb92bcc2010-07-20 14:32:46 -0700124#define EXPAND(NAME) #NAME
125#define TARGET(NAME) EXPAND(NAME)
Brian Swetland2defe162009-08-18 14:35:59 -0700126
Ajay Singh Parmara7865a82015-04-16 21:27:52 -0700127#define DISPLAY_PANEL_HDMI "hdmi"
128
Ajay Dudanicd01f9b2010-02-23 21:13:04 -0800129#ifdef MEMBASE
130#define EMMC_BOOT_IMG_HEADER_ADDR (0xFF000+(MEMBASE))
131#else
David Ng183a7422009-12-07 14:55:21 -0800132#define EMMC_BOOT_IMG_HEADER_ADDR 0xFF000
Ajay Dudanicd01f9b2010-02-23 21:13:04 -0800133#endif
134
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700135#ifndef MEMSIZE
136#define MEMSIZE 1024*1024
137#endif
138
139#define MAX_TAGS_SIZE 1024
Kishor PKee5c0a32018-03-06 16:49:46 +0530140#define PLL_CODES_OFFSET 4096
Kun Liang2f1601a2013-08-12 16:29:54 +0800141/* make 4096 as default size to ensure EFS,EXT4's erasing */
142#define DEFAULT_ERASE_SIZE 4096
Ujwal Patelc0b0a252015-08-16 14:05:35 -0700143#define MAX_PANEL_BUF_SIZE 196
Vijay Kumar Pendoti0b21f462016-05-02 17:09:18 +0530144#define FOOTER_SIZE 16384
Kun Liang2f1601a2013-08-12 16:29:54 +0800145
Dhaval Patelf83d73b2014-06-23 16:24:37 -0700146#define DISPLAY_DEFAULT_PREFIX "mdss_mdp"
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700147#define BOOT_DEV_MAX_LEN 64
Sundarajan Srinivasan595b71e2013-11-05 12:44:34 -0800148
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -0800149#define IS_ARM64(ptr) (ptr->magic_64 == KERNEL64_HDR_MAGIC) ? true : false
150
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -0700151#define ADD_OF(a, b) (UINT_MAX - b > a) ? (a + b) : UINT_MAX
152
Ameya Thakur10a33452016-06-13 14:24:26 -0700153//Size of the header that is used in case the boot image has
154//a uncompressed kernel + appended dtb
155#define PATCHED_KERNEL_HEADER_SIZE 20
156
157//String used to determine if the boot image has
158//a uncompressed kernel + appended dtb
159#define PATCHED_KERNEL_MAGIC "UNCOMPRESSED_IMG"
160
Sridhar Parasuram7bd4aaf2015-02-12 11:14:38 -0800161#if USE_BOOTDEV_CMDLINE
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700162static const char *emmc_cmdline = " androidboot.bootdevice=";
Sundarajan Srinivasan3827a102013-09-10 13:57:40 -0700163#else
David Ng183a7422009-12-07 14:55:21 -0800164static const char *emmc_cmdline = " androidboot.emmc=true";
Sundarajan Srinivasan3827a102013-09-10 13:57:40 -0700165#endif
Mayank Groverb716edf2019-05-08 16:06:55 +0530166static const char *dynamic_bootdev_cmdline =
167 " androidboot.boot_devices=soc/";
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800168static const char *usb_sn_cmdline = " androidboot.serialno=";
Pavel Nedev328ac822013-04-05 15:25:11 +0300169static const char *androidboot_mode = " androidboot.mode=";
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530170
171static const char *systemd_ffbm_mode = " systemd.unit=ffbm.target";
Matthew Qind886f3c2014-01-17 16:52:01 +0800172static const char *alarmboot_cmdline = " androidboot.alarmboot=true";
Pavel Nedev898298c2013-02-27 12:36:09 -0800173static const char *loglevel = " quiet";
Ajay Dudanica3a33c2011-11-18 08:31:40 -0800174static const char *battchg_pause = " androidboot.mode=charger";
Shashank Mittalcd98d472011-08-02 14:29:24 -0700175static const char *auth_kernel = " androidboot.authorized_kernel=true";
Pavel Nedev5614d222013-06-17 18:01:02 +0300176static const char *secondary_gpt_enable = " gpt";
Monika Singh292b3e92018-03-17 22:40:23 +0530177#ifdef MDTP_SUPPORT
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200178static const char *mdtp_activated_flag = " mdtp";
Monika Singh292b3e92018-03-17 22:40:23 +0530179#endif
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800180static const char *baseband_apq = " androidboot.baseband=apq";
181static const char *baseband_msm = " androidboot.baseband=msm";
182static const char *baseband_csfb = " androidboot.baseband=csfb";
183static const char *baseband_svlte2a = " androidboot.baseband=svlte2a";
Ajay Dudani403bc492011-09-30 16:17:21 -0700184static const char *baseband_mdm = " androidboot.baseband=mdm";
Sundarajan Srinivasanaaa8aff2013-11-12 17:19:14 -0800185static const char *baseband_mdm2 = " androidboot.baseband=mdm2";
Amol Jadi5c61a952012-05-04 17:05:35 -0700186static const char *baseband_sglte = " androidboot.baseband=sglte";
Amol Jadi2a15a272013-01-22 12:03:36 -0800187static const char *baseband_dsda = " androidboot.baseband=dsda";
188static const char *baseband_dsda2 = " androidboot.baseband=dsda2";
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -0800189static const char *baseband_sglte2 = " androidboot.baseband=sglte2";
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800190static const char *warmboot_cmdline = " qpnp-power-on.warm_boot=1";
Vijay Kumar Pendotib228cfc2016-06-13 20:15:23 +0530191static const char *baseband_apq_nowgr = " androidboot.baseband=baseband_apq_nowgr";
Mayank Grover351a75e2017-05-30 20:06:08 +0530192static const char *androidboot_slot_suffix = " androidboot.slot_suffix=";
193static const char *skip_ramfs = " skip_initramfs";
Mayank Grover466d6562018-05-10 14:52:20 +0530194
195#if HIBERNATION_SUPPORT
196static const char *resume = " resume=/dev/mmcblk0p";
197#endif
198
Sourabh Banerjee6c7153c2018-03-20 01:21:57 +0530199#ifdef INIT_BIN_LE
200static const char *sys_path_cmdline = " rootwait ro init="INIT_BIN_LE;
201#else
Mayank Grover3804be72017-06-22 11:59:23 +0530202static const char *sys_path_cmdline = " rootwait ro init=/init";
Sourabh Banerjee6c7153c2018-03-20 01:21:57 +0530203#endif
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530204
205#if VERITY_LE
206static const char *verity_dev = " root=/dev/dm-0";
207static const char *verity_system_part = " dm=\"system";
208static const char *verity_params = " none ro,0 1 android-verity /dev/mmcblk0p";
209#else
Mayank Grover5384ed82018-05-09 12:09:24 +0530210static const char *sys_path = " root=/dev/mmcblk0p";
lijuang83ef4b22018-08-23 11:01:55 +0800211
212#define MAX_DTBO_IDX_STR 64
213static const char *android_boot_dtbo_idx = " androidboot.dtbo_idx=";
Parth Dixit1375d9e2019-07-08 20:56:13 +0530214
215#define MAX_DTB_IDX_STR MAX_DTBO_IDX_STR
216static const char *android_boot_dtb_idx = " androidboot.dtb_idx=";
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530217#endif
Ajay Dudanid04110c2011-01-17 23:55:07 -0800218
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700219#if VERIFIED_BOOT
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700220static const char *verity_mode = " androidboot.veritymode=";
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700221static const char *verified_state= " androidboot.verifiedbootstate=";
Parth Dixita5715a02015-10-29 12:25:10 +0530222static const char *keymaster_v1= " androidboot.keymaster=1";
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700223//indexed based on enum values, green is 0 by default
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700224
225struct verified_boot_verity_mode vbvm[] =
226{
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700227#if ENABLE_VB_ATTEST
228 {false, "eio"},
229#else
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700230 {false, "logging"},
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700231#endif
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700232 {true, "enforcing"},
233};
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700234struct verified_boot_state_name vbsn[] =
235{
236 {GREEN, "green"},
237 {ORANGE, "orange"},
238 {YELLOW,"yellow"},
239 {RED,"red" },
240};
241#endif
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700242/*As per spec delay wait time before shutdown in Red state*/
243#define DELAY_WAIT 30000
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700244static unsigned page_size = 0;
245static unsigned page_mask = 0;
Gaurav Nebhwani4d2389c2016-03-17 21:10:05 +0530246static unsigned mmc_blocksize = 0;
247static unsigned mmc_blocksize_mask = 0;
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700248static char ffbm_mode_string[FFBM_MODE_BUF_SIZE];
249static bool boot_into_ffbm;
vijay kumar870515d2015-08-31 16:37:24 +0530250static char *target_boot_params = NULL;
Matthew Qind886f3c2014-01-17 16:52:01 +0800251static bool boot_reason_alarm;
Channagoud Kadabi80a182b2015-03-11 17:04:23 -0700252static bool devinfo_present = true;
Channagoud Kadabi736c4962015-08-21 11:56:52 -0700253bool boot_into_fastboot = false;
Parth Dixit4097b622016-03-15 14:42:27 +0530254static uint32_t dt_size = 0;
Monika Singh292b3e92018-03-17 22:40:23 +0530255static char *vbcmdline;
256static bootinfo info = {0};
Mayank Grovere1ab96c2018-09-04 20:31:31 +0530257static void *recovery_dtbo_buf = NULL;
258static uint32_t recovery_dtbo_size = 0;
259
Shashank Mittalcd98d472011-08-02 14:29:24 -0700260/* Assuming unauthorized kernel image by default */
261static int auth_kernel_img = 0;
Monika Singh292b3e92018-03-17 22:40:23 +0530262static device_info device = {DEVICE_MAGIC,0,0,0,0,{0},{0},{0},1,{0},0,{0}};
263
vijay kumarc65876c2015-04-24 13:29:16 +0530264static bool is_allow_unlock = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -0700265
vijay kumarca2e6812015-07-08 20:28:25 +0530266static char frp_ptns[2][8] = {"config","frp"};
267
lijuang511a2b52015-08-14 20:50:51 +0800268static const char *critical_flash_allowed_ptn[] = {
269 "aboot",
270 "rpm",
271 "tz",
272 "sbl",
273 "sdi",
274 "sbl1",
275 "xbl",
276 "hyp",
277 "pmic",
278 "bootloader",
279 "devinfo",
280 "partition"};
281
Dima Zavin42168f22009-01-30 11:52:22 -0800282struct atag_ptbl_entry
283{
284 char name[16];
285 unsigned offset;
286 unsigned size;
287 unsigned flags;
288};
289
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700290/*
291 * Partition info, required to be published
292 * for fastboot
293 */
294struct getvar_partition_info {
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530295 char part_name[MAX_GPT_NAME_SIZE]; /* Partition name */
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700296 char getvar_size[MAX_GET_VAR_NAME_SIZE]; /* fastboot get var name for size */
297 char getvar_type[MAX_GET_VAR_NAME_SIZE]; /* fastboot get var name for type */
298 char size_response[MAX_RSP_SIZE]; /* fastboot response for size */
299 char type_response[MAX_RSP_SIZE]; /* fastboot response for type */
300};
301
302/*
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530303 * Update the part_type_known for known paritions types.
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700304 */
Mayank Groverd38fe012018-03-13 15:33:16 +0530305#define RAW_STR "raw"
Mayank Grover52cd10a2018-03-15 12:57:54 +0530306#define EXT_STR "ext4"
307#define F2FS_STR "f2fs"
308
309#define FS_SUPERBLOCK_OFFSET 0x400
310#define EXT_MAGIC 0xEF53
311#define EXT_MAGIC_OFFSET_SB 0x38
312#define F2FS_MAGIC 0xF2F52010 // F2FS Magic Number
313#define F2FS_MAGIC_OFFSET_SB 0x0
314
315typedef enum fs_signature_type {
316 EXT_FS_SIGNATURE = 1,
317 EXT_F2FS_SIGNATURE = 2,
318 NO_FS = -1
319} fs_signature_type;
320
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530321struct getvar_partition_info part_info[NUM_PARTITIONS];
322struct getvar_partition_info part_type_known[] =
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700323{
Mayank Grover49920212018-02-09 18:15:55 +0530324 { "system" , "partition-size:", "partition-type:", "", "ext4" },
325 { "userdata" , "partition-size:", "partition-type:", "", "ext4" },
326 { "cache" , "partition-size:", "partition-type:", "", "ext4" },
327 { "recoveryfs" , "partition-size:", "partition-type:", "", "ext4" },
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700328};
329
330char max_download_size[MAX_RSP_SIZE];
Ameya Thakur11cf1a62013-08-05 12:44:48 -0700331char charger_screen_enabled[MAX_RSP_SIZE];
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800332char sn_buf[13];
Dhaval Patel223ec952013-07-18 14:49:44 -0700333char display_panel_buf[MAX_PANEL_BUF_SIZE];
Unnati Gandhi62c8ab82014-01-24 11:01:01 +0530334char panel_display_mode[MAX_RSP_SIZE];
Mayank Grovera64dfbe2018-05-17 14:06:34 +0530335char soc_version_str[MAX_RSP_SIZE];
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530336char block_size_string[MAX_RSP_SIZE];
Mukesh Ojhabb6e7f32018-03-02 15:04:06 +0530337#if PRODUCT_IOT
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530338
339/* For IOT we are using custom version */
340#define PRODUCT_IOT_VERSION "IOT001"
341char bootloader_version_string[MAX_RSP_SIZE];
342#endif
lijuang102dfa92015-10-09 18:31:03 +0800343
344#if CHECK_BAT_VOLTAGE
lijuang65c5a822015-08-29 16:35:36 +0800345char battery_voltage[MAX_RSP_SIZE];
lijuang102dfa92015-10-09 18:31:03 +0800346char battery_soc_ok [MAX_RSP_SIZE];
347#endif
348
lijuangf16461c2015-08-03 17:09:34 +0800349char get_variant[MAX_RSP_SIZE];
Greg Griscod6250552011-06-29 14:40:23 -0700350
Greg Griscod2471ef2011-07-14 13:00:42 -0700351extern int emmc_recovery_init(void);
352
Kinson Chik0b1c8162011-08-31 16:31:57 -0700353#if NO_KEYPAD_DRIVER
354extern int fastboot_trigger(void);
355#endif
Greg Griscod2471ef2011-07-14 13:00:42 -0700356
Mayank Grovere1ab96c2018-09-04 20:31:31 +0530357static void update_ker_tags_rdisk_addr(boot_img_hdr *hdr, bool is_arm64)
Channagoud Kadabia22144f2013-03-20 11:49:01 -0700358{
359 /* overwrite the destination of specified for the project */
Channagoud Kadabi7042fa32013-04-26 16:44:14 -0700360#ifdef ABOOT_IGNORE_BOOT_HEADER_ADDRS
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -0800361 if (is_arm64)
362 hdr->kernel_addr = ABOOT_FORCE_KERNEL64_ADDR;
363 else
364 hdr->kernel_addr = ABOOT_FORCE_KERNEL_ADDR;
Channagoud Kadabi7042fa32013-04-26 16:44:14 -0700365 hdr->ramdisk_addr = ABOOT_FORCE_RAMDISK_ADDR;
366 hdr->tags_addr = ABOOT_FORCE_TAGS_ADDR;
Channagoud Kadabia22144f2013-03-20 11:49:01 -0700367#endif
368}
369
Dima Zavin42168f22009-01-30 11:52:22 -0800370static void ptentry_to_tag(unsigned **ptr, struct ptentry *ptn)
371{
372 struct atag_ptbl_entry atag_ptn;
373
374 memcpy(atag_ptn.name, ptn->name, 16);
375 atag_ptn.name[15] = '\0';
376 atag_ptn.offset = ptn->start;
377 atag_ptn.size = ptn->length;
378 atag_ptn.flags = ptn->flags;
379 memcpy(*ptr, &atag_ptn, sizeof(struct atag_ptbl_entry));
380 *ptr += sizeof(struct atag_ptbl_entry) / sizeof(unsigned);
381}
Mayank Grover9df84c02018-08-30 15:46:35 +0530382#ifdef VERIFIED_BOOT_2
383void load_vbmeta_image(void **vbmeta_image_buf, uint32_t *vbmeta_image_sz)
384{
385 int index = 0;
386 char *vbm_img_buf = NULL;
387 unsigned long long ptn = 0;
388 unsigned long long ptn_size = 0;
389
390 /* Immediately return if dtbo is not supported */
391 index = partition_get_index("vbmeta");
392 ptn = partition_get_offset(index);
393 if(!ptn)
394 {
395 dprintf(CRITICAL, "ERROR: vbmeta partition not found.\n");
396 return;
397 }
398
399 ptn_size = partition_get_size(index);
400 if (ptn_size > MAX_SUPPORTED_VBMETA_IMG_BUF)
401 {
402 dprintf(CRITICAL, "ERROR: vbmeta parition size is greater than supported.\n");
403 return;
404 }
405
406 vbm_img_buf = (char *)memalign(CACHE_LINE, ROUNDUP((uint32_t)ptn_size, CACHE_LINE));
407 if (!vbm_img_buf)
408 {
409 dprintf(CRITICAL, "ERROR: vbmeta unable to locate buffer\n");
410 return;
411 }
412
413 mmc_set_lun(partition_get_lun(index));
414 if (mmc_read(ptn, (uint32_t *)vbm_img_buf, (uint32_t)ptn_size))
415 {
416 dprintf(CRITICAL, "ERROR: vbmeta read failure\n");
417 free(vbm_img_buf);
418 return;
419 }
420
421 *vbmeta_image_buf = vbm_img_buf;
422 *vbmeta_image_sz = (uint32_t)ptn_size;
423 return;
424}
425#endif
Brian Swetland9c4c0752009-01-25 16:23:50 -0800426
lijuang102dfa92015-10-09 18:31:03 +0800427#if CHECK_BAT_VOLTAGE
428void update_battery_status(void)
429{
430 snprintf(battery_voltage,MAX_RSP_SIZE, "%d",target_get_battery_voltage());
431 snprintf(battery_soc_ok ,MAX_RSP_SIZE, "%s",target_battery_soc_ok()? "yes":"no");
432}
433#endif
434
Neeti Desaie245d492012-06-01 12:52:13 -0700435unsigned char *update_cmdline(const char * cmdline)
Brian Swetland9c4c0752009-01-25 16:23:50 -0800436{
David Ng183a7422009-12-07 14:55:21 -0800437 int cmdline_len = 0;
438 int have_cmdline = 0;
Amol Jadi168b7712012-03-06 16:15:00 -0800439 unsigned char *cmdline_final = NULL;
Neeti Desaie245d492012-06-01 12:52:13 -0700440 int pause_at_bootup = 0;
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800441 bool warm_boot = false;
Pavel Nedev5614d222013-06-17 18:01:02 +0300442 bool gpt_exists = partition_gpt_exists();
Joonwoo Park61112782013-10-02 19:50:39 -0700443 int have_target_boot_params = 0;
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700444 char *boot_dev_buf = NULL;
Monika Singh292b3e92018-03-17 22:40:23 +0530445#ifdef MDTP_SUPPORT
Mayank Grover351a75e2017-05-30 20:06:08 +0530446 bool is_mdtp_activated = 0;
Monika Singh292b3e92018-03-17 22:40:23 +0530447#endif
Mayank Grover351a75e2017-05-30 20:06:08 +0530448 int current_active_slot = INVALID;
Mayank Grover3804be72017-06-22 11:59:23 +0530449 int system_ptn_index = -1;
450 unsigned int lun = 0;
451 char lun_char_base = 'a';
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530452#if VERITY_LE
453 int syspath_buflen = strlen(verity_dev)
454 + strlen(verity_system_part) + (sizeof(char) * 2) + 2
455 + strlen(verity_params) + sizeof(int) + 2;
456#else
lijuang83ef4b22018-08-23 11:01:55 +0800457 int syspath_buflen = strlen(sys_path) + sizeof(int) + 2; /*allocate buflen for largest possible string*/
458 char dtbo_idx_str[MAX_DTBO_IDX_STR] = "\0";
459 int dtbo_idx = INVALID_PTN;
Parth Dixit1375d9e2019-07-08 20:56:13 +0530460 char dtb_idx_str[MAX_DTB_IDX_STR] = "\0";
461 int dtb_idx = INVALID_PTN;
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530462#endif
Mayank Grover3804be72017-06-22 11:59:23 +0530463 char syspath_buf[syspath_buflen];
Mayank Grover466d6562018-05-10 14:52:20 +0530464#if HIBERNATION_SUPPORT
465 int resume_buflen = strlen(resume) + sizeof(int) + 2;
466 char resume_buf[resume_buflen];
467 int swap_ptn_index = INVALID_PTN;
468#endif
469
Mayank Grover889be1b2017-09-12 20:12:23 +0530470#if VERIFIED_BOOT
471 uint32_t boot_state = RED;
472#endif
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530473
474#if USE_LE_SYSTEMD
475 is_systemd_present=true;
476#endif
477
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700478#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +0530479 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +0530480 {
481 boot_state = boot_verify_get_state();
482 }
Parth Dixitddbc7352015-10-18 03:13:31 +0530483#endif
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700484
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200485#ifdef MDTP_SUPPORT
486 mdtp_activated(&is_mdtp_activated);
487#endif /* MDTP_SUPPORT */
Dima Zavin42168f22009-01-30 11:52:22 -0800488
Brian Swetland9c4c0752009-01-25 16:23:50 -0800489 if (cmdline && cmdline[0]) {
David Ng183a7422009-12-07 14:55:21 -0800490 cmdline_len = strlen(cmdline);
491 have_cmdline = 1;
492 }
493 if (target_is_emmc_boot()) {
494 cmdline_len += strlen(emmc_cmdline);
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700495 boot_dev_buf = (char *) malloc(sizeof(char) * BOOT_DEV_MAX_LEN);
Mayank Groverb716edf2019-05-08 16:06:55 +0530496 if (!boot_dev_buf) {
497 dprintf(CRITICAL, "ERROR: Failed to allocate boot_dev_buf\n");
498 } else {
499 platform_boot_dev_cmdline(boot_dev_buf);
500#if USE_BOOTDEV_CMDLINE
501 cmdline_len += strlen(boot_dev_buf);
Sundarajan Srinivasan3827a102013-09-10 13:57:40 -0700502#endif
Mayank Groverb716edf2019-05-08 16:06:55 +0530503 if (target_dynamic_partition_supported()) {
504 cmdline_len += strlen(dynamic_bootdev_cmdline);
505 cmdline_len += strlen(boot_dev_buf);
506 }
507 }
David Ng183a7422009-12-07 14:55:21 -0800508 }
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800509
510 cmdline_len += strlen(usb_sn_cmdline);
511 cmdline_len += strlen(sn_buf);
512
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700513#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +0530514 if (VB_M <= target_get_vb_version())
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700515 {
Mayank Grover889be1b2017-09-12 20:12:23 +0530516 cmdline_len += strlen(verified_state) + strlen(vbsn[boot_state].name);
517 if ((device.verity_mode != 0 ) && (device.verity_mode != 1))
518 {
519 dprintf(CRITICAL, "Devinfo paritition possibly corrupted!!!. Please erase devinfo partition to continue booting\n");
520 ASSERT(0);
521 }
522 cmdline_len += strlen(verity_mode) + strlen(vbvm[device.verity_mode].name);
523 cmdline_len += strlen(keymaster_v1);
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700524 }
Parth Dixitddbc7352015-10-18 03:13:31 +0530525#endif
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700526
Monika Singh292b3e92018-03-17 22:40:23 +0530527
528 if (vbcmdline != NULL) {
529 dprintf(DEBUG, "UpdateCmdLine vbcmdline present len %d\n",
530 strlen(vbcmdline));
531 cmdline_len += strlen(vbcmdline);
532 }
533
Pavel Nedev5614d222013-06-17 18:01:02 +0300534 if (boot_into_recovery && gpt_exists)
535 cmdline_len += strlen(secondary_gpt_enable);
536
Monika Singh292b3e92018-03-17 22:40:23 +0530537#ifdef MDTP_SUPPORT
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200538 if(is_mdtp_activated)
539 cmdline_len += strlen(mdtp_activated_flag);
Monika Singh292b3e92018-03-17 22:40:23 +0530540#endif
Pavel Nedev328ac822013-04-05 15:25:11 +0300541 if (boot_into_ffbm) {
542 cmdline_len += strlen(androidboot_mode);
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530543
544 if(is_systemd_present)
545 cmdline_len += strlen(systemd_ffbm_mode);
546
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700547 cmdline_len += strlen(ffbm_mode_string);
Pavel Nedev898298c2013-02-27 12:36:09 -0800548 /* reduce kernel console messages to speed-up boot */
549 cmdline_len += strlen(loglevel);
Matthew Qind886f3c2014-01-17 16:52:01 +0800550 } else if (boot_reason_alarm) {
551 cmdline_len += strlen(alarmboot_cmdline);
Zhenhua Huang431dafa2015-06-30 16:13:37 +0800552 } else if ((target_build_variant_user() || device.charger_screen_enabled)
lijuang266b17d2018-08-17 18:53:42 +0800553 && target_pause_for_battery_charge() && !boot_into_recovery) {
David Ngf773dde2010-07-26 19:55:08 -0700554 pause_at_bootup = 1;
555 cmdline_len += strlen(battchg_pause);
556 }
Ajay Dudanid04110c2011-01-17 23:55:07 -0800557
Shashank Mittalcd98d472011-08-02 14:29:24 -0700558 if(target_use_signed_kernel() && auth_kernel_img) {
559 cmdline_len += strlen(auth_kernel);
560 }
561
Joonwoo Park61112782013-10-02 19:50:39 -0700562 if (get_target_boot_params(cmdline, boot_into_recovery ? "recoveryfs" :
563 "system",
vijay kumar870515d2015-08-31 16:37:24 +0530564 &target_boot_params) == 0) {
Joonwoo Park61112782013-10-02 19:50:39 -0700565 have_target_boot_params = 1;
566 cmdline_len += strlen(target_boot_params);
567 }
568
Ajay Dudanid04110c2011-01-17 23:55:07 -0800569 /* Determine correct androidboot.baseband to use */
570 switch(target_baseband())
571 {
572 case BASEBAND_APQ:
573 cmdline_len += strlen(baseband_apq);
574 break;
575
576 case BASEBAND_MSM:
577 cmdline_len += strlen(baseband_msm);
578 break;
579
580 case BASEBAND_CSFB:
581 cmdline_len += strlen(baseband_csfb);
582 break;
583
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800584 case BASEBAND_SVLTE2A:
585 cmdline_len += strlen(baseband_svlte2a);
Ajay Dudanid04110c2011-01-17 23:55:07 -0800586 break;
Ajay Dudani403bc492011-09-30 16:17:21 -0700587
588 case BASEBAND_MDM:
589 cmdline_len += strlen(baseband_mdm);
590 break;
Amol Jadi5c61a952012-05-04 17:05:35 -0700591
Sundarajan Srinivasanaaa8aff2013-11-12 17:19:14 -0800592 case BASEBAND_MDM2:
593 cmdline_len += strlen(baseband_mdm2);
594 break;
595
Amol Jadi5c61a952012-05-04 17:05:35 -0700596 case BASEBAND_SGLTE:
597 cmdline_len += strlen(baseband_sglte);
598 break;
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530599
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -0800600 case BASEBAND_SGLTE2:
601 cmdline_len += strlen(baseband_sglte2);
602 break;
603
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530604 case BASEBAND_DSDA:
605 cmdline_len += strlen(baseband_dsda);
606 break;
Amol Jadi2a15a272013-01-22 12:03:36 -0800607
608 case BASEBAND_DSDA2:
609 cmdline_len += strlen(baseband_dsda2);
610 break;
Vijay Kumar Pendotib228cfc2016-06-13 20:15:23 +0530611 case BASEBAND_APQ_NOWGR:
612 cmdline_len += strlen(baseband_apq_nowgr);
613 break;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800614 }
615
Vladislav Levenetz3cd45242017-04-05 08:58:07 +0300616#if ENABLE_DISPLAY
Lijuan Gao4a5b8322014-07-24 10:38:42 +0800617 if (cmdline) {
618 if ((strstr(cmdline, DISPLAY_DEFAULT_PREFIX) == NULL) &&
Padmanabhan Komandurubccbcdc2015-06-30 16:19:24 +0530619 target_display_panel_node(display_panel_buf,
620 MAX_PANEL_BUF_SIZE) &&
Lijuan Gao4a5b8322014-07-24 10:38:42 +0800621 strlen(display_panel_buf)) {
622 cmdline_len += strlen(display_panel_buf);
623 }
Dhaval Patel223ec952013-07-18 14:49:44 -0700624 }
Vladislav Levenetz3cd45242017-04-05 08:58:07 +0300625#endif
Dhaval Patel223ec952013-07-18 14:49:44 -0700626
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800627 if (target_warm_boot()) {
628 warm_boot = true;
629 cmdline_len += strlen(warmboot_cmdline);
630 }
631
Mayank Grover5384ed82018-05-09 12:09:24 +0530632 if (target_uses_system_as_root() ||
633 partition_multislot_is_supported())
Mayank Grover351a75e2017-05-30 20:06:08 +0530634 {
635 current_active_slot = partition_find_active_slot();
636 cmdline_len += (strlen(androidboot_slot_suffix)+
637 strlen(SUFFIX_SLOT(current_active_slot)));
638
Mayank Grover3804be72017-06-22 11:59:23 +0530639 system_ptn_index = partition_get_index("system");
640 if (platform_boot_dev_isemmc())
641 {
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530642#if VERITY_LE
643 /*
644 Condition 4: Verity and A/B both enabled
645 Eventual command line looks like:
646 ... androidboot.slot_suffix=<slot_suffix> ... rootfstype=ext4 ...
647 ... root=/dev/dm-0 dm="system_<slot_suffix> none ro,0 1 android-verity /dev/mmcblk0p<NN>"
648 */
649 snprintf(syspath_buf, syspath_buflen, " %s %s%s %s%d\"",
650 verity_dev,
651 verity_system_part, suffix_slot[current_active_slot],
652 verity_params, system_ptn_index + 1);
653#else
654 /*
655 Condition 5: A/B enabled, but verity disabled
656 Eventual command line looks like:
657 ... androidboot.slot_suffix=<slot_suffix> ... rootfstype=ext4 ...
658 ... root=/dev/mmcblk0p<NN> ...
659 */
660 snprintf(syspath_buf, syspath_buflen, " %s%d",
661 sys_path, system_ptn_index + 1);
662#endif
Mayank Grover3804be72017-06-22 11:59:23 +0530663 }
664 else
665 {
666 lun = partition_get_lun(system_ptn_index);
667 snprintf(syspath_buf, syspath_buflen, " root=/dev/sd%c%d",
668 lun_char_base + lun,
669 partition_get_index_in_lun("system", lun));
670 }
Mayank Grover351a75e2017-05-30 20:06:08 +0530671
Monika Singh292b3e92018-03-17 22:40:23 +0530672#ifndef VERIFIED_BOOT_2
Mayank Grover3804be72017-06-22 11:59:23 +0530673 cmdline_len += strlen(syspath_buf);
Monika Singh292b3e92018-03-17 22:40:23 +0530674#endif
Mayank Grover5384ed82018-05-09 12:09:24 +0530675 }
676
677 if (target_uses_system_as_root() ||
678 partition_multislot_is_supported())
679 {
680 cmdline_len += strlen(sys_path_cmdline);
Mayank Groverb716edf2019-05-08 16:06:55 +0530681
682 /* For dynamic partition, support skip skip_initramfs */
683 if (!target_dynamic_partition_supported() &&
684 !boot_into_recovery)
Mayank Grover351a75e2017-05-30 20:06:08 +0530685 cmdline_len += strlen(skip_ramfs);
686 }
687
Mayank Grover466d6562018-05-10 14:52:20 +0530688#if HIBERNATION_SUPPORT
689 if (platform_boot_dev_isemmc())
690 {
691 swap_ptn_index = partition_get_index("swap");
692 if (swap_ptn_index != INVALID_PTN)
693 {
694 snprintf(resume_buf, resume_buflen,
695 " %s%d", resume,
696 (swap_ptn_index + 1));
697 cmdline_len += strlen(resume_buf);
698 }
699 else
700 {
701 dprintf(INFO, "WARNING: swap partition not found\n");
702 }
703 }
704#endif
705
Channagoud Kadabi85c7ec32016-01-28 23:09:21 -0800706#if TARGET_CMDLINE_SUPPORT
707 char *target_cmdline_buf = malloc(TARGET_MAX_CMDLNBUF);
708 int target_cmd_line_len;
709 ASSERT(target_cmdline_buf);
710 target_cmd_line_len = target_update_cmdline(target_cmdline_buf);
711 cmdline_len += target_cmd_line_len;
712#endif
713
lijuang83ef4b22018-08-23 11:01:55 +0800714#if !VERITY_LE
715 dtbo_idx = get_dtbo_idx ();
716 if (dtbo_idx != INVALID_PTN) {
717 snprintf(dtbo_idx_str, sizeof(dtbo_idx_str), "%s%d",
718 android_boot_dtbo_idx, dtbo_idx);
719 cmdline_len += strlen (dtbo_idx_str);
720 }
Parth Dixit1375d9e2019-07-08 20:56:13 +0530721
722 dtb_idx = get_dtb_idx ();
723 if (dtb_idx != INVALID_PTN) {
724 snprintf(dtb_idx_str, sizeof(dtb_idx_str), "%s%d",
725 android_boot_dtb_idx, dtb_idx);
726 cmdline_len += strlen (dtb_idx_str);
727 }
lijuang83ef4b22018-08-23 11:01:55 +0800728#endif
729
David Ng183a7422009-12-07 14:55:21 -0800730 if (cmdline_len > 0) {
731 const char *src;
Maria Yu52254c02014-07-04 16:14:54 +0800732 unsigned char *dst;
733
734 cmdline_final = (unsigned char*) malloc((cmdline_len + 4) & (~3));
735 ASSERT(cmdline_final != NULL);
vijay kumar287bb542015-09-29 13:01:52 +0530736 memset((void *)cmdline_final, 0, sizeof(*cmdline_final));
Maria Yu52254c02014-07-04 16:14:54 +0800737 dst = cmdline_final;
Neeti Desaie245d492012-06-01 12:52:13 -0700738
Amol Jadi168b7712012-03-06 16:15:00 -0800739 /* Save start ptr for debug print */
David Ng183a7422009-12-07 14:55:21 -0800740 if (have_cmdline) {
741 src = cmdline;
742 while ((*dst++ = *src++));
743 }
744 if (target_is_emmc_boot()) {
745 src = emmc_cmdline;
746 if (have_cmdline) --dst;
David Ngf773dde2010-07-26 19:55:08 -0700747 have_cmdline = 1;
748 while ((*dst++ = *src++));
Sridhar Parasuram7bd4aaf2015-02-12 11:14:38 -0800749#if USE_BOOTDEV_CMDLINE
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700750 src = boot_dev_buf;
Mayank Groverb716edf2019-05-08 16:06:55 +0530751 if (have_cmdline &&
752 boot_dev_buf) {
753 --dst;
754 while ((*dst++ = *src++));
755 }
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700756#endif
Mayank Groverb716edf2019-05-08 16:06:55 +0530757 /* Dynamic partition append boot_devices */
758 if (target_dynamic_partition_supported() &&
759 boot_dev_buf) {
760 src = dynamic_bootdev_cmdline;
761 if (have_cmdline) --dst;
762 while ((*dst++ = *src++));
763 src = boot_dev_buf;
764 if (have_cmdline) --dst;
765 while ((*dst++ = *src++));
766 }
David Ngf773dde2010-07-26 19:55:08 -0700767 }
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800768
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700769#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +0530770 if (VB_M <= target_get_vb_version())
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700771 {
Mayank Grover889be1b2017-09-12 20:12:23 +0530772 src = verified_state;
773 if(have_cmdline) --dst;
774 have_cmdline = 1;
775 while ((*dst++ = *src++));
776 src = vbsn[boot_state].name;
777 if(have_cmdline) --dst;
778 while ((*dst++ = *src++));
779
780 if ((device.verity_mode != 0 ) && (device.verity_mode != 1))
781 {
782 dprintf(CRITICAL, "Devinfo paritition possibly corrupted!!!. Please erase devinfo partition to continue booting\n");
783 ASSERT(0);
784 }
785 src = verity_mode;
786 if(have_cmdline) --dst;
787 while ((*dst++ = *src++));
788 src = vbvm[device.verity_mode].name;
789 if(have_cmdline) -- dst;
790 while ((*dst++ = *src++));
791 src = keymaster_v1;
792 if(have_cmdline) --dst;
793 while ((*dst++ = *src++));
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700794 }
Parth Dixitddbc7352015-10-18 03:13:31 +0530795#endif
Monika Singh292b3e92018-03-17 22:40:23 +0530796
797 if (vbcmdline != NULL) {
798 src = vbcmdline;
799 if (have_cmdline) --dst;
800 while ((*dst++ = *src++));
801 }
802
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800803 src = usb_sn_cmdline;
804 if (have_cmdline) --dst;
805 have_cmdline = 1;
806 while ((*dst++ = *src++));
807 src = sn_buf;
808 if (have_cmdline) --dst;
809 have_cmdline = 1;
810 while ((*dst++ = *src++));
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800811 if (warm_boot) {
812 if (have_cmdline) --dst;
813 src = warmboot_cmdline;
814 while ((*dst++ = *src++));
815 }
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800816
Pavel Nedev5614d222013-06-17 18:01:02 +0300817 if (boot_into_recovery && gpt_exists) {
818 src = secondary_gpt_enable;
819 if (have_cmdline) --dst;
820 while ((*dst++ = *src++));
821 }
Monika Singh292b3e92018-03-17 22:40:23 +0530822#ifdef MDTP_SUPPORT
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200823 if (is_mdtp_activated) {
824 src = mdtp_activated_flag;
825 if (have_cmdline) --dst;
826 while ((*dst++ = *src++));
827 }
Monika Singh292b3e92018-03-17 22:40:23 +0530828#endif
Pavel Nedev328ac822013-04-05 15:25:11 +0300829 if (boot_into_ffbm) {
830 src = androidboot_mode;
831 if (have_cmdline) --dst;
832 while ((*dst++ = *src++));
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700833 src = ffbm_mode_string;
Pavel Nedev328ac822013-04-05 15:25:11 +0300834 if (have_cmdline) --dst;
835 while ((*dst++ = *src++));
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530836
837 if(is_systemd_present) {
838 src = systemd_ffbm_mode;
839 if (have_cmdline) --dst;
840 while ((*dst++ = *src++));
841 }
842
Pavel Nedev898298c2013-02-27 12:36:09 -0800843 src = loglevel;
844 if (have_cmdline) --dst;
845 while ((*dst++ = *src++));
Matthew Qind886f3c2014-01-17 16:52:01 +0800846 } else if (boot_reason_alarm) {
847 src = alarmboot_cmdline;
848 if (have_cmdline) --dst;
849 while ((*dst++ = *src++));
Pavel Nedev328ac822013-04-05 15:25:11 +0300850 } else if (pause_at_bootup) {
David Ngf773dde2010-07-26 19:55:08 -0700851 src = battchg_pause;
852 if (have_cmdline) --dst;
David Ng183a7422009-12-07 14:55:21 -0800853 while ((*dst++ = *src++));
854 }
Ajay Dudanid04110c2011-01-17 23:55:07 -0800855
Shashank Mittalcd98d472011-08-02 14:29:24 -0700856 if(target_use_signed_kernel() && auth_kernel_img) {
857 src = auth_kernel;
858 if (have_cmdline) --dst;
859 while ((*dst++ = *src++));
860 }
861
Ajay Dudanid04110c2011-01-17 23:55:07 -0800862 switch(target_baseband())
863 {
864 case BASEBAND_APQ:
865 src = baseband_apq;
866 if (have_cmdline) --dst;
867 while ((*dst++ = *src++));
868 break;
869
870 case BASEBAND_MSM:
871 src = baseband_msm;
872 if (have_cmdline) --dst;
873 while ((*dst++ = *src++));
874 break;
875
876 case BASEBAND_CSFB:
877 src = baseband_csfb;
878 if (have_cmdline) --dst;
879 while ((*dst++ = *src++));
880 break;
881
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800882 case BASEBAND_SVLTE2A:
883 src = baseband_svlte2a;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800884 if (have_cmdline) --dst;
885 while ((*dst++ = *src++));
886 break;
Ajay Dudani403bc492011-09-30 16:17:21 -0700887
888 case BASEBAND_MDM:
889 src = baseband_mdm;
890 if (have_cmdline) --dst;
891 while ((*dst++ = *src++));
892 break;
Amol Jadi5c61a952012-05-04 17:05:35 -0700893
Sundarajan Srinivasanaaa8aff2013-11-12 17:19:14 -0800894 case BASEBAND_MDM2:
895 src = baseband_mdm2;
896 if (have_cmdline) --dst;
897 while ((*dst++ = *src++));
898 break;
899
Amol Jadi5c61a952012-05-04 17:05:35 -0700900 case BASEBAND_SGLTE:
901 src = baseband_sglte;
902 if (have_cmdline) --dst;
903 while ((*dst++ = *src++));
904 break;
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530905
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -0800906 case BASEBAND_SGLTE2:
907 src = baseband_sglte2;
908 if (have_cmdline) --dst;
909 while ((*dst++ = *src++));
910 break;
911
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530912 case BASEBAND_DSDA:
913 src = baseband_dsda;
914 if (have_cmdline) --dst;
915 while ((*dst++ = *src++));
916 break;
Amol Jadi2a15a272013-01-22 12:03:36 -0800917
918 case BASEBAND_DSDA2:
919 src = baseband_dsda2;
920 if (have_cmdline) --dst;
921 while ((*dst++ = *src++));
922 break;
Vijay Kumar Pendotib228cfc2016-06-13 20:15:23 +0530923 case BASEBAND_APQ_NOWGR:
924 src = baseband_apq_nowgr;
925 if (have_cmdline) --dst;
926 while ((*dst++ = *src++));
927 break;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800928 }
Dhaval Patel223ec952013-07-18 14:49:44 -0700929
930 if (strlen(display_panel_buf)) {
Dhaval Patel223ec952013-07-18 14:49:44 -0700931 src = display_panel_buf;
932 if (have_cmdline) --dst;
933 while ((*dst++ = *src++));
934 }
Joonwoo Park61112782013-10-02 19:50:39 -0700935
936 if (have_target_boot_params) {
937 if (have_cmdline) --dst;
938 src = target_boot_params;
939 while ((*dst++ = *src++));
vijay kumar870515d2015-08-31 16:37:24 +0530940 free(target_boot_params);
Joonwoo Park61112782013-10-02 19:50:39 -0700941 }
Channagoud Kadabi85c7ec32016-01-28 23:09:21 -0800942
Mayank Grover351a75e2017-05-30 20:06:08 +0530943 if (partition_multislot_is_supported() && have_cmdline)
944 {
945 src = androidboot_slot_suffix;
946 --dst;
947 while ((*dst++ = *src++));
948 --dst;
949 src = SUFFIX_SLOT(current_active_slot);
950 while ((*dst++ = *src++));
Mayank Grover5384ed82018-05-09 12:09:24 +0530951 }
Mayank Grover351a75e2017-05-30 20:06:08 +0530952
Mayank Grover351a75e2017-05-30 20:06:08 +0530953
Mayank Grover5384ed82018-05-09 12:09:24 +0530954 /*
955 * System-As-Root behaviour, system.img should contain both
956 * system content and ramdisk content, and should be mounted at
957 * root(a/b).
958 * Apending skip_ramfs for non a/b builds which use, system as root.
959 */
960 if ((target_uses_system_as_root() ||
961 partition_multislot_is_supported()) &&
962 have_cmdline)
963 {
Mayank Groverb716edf2019-05-08 16:06:55 +0530964 if (!target_dynamic_partition_supported() &&
965 !boot_into_recovery)
Mayank Grover5384ed82018-05-09 12:09:24 +0530966 {
967 src = skip_ramfs;
Mayank Grover351a75e2017-05-30 20:06:08 +0530968 --dst;
969 while ((*dst++ = *src++));
Mayank Grover5384ed82018-05-09 12:09:24 +0530970 }
971
972 src = sys_path_cmdline;
973 --dst;
974 while ((*dst++ = *src++));
Mayank Grover3804be72017-06-22 11:59:23 +0530975
Monika Singh292b3e92018-03-17 22:40:23 +0530976#ifndef VERIFIED_BOOT_2
Mayank Grover5384ed82018-05-09 12:09:24 +0530977 src = syspath_buf;
978 --dst;
979 while ((*dst++ = *src++));
Monika Singh292b3e92018-03-17 22:40:23 +0530980#endif
Mayank Grover351a75e2017-05-30 20:06:08 +0530981 }
982
Mayank Grover466d6562018-05-10 14:52:20 +0530983#if HIBERNATION_SUPPORT
984 if (swap_ptn_index != INVALID_PTN)
985 {
986 src = resume_buf;
987 --dst;
988 while ((*dst++ = *src++));
989 }
990#endif
991
Channagoud Kadabi85c7ec32016-01-28 23:09:21 -0800992#if TARGET_CMDLINE_SUPPORT
993 if (target_cmdline_buf && target_cmd_line_len)
994 {
995 if (have_cmdline) --dst;
996 src = target_cmdline_buf;
997 while((*dst++ = *src++));
998 free(target_cmdline_buf);
999 }
1000#endif
lijuang83ef4b22018-08-23 11:01:55 +08001001
1002#if !VERITY_LE
1003 if (dtbo_idx != INVALID_PTN) {
1004 src = dtbo_idx_str;
1005 --dst;
1006 while ((*dst++ = *src++));
1007 }
Parth Dixit1375d9e2019-07-08 20:56:13 +05301008
1009 if (dtb_idx != INVALID_PTN) {
1010 src = dtb_idx_str;
1011 --dst;
1012 while ((*dst++ = *src++));
1013 }
lijuang83ef4b22018-08-23 11:01:55 +08001014#endif
Neeti Desaie245d492012-06-01 12:52:13 -07001015 }
Dhaval Patel223ec952013-07-18 14:49:44 -07001016
1017
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -07001018 if (boot_dev_buf)
1019 free(boot_dev_buf);
1020
Veera Sundaram Sankaranf9915462014-12-09 11:54:59 -08001021 if (cmdline_final)
1022 dprintf(INFO, "cmdline: %s\n", cmdline_final);
1023 else
1024 dprintf(INFO, "cmdline is NULL\n");
Neeti Desaie245d492012-06-01 12:52:13 -07001025 return cmdline_final;
1026}
1027
1028unsigned *atag_core(unsigned *ptr)
1029{
1030 /* CORE */
1031 *ptr++ = 2;
1032 *ptr++ = 0x54410001;
1033
1034 return ptr;
1035
1036}
1037
1038unsigned *atag_ramdisk(unsigned *ptr, void *ramdisk,
1039 unsigned ramdisk_size)
1040{
1041 if (ramdisk_size) {
1042 *ptr++ = 4;
1043 *ptr++ = 0x54420005;
1044 *ptr++ = (unsigned)ramdisk;
1045 *ptr++ = ramdisk_size;
Brian Swetland9c4c0752009-01-25 16:23:50 -08001046 }
1047
Neeti Desaie245d492012-06-01 12:52:13 -07001048 return ptr;
1049}
1050
1051unsigned *atag_ptable(unsigned **ptr_addr)
1052{
1053 int i;
1054 struct ptable *ptable;
1055
1056 if ((ptable = flash_get_ptable()) && (ptable->count != 0)) {
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001057 *(*ptr_addr)++ = 2 + (ptable->count * (sizeof(struct atag_ptbl_entry) /
1058 sizeof(unsigned)));
Neeti Desaie245d492012-06-01 12:52:13 -07001059 *(*ptr_addr)++ = 0x4d534d70;
1060 for (i = 0; i < ptable->count; ++i)
1061 ptentry_to_tag(ptr_addr, ptable_get(ptable, i));
1062 }
1063
1064 return (*ptr_addr);
1065}
1066
1067unsigned *atag_cmdline(unsigned *ptr, const char *cmdline)
1068{
1069 int cmdline_length = 0;
1070 int n;
Neeti Desaie245d492012-06-01 12:52:13 -07001071 char *dest;
1072
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001073 cmdline_length = strlen((const char*)cmdline);
Neeti Desaie245d492012-06-01 12:52:13 -07001074 n = (cmdline_length + 4) & (~3);
1075
1076 *ptr++ = (n / 4) + 2;
1077 *ptr++ = 0x54410009;
1078 dest = (char *) ptr;
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001079 while ((*dest++ = *cmdline++));
Neeti Desaie245d492012-06-01 12:52:13 -07001080 ptr += (n / 4);
1081
1082 return ptr;
1083}
1084
1085unsigned *atag_end(unsigned *ptr)
1086{
Brian Swetland9c4c0752009-01-25 16:23:50 -08001087 /* END */
1088 *ptr++ = 0;
1089 *ptr++ = 0;
1090
Neeti Desaie245d492012-06-01 12:52:13 -07001091 return ptr;
1092}
1093
1094void generate_atags(unsigned *ptr, const char *cmdline,
1095 void *ramdisk, unsigned ramdisk_size)
1096{
vijay kumar21a37452015-12-29 16:23:21 +05301097 unsigned *orig_ptr = ptr;
Neeti Desaie245d492012-06-01 12:52:13 -07001098 ptr = atag_core(ptr);
1099 ptr = atag_ramdisk(ptr, ramdisk, ramdisk_size);
1100 ptr = target_atag_mem(ptr);
1101
1102 /* Skip NAND partition ATAGS for eMMC boot */
1103 if (!target_is_emmc_boot()){
1104 ptr = atag_ptable(&ptr);
1105 }
1106
vijay kumar21a37452015-12-29 16:23:21 +05301107 /*
1108 * Atags size filled till + cmdline size + 1 unsigned for 4-byte boundary + 4 unsigned
1109 * for atag identifier in atag_cmdline and atag_end should be with in MAX_TAGS_SIZE bytes
1110 */
Mayank Groverbc8a2ef2018-02-23 18:03:36 +05301111 if (!cmdline)
1112 return;
1113
vijay kumar21a37452015-12-29 16:23:21 +05301114 if (((ptr - orig_ptr) + strlen(cmdline) + 5 * sizeof(unsigned)) < MAX_TAGS_SIZE) {
1115 ptr = atag_cmdline(ptr, cmdline);
1116 ptr = atag_end(ptr);
1117 }
1118 else {
1119 dprintf(CRITICAL,"Crossing ATAGs Max size allowed\n");
1120 ASSERT(0);
1121 }
Neeti Desaie245d492012-06-01 12:52:13 -07001122}
1123
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001124typedef void entry_func_ptr(unsigned, unsigned, unsigned*);
Neeti Desaie245d492012-06-01 12:52:13 -07001125void boot_linux(void *kernel, unsigned *tags,
1126 const char *cmdline, unsigned machtype,
1127 void *ramdisk, unsigned ramdisk_size)
1128{
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001129 unsigned char *final_cmdline;
Amol Jadib6be5c12012-11-14 13:39:51 -08001130#if DEVICE_TREE
Neeti Desai17379b82012-06-04 18:42:53 -07001131 int ret = 0;
Amol Jadib6be5c12012-11-14 13:39:51 -08001132#endif
1133
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001134 void (*entry)(unsigned, unsigned, unsigned*) = (entry_func_ptr*)(PA((addr_t)kernel));
Deepa Dinamani25a9f762012-11-30 15:57:15 -08001135 uint32_t tags_phys = PA((addr_t)tags);
vijay kumar1a50a642015-11-16 12:41:15 +05301136 struct kernel64_hdr *kptr = ((struct kernel64_hdr*)(PA((addr_t)kernel)));
Deepa Dinamani25a9f762012-11-30 15:57:15 -08001137
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301138 ramdisk = (void *)PA((addr_t)ramdisk);
Neeti Desaie245d492012-06-01 12:52:13 -07001139
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001140 final_cmdline = update_cmdline((const char*)cmdline);
1141
Neeti Desai17379b82012-06-04 18:42:53 -07001142#if DEVICE_TREE
Amol Jadib6be5c12012-11-14 13:39:51 -08001143 dprintf(INFO, "Updating device tree: start\n");
1144
Neeti Desai17379b82012-06-04 18:42:53 -07001145 /* Update the Device Tree */
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301146 ret = update_device_tree((void *)tags,(const char *)final_cmdline, ramdisk, ramdisk_size);
Neeti Desai17379b82012-06-04 18:42:53 -07001147 if(ret)
1148 {
1149 dprintf(CRITICAL, "ERROR: Updating Device Tree Failed \n");
1150 ASSERT(0);
1151 }
Amol Jadib6be5c12012-11-14 13:39:51 -08001152 dprintf(INFO, "Updating device tree: done\n");
Neeti Desai17379b82012-06-04 18:42:53 -07001153#else
Neeti Desaie245d492012-06-01 12:52:13 -07001154 /* Generating the Atags */
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001155 generate_atags(tags, final_cmdline, ramdisk, ramdisk_size);
Neeti Desai17379b82012-06-04 18:42:53 -07001156#endif
Neeti Desaie245d492012-06-01 12:52:13 -07001157
Monika Singh0ec6db82019-07-18 16:57:58 +05301158#if VERIFIED_BOOT
Monika Singhb0db4b82018-09-26 12:18:02 +05301159 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05301160 {
1161 if (device.verity_mode == 0) {
lijuangbdd9bb42016-03-01 18:22:17 +08001162#if FBCON_DISPLAY_MSG
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001163#if ENABLE_VB_ATTEST
Mayank Grover889be1b2017-09-12 20:12:23 +05301164 display_bootverify_menu(DISPLAY_MENU_EIO);
1165 wait_for_users_action();
1166 if(!pwr_key_is_pressed)
1167 shutdown_device();
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001168#else
Mayank Grover889be1b2017-09-12 20:12:23 +05301169 display_bootverify_menu(DISPLAY_MENU_LOGGING);
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001170#endif
Mayank Grover889be1b2017-09-12 20:12:23 +05301171 wait_for_users_action();
lijuangbdd9bb42016-03-01 18:22:17 +08001172#else
Mayank Grover889be1b2017-09-12 20:12:23 +05301173 dprintf(CRITICAL,
1174 "The dm-verity is not started in enforcing mode.\nWait for 5 seconds before proceeding\n");
1175 mdelay(5000);
lijuangbdd9bb42016-03-01 18:22:17 +08001176#endif
Mayank Grover889be1b2017-09-12 20:12:23 +05301177 }
lijuangbdd9bb42016-03-01 18:22:17 +08001178 }
lijuangbdd9bb42016-03-01 18:22:17 +08001179#endif
1180
1181#if VERIFIED_BOOT
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07001182 /* Write protect the device info */
Channagoud Kadabi3bd9d1e2015-05-05 16:18:20 -07001183 if (!boot_into_recovery && target_build_variant_user() && devinfo_present && mmc_write_protect("devinfo", 1))
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07001184 {
1185 dprintf(INFO, "Failed to write protect dev info\n");
1186 ASSERT(0);
1187 }
1188#endif
1189
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08001190 /* Turn off splash screen if enabled */
1191#if DISPLAY_SPLASH_SCREEN
1192 target_display_shutdown();
1193#endif
1194
Veera Sundaram Sankaran67ea0932015-09-25 10:09:30 -07001195 /* Perform target specific cleanup */
1196 target_uninit();
Monika Singh292b3e92018-03-17 22:40:23 +05301197 free_verified_boot_resource(&info);
1198 if (final_cmdline)
1199 free(final_cmdline);
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08001200
Deepa Dinamani33734bc2013-03-06 12:16:06 -08001201 dprintf(INFO, "booting linux @ %p, ramdisk @ %p (%d), tags/device tree @ %p\n",
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301202 entry, ramdisk, ramdisk_size, (void *)tags_phys);
Brian Swetland9c4c0752009-01-25 16:23:50 -08001203
1204 enter_critical_section();
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001205
Amol Jadi4421e652011-06-16 15:00:48 -07001206 /* do any platform specific cleanup before kernel entry */
1207 platform_uninit();
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001208
Brian Swetland9c4c0752009-01-25 16:23:50 -08001209 arch_disable_cache(UCACHE);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001210
Amol Jadi504f9fe2012-08-16 13:56:48 -07001211#if ARM_WITH_MMU
Brian Swetland9c4c0752009-01-25 16:23:50 -08001212 arch_disable_mmu();
Amol Jadi504f9fe2012-08-16 13:56:48 -07001213#endif
Amol Jadi492d5a52013-03-15 16:12:34 -07001214 bs_set_timestamp(BS_KERNEL_ENTRY);
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001215
1216 if (IS_ARM64(kptr))
1217 /* Jump to a 64bit kernel */
1218 scm_elexec_call((paddr_t)kernel, tags_phys);
1219 else
1220 /* Jump to a 32bit kernel */
1221 entry(0, machtype, (unsigned*)tags_phys);
Brian Swetland9c4c0752009-01-25 16:23:50 -08001222}
1223
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001224/* Function to check if the memory address range falls within the aboot
1225 * boundaries.
1226 * start: Start of the memory region
1227 * size: Size of the memory region
1228 */
Vijay Kumar Pendoti9c002ad2016-03-09 13:52:45 +05301229int check_aboot_addr_range_overlap(uintptr_t start, uint32_t size)
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001230{
1231 /* Check for boundary conditions. */
Sundarajan Srinivasance2a0ea2013-12-16 17:02:56 -08001232 if ((UINT_MAX - start) < size)
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001233 return -1;
1234
1235 /* Check for memory overlap. */
1236 if ((start < MEMBASE) && ((start + size) <= MEMBASE))
1237 return 0;
Channagoud Kadabi94143912013-10-15 12:53:52 -07001238 else if (start >= (MEMBASE + MEMSIZE))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001239 return 0;
1240 else
1241 return -1;
1242}
1243
Mayank Grovere559cec2017-10-17 15:12:03 +05301244/* Function to check if the memory address range falls beyond ddr region.
1245 * start: Start of the memory region
1246 * size: Size of the memory region
1247 */
1248int check_ddr_addr_range_bound(uintptr_t start, uint32_t size)
1249{
1250 uintptr_t ddr_pa_start_addr = PA(get_ddr_start());
1251 uint64_t ddr_size = smem_get_ddr_size();
1252 uint64_t ddr_pa_end_addr = ddr_pa_start_addr + ddr_size;
1253 uintptr_t pa_start_addr = PA(start);
1254
1255 /* Check for boundary conditions. */
1256 if ((UINT_MAX - start) < size)
1257 return -1;
1258
1259 /* Check if memory range is beyond the ddr range. */
1260 if (pa_start_addr < ddr_pa_start_addr ||
1261 pa_start_addr >= (ddr_pa_end_addr) ||
1262 (pa_start_addr + size) > ddr_pa_end_addr)
1263 return -1;
1264 else
1265 return 0;
1266}
1267
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001268BUF_DMA_ALIGN(buf, BOOT_IMG_MAX_PAGE_SIZE); //Equal to max-supported pagesize
Dima Zavin214cc642009-01-26 11:16:21 -08001269
Mayank Groverdd080e82018-09-04 20:12:13 +05301270int getimage(void **image_buffer, uint32_t *imgsize,
1271 const char *imgname)
Monika Singh292b3e92018-03-17 22:40:23 +05301272{
Mayank Groverdd080e82018-09-04 20:12:13 +05301273 uint32_t loadedindex;
1274 if (image_buffer == NULL || imgsize == NULL ||
Monika Singh292b3e92018-03-17 22:40:23 +05301275 imgname == NULL) {
1276 dprintf(CRITICAL, "getimage: invalid parameters\n");
1277 return -1;
1278 }
Mayank Groverdd080e82018-09-04 20:12:13 +05301279 for (loadedindex = 0; loadedindex < info.num_loaded_images; loadedindex++) {
1280 if (!strncmp(info.images[loadedindex].name, imgname,
Monika Singh292b3e92018-03-17 22:40:23 +05301281 strlen(imgname))) {
Mayank Groverdd080e82018-09-04 20:12:13 +05301282 *image_buffer = info.images[loadedindex].image_buffer;
1283 *imgsize = info.images[loadedindex].imgsize;
Mayank Grover027a9412018-09-04 15:12:05 +05301284 dprintf(SPEW, "getimage(): Loaded image [%s|%d]\n",
1285 info.images[loadedindex].name,
1286 info.images[loadedindex].imgsize);
Monika Singh292b3e92018-03-17 22:40:23 +05301287 return 0;
1288 }
1289 }
1290 return -1;
1291}
1292
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001293static void verify_signed_bootimg(uint32_t bootimg_addr, uint32_t bootimg_size)
1294{
1295 int ret;
Channagoud Kadabia8c623f2015-01-13 14:48:48 -08001296
1297#if !VERIFIED_BOOT
Sundarajan Srinivasance54d6e2013-11-11 12:45:00 -08001298#if IMAGE_VERIF_ALGO_SHA1
1299 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA1;
1300#else
1301 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
1302#endif
Channagoud Kadabia8c623f2015-01-13 14:48:48 -08001303#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001304
1305 /* Assume device is rooted at this time. */
1306 device.is_tampered = 1;
1307
1308 dprintf(INFO, "Authenticating boot image (%d): start\n", bootimg_size);
1309
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001310#if VERIFIED_BOOT
Monika Singh7d2fc272018-03-16 17:16:01 +05301311 uint32_t bootstate;
1312 if(boot_into_recovery &&
Mayank Grover68fbf0d2017-10-24 14:13:39 +05301313 (!partition_multislot_is_supported()))
Monika Singh7d2fc272018-03-16 17:16:01 +05301314 {
1315 ret = boot_verify_image((unsigned char *)bootimg_addr,
1316 bootimg_size, "/recovery", &bootstate);
1317 }
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001318 else
Monika Singh7d2fc272018-03-16 17:16:01 +05301319 {
1320 ret = boot_verify_image((unsigned char *)bootimg_addr,
1321 bootimg_size, "/boot", &bootstate);
1322 }
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001323 boot_verify_print_state();
1324#else
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001325 ret = image_verify((unsigned char *)bootimg_addr,
1326 (unsigned char *)(bootimg_addr + bootimg_size),
1327 bootimg_size,
Sundarajan Srinivasance54d6e2013-11-11 12:45:00 -08001328 auth_algo);
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001329#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001330 dprintf(INFO, "Authenticating boot image: done return value = %d\n", ret);
1331
1332 if (ret)
1333 {
1334 /* Authorized kernel */
1335 device.is_tampered = 0;
Sundarajan Srinivasan3fb21f12013-09-16 18:36:15 -07001336 auth_kernel_img = 1;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001337 }
1338
Amit Blay4aa292f2015-04-28 21:55:59 +03001339#ifdef MDTP_SUPPORT
1340 {
1341 /* Verify MDTP lock.
1342 * For boot & recovery partitions, use aboot's verification result.
1343 */
1344 mdtp_ext_partition_verification_t ext_partition;
1345 ext_partition.partition = boot_into_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
1346 ext_partition.integrity_state = device.is_tampered ? MDTP_PARTITION_STATE_INVALID : MDTP_PARTITION_STATE_VALID;
1347 ext_partition.page_size = 0; /* Not needed since already validated */
1348 ext_partition.image_addr = 0; /* Not needed since already validated */
1349 ext_partition.image_size = 0; /* Not needed since already validated */
1350 ext_partition.sig_avail = FALSE; /* Not needed since already validated */
1351 mdtp_fwlock_verify_lock(&ext_partition);
1352 }
1353#endif /* MDTP_SUPPORT */
1354
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001355#if USE_PCOM_SECBOOT
1356 set_tamper_flag(device.is_tampered);
1357#endif
1358
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001359#if VERIFIED_BOOT
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001360 switch(boot_verify_get_state())
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001361 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001362 case RED:
lijuanga40d6302015-07-20 20:10:13 +08001363#if FBCON_DISPLAY_MSG
lijuang9a7d3b92015-11-30 14:41:24 +08001364 display_bootverify_menu(DISPLAY_MENU_RED);
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001365#if ENABLE_VB_ATTEST
1366 mdelay(DELAY_WAIT);
1367 shutdown_device();
1368#else
lijuanga40d6302015-07-20 20:10:13 +08001369 wait_for_users_action();
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001370#endif
lijuanga40d6302015-07-20 20:10:13 +08001371#else
1372 dprintf(CRITICAL,
1373 "Your device has failed verification and may not work properly.\nWait for 5 seconds before proceeding\n");
1374 mdelay(5000);
1375#endif
1376
1377 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001378 case YELLOW:
lijuanga40d6302015-07-20 20:10:13 +08001379#if FBCON_DISPLAY_MSG
lijuang9a7d3b92015-11-30 14:41:24 +08001380 display_bootverify_menu(DISPLAY_MENU_YELLOW);
lijuanga40d6302015-07-20 20:10:13 +08001381 wait_for_users_action();
1382#else
1383 dprintf(CRITICAL,
1384 "Your device has loaded a different operating system.\nWait for 5 seconds before proceeding\n");
1385 mdelay(5000);
1386#endif
1387 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001388 default:
lijuanga40d6302015-07-20 20:10:13 +08001389 break;
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001390 }
1391#endif
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001392#if !VERIFIED_BOOT
Unnati Gandhi1be04752015-03-27 19:41:53 +05301393 if(device.is_tampered)
1394 {
1395 write_device_info_mmc(&device);
1396 #ifdef TZ_TAMPER_FUSE
Monika Singh98257462018-06-06 11:28:49 +05301397 set_tamper_fuse_cmd(HLOS_IMG_TAMPER_FUSE);
Unnati Gandhi1be04752015-03-27 19:41:53 +05301398 #endif
1399 #ifdef ASSERT_ON_TAMPER
1400 dprintf(CRITICAL, "Device is tampered. Asserting..\n");
1401 ASSERT(0);
1402 #endif
1403 }
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001404#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001405}
1406
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301407static bool check_format_bit()
1408{
1409 bool ret = false;
1410 int index;
1411 uint64_t offset;
1412 struct boot_selection_info *in = NULL;
1413 char *buf = NULL;
1414
1415 index = partition_get_index("bootselect");
1416 if (index == INVALID_PTN)
1417 {
1418 dprintf(INFO, "Unable to locate /bootselect partition\n");
1419 return ret;
1420 }
1421 offset = partition_get_offset(index);
1422 if(!offset)
1423 {
1424 dprintf(INFO, "partition /bootselect doesn't exist\n");
1425 return ret;
1426 }
1427 buf = (char *) memalign(CACHE_LINE, ROUNDUP(page_size, CACHE_LINE));
Mayank Grover48860402016-11-29 12:34:53 +05301428 mmc_set_lun(partition_get_lun(index));
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301429 ASSERT(buf);
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301430 if (mmc_read(offset, (uint32_t *)buf, page_size))
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301431 {
1432 dprintf(INFO, "mmc read failure /bootselect %d\n", page_size);
1433 free(buf);
1434 return ret;
1435 }
1436 in = (struct boot_selection_info *) buf;
1437 if ((in->signature == BOOTSELECT_SIGNATURE) &&
1438 (in->version == BOOTSELECT_VERSION)) {
1439 if ((in->state_info & BOOTSELECT_FORMAT) &&
1440 !(in->state_info & BOOTSELECT_FACTORY))
1441 ret = true;
1442 } else {
1443 dprintf(CRITICAL, "Signature: 0x%08x or version: 0x%08x mismatched of /bootselect\n",
1444 in->signature, in->version);
1445 ASSERT(0);
1446 }
1447 free(buf);
1448 return ret;
1449}
1450
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001451void boot_verifier_init()
1452{
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001453 uint32_t boot_state;
1454 /* Check if device unlock */
1455 if(device.is_unlocked)
1456 {
1457 boot_verify_send_event(DEV_UNLOCK);
1458 boot_verify_print_state();
1459 dprintf(CRITICAL, "Device is unlocked! Skipping verification...\n");
1460 return;
1461 }
1462 else
1463 {
1464 boot_verify_send_event(BOOT_INIT);
1465 }
1466
1467 /* Initialize keystore */
1468 boot_state = boot_verify_keystore_init();
1469 if(boot_state == YELLOW)
1470 {
1471 boot_verify_print_state();
1472 dprintf(CRITICAL, "Keystore verification failed! Continuing anyways...\n");
1473 }
1474}
1475
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301476/* Function to return recovery appended dtbo buffer info */
1477void get_recovery_dtbo_info(uint32_t *dtbo_size, void **dtbo_buf)
1478{
1479 *dtbo_size = recovery_dtbo_size;
1480 *dtbo_buf = recovery_dtbo_buf;
1481 return;
1482}
1483
Shashank Mittal23b8f422010-04-16 19:27:21 -07001484int boot_linux_from_mmc(void)
1485{
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301486 boot_img_hdr *hdr = (void*) buf;
1487 boot_img_hdr *uhdr;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001488 unsigned offset = 0;
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07001489 int rcode;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001490 unsigned long long ptn = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07001491 int index = INVALID_PTN;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001492
Shashank Mittalcd98d472011-08-02 14:29:24 -07001493 unsigned char *image_addr = 0;
1494 unsigned kernel_actual;
1495 unsigned ramdisk_actual;
1496 unsigned imagesize_actual;
Neeti Desai465491e2012-07-31 12:53:35 -07001497 unsigned second_actual = 0;
Parth Dixit1375d9e2019-07-08 20:56:13 +05301498 void * image_buf = NULL;
Neeti Desai465491e2012-07-31 12:53:35 -07001499
Matthew Qin271927e2015-03-31 22:07:07 -04001500 unsigned int dtb_size = 0;
Parth Dixit1375d9e2019-07-08 20:56:13 +05301501 unsigned dtb_image_size = 0;
1502 uint32_t dtb_image_offset = 0;
Matthew Qinbb7923d2015-02-09 10:56:09 +08001503 unsigned int out_len = 0;
1504 unsigned int out_avai_len = 0;
1505 unsigned char *out_addr = NULL;
1506 uint32_t dtb_offset = 0;
1507 unsigned char *kernel_start_addr = NULL;
1508 unsigned int kernel_size = 0;
Ameya Thakur10a33452016-06-13 14:24:26 -07001509 unsigned int patched_kernel_hdr_size = 0;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301510 uint64_t image_size = 0;
Matthew Qinbb7923d2015-02-09 10:56:09 +08001511 int rc;
Monika Singh292b3e92018-03-17 22:40:23 +05301512#if VERIFIED_BOOT_2
1513 int status;
Mayank Grover027a9412018-09-04 15:12:05 +05301514 void *dtbo_image_buf = NULL;
1515 uint32_t dtbo_image_sz = 0;
Mayank Grover9df84c02018-08-30 15:46:35 +05301516 void *vbmeta_image_buf = NULL;
1517 uint32_t vbmeta_image_sz = 0;
Monika Singh292b3e92018-03-17 22:40:23 +05301518#endif
Mayank Groverc93cad82017-10-03 12:23:45 +05301519 char *ptn_name = NULL;
Neeti Desai465491e2012-07-31 12:53:35 -07001520#if DEVICE_TREE
1521 struct dt_table *table;
Joel Kingaa335dc2013-06-03 16:11:08 -07001522 struct dt_entry dt_entry;
Neeti Desai465491e2012-07-31 12:53:35 -07001523 unsigned dt_table_offset;
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -08001524 uint32_t dt_actual;
Deepa Dinamani19648b42013-09-05 17:05:55 -07001525 uint32_t dt_hdr_size;
Matthew Qin271927e2015-03-31 22:07:07 -04001526 unsigned char *best_match_dt_addr = NULL;
Neeti Desai465491e2012-07-31 12:53:35 -07001527#endif
Matthew Qin49e51fa2015-02-09 10:40:45 +08001528 struct kernel64_hdr *kptr = NULL;
Mayank Grover351a75e2017-05-30 20:06:08 +05301529 int current_active_slot = INVALID;
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001530
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301531 if (check_format_bit())
1532 boot_into_recovery = 1;
1533
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07001534 if (!boot_into_recovery) {
1535 memset(ffbm_mode_string, '\0', sizeof(ffbm_mode_string));
1536 rcode = get_ffbm(ffbm_mode_string, sizeof(ffbm_mode_string));
1537 if (rcode <= 0) {
1538 boot_into_ffbm = false;
1539 if (rcode < 0)
1540 dprintf(CRITICAL,"failed to get ffbm cookie");
1541 } else
1542 boot_into_ffbm = true;
1543 } else
1544 boot_into_ffbm = false;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301545 uhdr = (boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001546 if (!memcmp(uhdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
1547 dprintf(INFO, "Unified boot method!\n");
1548 hdr = uhdr;
1549 goto unified_boot;
1550 }
Mayank Groverc93cad82017-10-03 12:23:45 +05301551
1552 /* For a/b recovery image code is on boot partition.
1553 If we support multislot, always use boot partition. */
1554 if (boot_into_recovery &&
Mayank Grover8ab4a762019-04-25 17:23:34 +05301555 ((!partition_multislot_is_supported()) ||
1556 (target_dynamic_partition_supported())))
Mayank Groverc93cad82017-10-03 12:23:45 +05301557 ptn_name = "recovery";
1558 else
1559 ptn_name = "boot";
1560
1561 index = partition_get_index(ptn_name);
1562 ptn = partition_get_offset(index);
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301563 image_size = partition_get_size(index);
1564 if(ptn == 0 || image_size == 0) {
Mayank Groverc93cad82017-10-03 12:23:45 +05301565 dprintf(CRITICAL, "ERROR: No %s partition found\n", ptn_name);
1566 return -1;
Kinson Chikf1a43512011-07-14 11:28:39 -07001567 }
Mayank Groverc93cad82017-10-03 12:23:45 +05301568
Channagoud Kadabief0547c2015-02-10 12:57:38 -08001569 /* Set Lun for boot & recovery partitions */
1570 mmc_set_lun(partition_get_lun(index));
Shashank Mittal23b8f422010-04-16 19:27:21 -07001571
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301572 if (mmc_read(ptn + offset, (uint32_t *) buf, page_size)) {
Shashank Mittal23b8f422010-04-16 19:27:21 -07001573 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
1574 return -1;
1575 }
Shashank Mittal23b8f422010-04-16 19:27:21 -07001576
1577 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07001578 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
Mayank Grover351a75e2017-05-30 20:06:08 +05301579 return ERR_INVALID_BOOT_MAGIC;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001580 }
1581
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -07001582 if (hdr->page_size && (hdr->page_size != page_size)) {
vijay kumar2e21b3a2014-06-26 17:40:15 +05301583
1584 if (hdr->page_size > BOOT_IMG_MAX_PAGE_SIZE) {
1585 dprintf(CRITICAL, "ERROR: Invalid page size\n");
1586 return -1;
1587 }
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -07001588 page_size = hdr->page_size;
1589 page_mask = page_size - 1;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001590 }
1591
Matthew Qin49e51fa2015-02-09 10:40:45 +08001592 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
1593 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05301594 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001595
Matthew Qin49e51fa2015-02-09 10:40:45 +08001596 image_addr = (unsigned char *)target_get_scratch_address();
Mayank Grover6fd36792018-09-10 13:26:58 +05301597#if VERIFIED_BOOT_2
1598 /* Create hole in start of image for VB salt to copy */
1599 image_addr += SALT_BUFF_OFFSET;
1600#endif
Kishor PK9e91b592017-05-24 12:14:55 +05301601 memcpy(image_addr, (void *)buf, page_size);
1602
1603 /* ensure commandline is terminated */
1604 hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
Matthew Qin49e51fa2015-02-09 10:40:45 +08001605
1606#if DEVICE_TREE
Parth Dixit4097b622016-03-15 14:42:27 +05301607#ifndef OSVERSION_IN_BOOTIMAGE
1608 dt_size = hdr->dt_size;
Mayank Grover5a502582018-09-12 11:24:49 +05301609#else
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301610 dprintf(INFO, "BootImage Header: %d\n", hdr->header_version);
Mayank Grover5a502582018-09-12 11:24:49 +05301611#endif
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301612
Parth Dixit4097b622016-03-15 14:42:27 +05301613 dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05301614 if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + (uint64_t)dt_actual + page_size)) {
Vijay Kumar Pendoti208f9622016-06-09 19:34:01 +05301615 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields at %u in %s\n",__LINE__,__FILE__);
1616 return -1;
1617 }
Kishor PKd8ddcad2017-07-27 13:53:57 +05301618 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual + dt_actual);
Matthew Qin49e51fa2015-02-09 10:40:45 +08001619#else
Kishor PKd8ddcad2017-07-27 13:53:57 +05301620 if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual + (uint64_t)second_actual + page_size)) {
Vijay Kumar Pendoti208f9622016-06-09 19:34:01 +05301621 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields at %u in %s\n",__LINE__,__FILE__);
1622 return -1;
1623 }
Kishor PKd8ddcad2017-07-27 13:53:57 +05301624 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
Matthew Qin49e51fa2015-02-09 10:40:45 +08001625#endif
Parth Dixit1375d9e2019-07-08 20:56:13 +05301626 dtb_image_size = hdr->kernel_size;
Matthew Qin49e51fa2015-02-09 10:40:45 +08001627
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301628#ifdef OSVERSION_IN_BOOTIMAGE
1629 /* If header version is ONE and booting into recovery,
1630 dtbo is appended with recovery image.
1631 Doing following:
1632 * Validating the recovery offset and size.
1633 * Extracting recovery dtbo to be used as dtbo.
1634 */
1635 if (boot_into_recovery &&
1636 hdr->header_version == BOOT_HEADER_VERSION_ONE)
1637 {
1638 struct boot_img_hdr_v1 *hdr1 =
1639 (struct boot_img_hdr_v1 *) (image_addr + sizeof(boot_img_hdr));
Mayank Grovera1a83c72018-09-24 11:23:15 +05301640 unsigned int recovery_dtbo_actual = 0;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301641
Mayank Grovera1a83c72018-09-24 11:23:15 +05301642 recovery_dtbo_actual = ROUND_TO_PAGE(hdr1->recovery_dtbo_size, page_mask);
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301643 if ((hdr1->header_size !=
1644 sizeof(struct boot_img_hdr_v1) + sizeof(boot_img_hdr)))
1645 {
1646 dprintf(CRITICAL, "Invalid boot image header: %d\n", hdr1->header_size);
1647 return -1;
1648 }
1649
Mayank Grovera1a83c72018-09-24 11:23:15 +05301650 if (recovery_dtbo_actual > MAX_SUPPORTED_DTBO_IMG_BUF)
1651 {
1652 dprintf(CRITICAL, "Recovery Dtbo Size too big %x, Allowed size %x\n", recovery_dtbo_actual,
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301653 MAX_SUPPORTED_DTBO_IMG_BUF);
1654 return -1;
1655 }
1656
Mayank Grovera1a83c72018-09-24 11:23:15 +05301657 if (UINT_MAX < ((uint64_t)imagesize_actual + recovery_dtbo_actual))
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301658 {
1659 dprintf(CRITICAL, "Integer overflow detected in recoveryimage header fields at %u in %s\n",__LINE__,__FILE__);
1660 return -1;
1661 }
1662
Mayank Grovera1a83c72018-09-24 11:23:15 +05301663 if (UINT_MAX < (hdr1->recovery_dtbo_offset + recovery_dtbo_actual)) {
1664 dprintf(CRITICAL,
1665 "Integer overflow detected in recovery image header fields at %u in %s\n",__LINE__,__FILE__);
1666 return -1;
1667 }
1668
1669 if (hdr1->recovery_dtbo_offset + recovery_dtbo_actual > image_size)
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301670 {
1671 dprintf(CRITICAL, "Invalid recovery dtbo: Recovery Dtbo Offset=0x%llx,"
1672 " Recovery Dtbo Size=0x%x, Image Size=0x%llx\n",
1673 hdr1->recovery_dtbo_offset, recovery_dtbo_size, image_size);
1674 return -1;
1675 }
1676
1677 recovery_dtbo_buf = (void *)(hdr1->recovery_dtbo_offset + image_addr);
Mayank Grovera1a83c72018-09-24 11:23:15 +05301678 recovery_dtbo_size = recovery_dtbo_actual;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301679 imagesize_actual += recovery_dtbo_size;
1680
1681 dprintf(SPEW, "Header version: %d\n", hdr->header_version);
1682 dprintf(SPEW, "Recovery Dtbo Size 0x%x\n", recovery_dtbo_size);
1683 dprintf(SPEW, "Recovery Dtbo Offset 0x%llx\n", hdr1->recovery_dtbo_offset);
1684
1685 }
Parth Dixit1375d9e2019-07-08 20:56:13 +05301686
1687 if ( hdr->header_version == BOOT_HEADER_VERSION_TWO) {
1688 struct boot_img_hdr_v1 *hdr1 =
1689 (struct boot_img_hdr_v1 *) (image_addr + sizeof(boot_img_hdr));
1690 struct boot_img_hdr_v2 *hdr2 = (struct boot_img_hdr_v2 *)
1691 (image_addr + sizeof(boot_img_hdr) +
1692 BOOT_IMAGE_HEADER_V2_OFFSET);
1693 unsigned int recovery_dtbo_actual = 0;
1694
lijuang0b17ba22019-09-04 14:20:47 +08001695 recovery_dtbo_actual =
1696 ROUND_TO_PAGE(hdr1->recovery_dtbo_size, page_mask);
1697 imagesize_actual += recovery_dtbo_actual;
Parth Dixit1375d9e2019-07-08 20:56:13 +05301698
1699 imagesize_actual += ROUND_TO_PAGE(hdr2->dtb_size, page_mask);
1700
1701
1702 dtb_image_offset = page_size + patched_kernel_hdr_size +
1703 kernel_actual + ramdisk_actual + second_actual +
1704 recovery_dtbo_actual;
1705
1706 dprintf(SPEW, "Header version: %d\n", hdr->header_version);
1707 dprintf(SPEW, "Dtb image offset 0x%x\n", dtb_image_offset);
1708 }
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301709#endif
1710
Parth Dixit1375d9e2019-07-08 20:56:13 +05301711
Saranya Chidurab1aaf232018-11-19 15:47:50 +05301712 /* Validate the boot/recovery image size is within the bounds of partition size */
1713 if (imagesize_actual > image_size) {
1714 dprintf(CRITICAL, "Image size is greater than partition size.\n");
1715 return -1;
1716 }
1717
Matthew Qin49e51fa2015-02-09 10:40:45 +08001718#if VERIFIED_BOOT
1719 boot_verifier_init();
1720#endif
1721
Mayank Grover1ceaee22019-04-01 17:54:32 +05301722#if VERIFIED_BOOT_2
1723 /* read full partition if device is unlocked */
1724 if (device.is_unlocked)
1725 imagesize_actual = image_size;
1726#endif
1727
Vijay Kumar Pendoti9c002ad2016-03-09 13:52:45 +05301728 if (check_aboot_addr_range_overlap((uintptr_t) image_addr, imagesize_actual))
Matthew Qin49e51fa2015-02-09 10:40:45 +08001729 {
1730 dprintf(CRITICAL, "Boot image buffer address overlaps with aboot addresses.\n");
1731 return -1;
1732 }
1733
Matthew Qinbb7923d2015-02-09 10:56:09 +08001734 /*
1735 * Update loading flow of bootimage to support compressed/uncompressed
1736 * bootimage on both 64bit and 32bit platform.
1737 * 1. Load bootimage from emmc partition onto DDR.
1738 * 2. Check if bootimage is gzip format. If yes, decompress compressed kernel
1739 * 3. Check kernel header and update kernel load addr for 64bit and 32bit
1740 * platform accordingly.
1741 * 4. Sanity Check on kernel_addr and ramdisk_addr and copy data.
1742 */
Mayank Grover351a75e2017-05-30 20:06:08 +05301743 if (partition_multislot_is_supported())
1744 {
1745 current_active_slot = partition_find_active_slot();
1746 dprintf(INFO, "Loading boot image (%d) active_slot(%s): start\n",
1747 imagesize_actual, SUFFIX_SLOT(current_active_slot));
1748 }
1749 else
1750 {
1751 dprintf(INFO, "Loading (%s) image (%d): start\n",
1752 (!boot_into_recovery ? "boot" : "recovery"),imagesize_actual);
1753 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08001754 bs_set_timestamp(BS_KERNEL_LOAD_START);
1755
Gaurav Nebhwani43e2a462016-03-17 21:32:56 +05301756 if ((target_get_max_flash_size() - page_size) < imagesize_actual)
1757 {
1758 dprintf(CRITICAL, "booimage size is greater than DDR can hold\n");
1759 return -1;
1760 }
Kishor PK9e91b592017-05-24 12:14:55 +05301761 offset = page_size;
1762 /* Read image without signature and header*/
1763 if (mmc_read(ptn + offset, (void *)(image_addr + offset), imagesize_actual - page_size))
Matthew Qin49e51fa2015-02-09 10:40:45 +08001764 {
1765 dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
1766 return -1;
1767 }
1768
Mayank Grover351a75e2017-05-30 20:06:08 +05301769 if (partition_multislot_is_supported())
1770 {
1771 dprintf(INFO, "Loading boot image (%d) active_slot(%s): done\n",
1772 imagesize_actual, SUFFIX_SLOT(current_active_slot));
1773 }
1774 else
1775 {
1776 dprintf(INFO, "Loading (%s) image (%d): done\n",
Channagoud Kadabif0705b52015-08-20 14:16:08 -07001777 (!boot_into_recovery ? "boot" : "recovery"),imagesize_actual);
1778
Mayank Grover351a75e2017-05-30 20:06:08 +05301779 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08001780 bs_set_timestamp(BS_KERNEL_LOAD_DONE);
1781
1782 /* Authenticate Kernel */
1783 dprintf(INFO, "use_signed_kernel=%d, is_unlocked=%d, is_tampered=%d.\n",
1784 (int) target_use_signed_kernel(),
1785 device.is_unlocked,
1786 device.is_tampered);
Monika Singh292b3e92018-03-17 22:40:23 +05301787#if VERIFIED_BOOT_2
Mayank Grover1ceaee22019-04-01 17:54:32 +05301788 /* if device is unlocked skip reading signature, as full partition is read */
1789 if (!device.is_unlocked)
Monika Singh292b3e92018-03-17 22:40:23 +05301790 {
Mayank Grover1ceaee22019-04-01 17:54:32 +05301791 offset = imagesize_actual;
1792 if (check_aboot_addr_range_overlap((uintptr_t)image_addr + offset, page_size))
1793 {
1794 dprintf(CRITICAL, "Signature read buffer address overlaps with aboot addresses.\n");
1795 return -1;
1796 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08001797
Mayank Grover1ceaee22019-04-01 17:54:32 +05301798 /* Read signature */
1799 if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
1800 {
1801 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
1802 return -1;
1803 }
Monika Singh292b3e92018-03-17 22:40:23 +05301804 }
1805
Mayank Grover027a9412018-09-04 15:12:05 +05301806 /* load and validate dtbo partition */
1807 load_validate_dtbo_image(&dtbo_image_buf, &dtbo_image_sz);
1808
Mayank Grover9df84c02018-08-30 15:46:35 +05301809 /* load vbmeta partition */
1810 load_vbmeta_image(&vbmeta_image_buf, &vbmeta_image_sz);
1811
Monika Singh292b3e92018-03-17 22:40:23 +05301812 memset(&info, 0, sizeof(bootinfo));
Mayank Grover027a9412018-09-04 15:12:05 +05301813
1814 /* Pass loaded boot image passed */
Mayank Grover6fd36792018-09-10 13:26:58 +05301815 info.images[IMG_BOOT].image_buffer = SUB_SALT_BUFF_OFFSET(image_addr);
Mayank Grover027a9412018-09-04 15:12:05 +05301816 info.images[IMG_BOOT].imgsize = imagesize_actual;
1817 info.images[IMG_BOOT].name = ptn_name;
1818 ++info.num_loaded_images;
1819
1820 /* Pass loaded dtbo image */
1821 if (dtbo_image_buf != NULL) {
Mayank Grover6fd36792018-09-10 13:26:58 +05301822 info.images[IMG_DTBO].image_buffer =
1823 SUB_SALT_BUFF_OFFSET(dtbo_image_buf);
Mayank Grover027a9412018-09-04 15:12:05 +05301824 info.images[IMG_DTBO].imgsize = dtbo_image_sz;
1825 info.images[IMG_DTBO].name = "dtbo";
1826 ++info.num_loaded_images;
1827 }
1828
Mayank Grover9df84c02018-08-30 15:46:35 +05301829 /* Pass loaded vbmeta image */
1830 if (vbmeta_image_buf != NULL) {
1831 info.images[IMG_VBMETA].image_buffer = vbmeta_image_buf;
1832 info.images[IMG_VBMETA].imgsize = vbmeta_image_sz;
1833 info.images[IMG_VBMETA].name = "vbmeta";
1834 ++info.num_loaded_images;
1835 }
1836
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301837 info.header_version = hdr->header_version;
Monika Singh292b3e92018-03-17 22:40:23 +05301838 info.multi_slot_boot = partition_multislot_is_supported();
1839 info.bootreason_alarm = boot_reason_alarm;
1840 info.bootinto_recovery = boot_into_recovery;
1841 status = load_image_and_auth(&info);
1842 if(status)
1843 return -1;
1844
1845 vbcmdline = info.vbcmdline;
Mayank Grover9df84c02018-08-30 15:46:35 +05301846
1847 /* Free the buffer allocated to vbmeta post verification */
Saranya Chidurab4933332018-10-15 17:30:06 +05301848 if (vbmeta_image_buf != NULL) {
1849 free(vbmeta_image_buf);
1850 --info.num_loaded_images;
1851 }
Monika Singh292b3e92018-03-17 22:40:23 +05301852#else
Channagoud Kadabi736c4962015-08-21 11:56:52 -07001853 /* Change the condition a little bit to include the test framework support.
1854 * We would never reach this point if device is in fastboot mode, even if we did
1855 * that means we are in test mode, so execute kernel authentication part for the
1856 * tests */
Parth Dixitcb0c6082015-12-30 15:01:13 +05301857 if((target_use_signed_kernel() && (!device.is_unlocked)) || is_test_mode_enabled())
Matthew Qin49e51fa2015-02-09 10:40:45 +08001858 {
1859 offset = imagesize_actual;
Vijay Kumar Pendoti9c002ad2016-03-09 13:52:45 +05301860 if (check_aboot_addr_range_overlap((uintptr_t)image_addr + offset, page_size))
Matthew Qin49e51fa2015-02-09 10:40:45 +08001861 {
1862 dprintf(CRITICAL, "Signature read buffer address overlaps with aboot addresses.\n");
1863 return -1;
1864 }
1865
1866 /* Read signature */
1867 if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
1868 {
1869 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
1870 return -1;
1871 }
1872
1873 verify_signed_bootimg((uint32_t)image_addr, imagesize_actual);
Channagoud Kadabi736c4962015-08-21 11:56:52 -07001874 /* The purpose of our test is done here */
Parth Dixitcb0c6082015-12-30 15:01:13 +05301875 if(is_test_mode_enabled() && auth_kernel_img)
Channagoud Kadabi736c4962015-08-21 11:56:52 -07001876 return 0;
Matthew Qin49e51fa2015-02-09 10:40:45 +08001877 } else {
1878 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
1879 #ifdef TZ_SAVE_KERNEL_HASH
1880 aboot_save_boot_hash_mmc((uint32_t) image_addr, imagesize_actual);
1881 #endif /* TZ_SAVE_KERNEL_HASH */
Amit Blay4aa292f2015-04-28 21:55:59 +03001882
1883#ifdef MDTP_SUPPORT
1884 {
1885 /* Verify MDTP lock.
1886 * For boot & recovery partitions, MDTP will use boot_verifier APIs,
1887 * since verification was skipped in aboot. The signature is not part of the loaded image.
1888 */
1889 mdtp_ext_partition_verification_t ext_partition;
1890 ext_partition.partition = boot_into_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
1891 ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
1892 ext_partition.page_size = page_size;
1893 ext_partition.image_addr = (uint32)image_addr;
1894 ext_partition.image_size = imagesize_actual;
1895 ext_partition.sig_avail = FALSE;
1896 mdtp_fwlock_verify_lock(&ext_partition);
1897 }
1898#endif /* MDTP_SUPPORT */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001899 }
Monika Singh292b3e92018-03-17 22:40:23 +05301900#endif
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001901
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -07001902#if VERIFIED_BOOT
taozhang93088bd2016-11-16 15:50:46 +08001903 if((boot_verify_get_state() == ORANGE) && (!boot_into_ffbm))
Reut Zysmanba8a9d52016-02-18 11:44:04 +02001904 {
1905#if FBCON_DISPLAY_MSG
1906 display_bootverify_menu(DISPLAY_MENU_ORANGE);
1907 wait_for_users_action();
1908#else
1909 dprintf(CRITICAL,
1910 "Your device has been unlocked and can't be trusted.\nWait for 5 seconds before proceeding\n");
1911 mdelay(5000);
1912#endif
1913 }
1914#endif
1915
1916#if VERIFIED_BOOT
Monika Singh292b3e92018-03-17 22:40:23 +05301917 if (VB_M == target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05301918 {
1919 /* set boot and system versions. */
1920 set_os_version((unsigned char *)image_addr);
1921 // send root of trust
1922 if(!send_rot_command((uint32_t)device.is_unlocked))
1923 ASSERT(0);
1924 }
Parth Dixitbc9b6492015-10-18 00:41:38 +05301925#endif
Channagoud Kadabia22144f2013-03-20 11:49:01 -07001926 /*
Matthew Qinbb7923d2015-02-09 10:56:09 +08001927 * Check if the kernel image is a gzip package. If yes, need to decompress it.
1928 * If not, continue booting.
1929 */
1930 if (is_gzip_package((unsigned char *)(image_addr + page_size), hdr->kernel_size))
1931 {
1932 out_addr = (unsigned char *)(image_addr + imagesize_actual + page_size);
1933 out_avai_len = target_get_max_flash_size() - imagesize_actual - page_size;
Mayank Grover027a9412018-09-04 15:12:05 +05301934#if VERIFIED_BOOT_2
1935 if (dtbo_image_sz)
1936 out_avai_len -= DTBO_IMG_BUF;
1937#endif
Matthew Qin0b15b322015-05-19 05:20:54 -04001938 dprintf(INFO, "decompressing kernel image: start\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08001939 rc = decompress((unsigned char *)(image_addr + page_size),
1940 hdr->kernel_size, out_addr, out_avai_len,
1941 &dtb_offset, &out_len);
1942 if (rc)
1943 {
Matthew Qin0b15b322015-05-19 05:20:54 -04001944 dprintf(CRITICAL, "decompressing kernel image failed!!!\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08001945 ASSERT(0);
1946 }
1947
Matthew Qin0b15b322015-05-19 05:20:54 -04001948 dprintf(INFO, "decompressing kernel image: done\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08001949 kptr = (struct kernel64_hdr *)out_addr;
1950 kernel_start_addr = out_addr;
1951 kernel_size = out_len;
1952 } else {
Ameya Thakur10a33452016-06-13 14:24:26 -07001953 dprintf(INFO, "Uncpmpressed kernel in use\n");
1954 if (!strncmp((char*)(image_addr + page_size),
1955 PATCHED_KERNEL_MAGIC,
1956 sizeof(PATCHED_KERNEL_MAGIC) - 1)) {
1957 dprintf(INFO, "Patched kernel detected\n");
1958 kptr = (struct kernel64_hdr *)(image_addr + page_size +
1959 PATCHED_KERNEL_HEADER_SIZE);
1960 //The size of the kernel is stored at start of kernel image + 16
1961 //The dtb would start just after the kernel
1962 dtb_offset = *((uint32_t*)((unsigned char*)
1963 (image_addr + page_size +
1964 sizeof(PATCHED_KERNEL_MAGIC) -
1965 1)));
1966 //The actual kernel starts after the 20 byte header.
1967 kernel_start_addr = (unsigned char*)(image_addr +
1968 page_size + PATCHED_KERNEL_HEADER_SIZE);
1969 kernel_size = hdr->kernel_size;
1970 patched_kernel_hdr_size = PATCHED_KERNEL_HEADER_SIZE;
1971 } else {
1972 dprintf(INFO, "Kernel image not patched..Unable to locate dt offset\n");
1973 kptr = (struct kernel64_hdr *)(image_addr + page_size);
1974 kernel_start_addr = (unsigned char *)(image_addr + page_size);
1975 kernel_size = hdr->kernel_size;
1976 }
Matthew Qinbb7923d2015-02-09 10:56:09 +08001977 }
1978
1979 /*
Channagoud Kadabia22144f2013-03-20 11:49:01 -07001980 * Update the kernel/ramdisk/tags address if the boot image header
1981 * has default values, these default values come from mkbootimg when
1982 * the boot image is flashed using fastboot flash:raw
1983 */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001984 update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr));
Channagoud Kadabia22144f2013-03-20 11:49:01 -07001985
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001986 /* Get virtual addresses since the hdr saves physical addresses. */
1987 hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
1988 hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
1989 hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001990
Matthew Qinbb7923d2015-02-09 10:56:09 +08001991 kernel_size = ROUND_TO_PAGE(kernel_size, page_mask);
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001992 /* Check if the addresses in the header are valid. */
Matthew Qinbb7923d2015-02-09 10:56:09 +08001993 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_size) ||
Mayank Grovere559cec2017-10-17 15:12:03 +05301994 check_ddr_addr_range_bound(hdr->kernel_addr, kernel_size) ||
1995 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
1996 check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001997 {
Mayank Grovere559cec2017-10-17 15:12:03 +05301998 dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001999 return -1;
2000 }
2001
2002#ifndef DEVICE_TREE
Mayank Grovere559cec2017-10-17 15:12:03 +05302003 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
2004 check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002005 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302006 dprintf(CRITICAL, "Tags addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002007 return -1;
2008 }
2009#endif
2010
Matthew Qin49e51fa2015-02-09 10:40:45 +08002011 /* Move kernel, ramdisk and device tree to correct address */
Matthew Qinbb7923d2015-02-09 10:56:09 +08002012 memmove((void*) hdr->kernel_addr, kernel_start_addr, kernel_size);
Matthew Qin49e51fa2015-02-09 10:40:45 +08002013 memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
Shashank Mittald3e54dd2014-08-28 15:24:02 -07002014
Matthew Qin49e51fa2015-02-09 10:40:45 +08002015 #if DEVICE_TREE
Parth Dixit4097b622016-03-15 14:42:27 +05302016 if(dt_size) {
Matthew Qin49e51fa2015-02-09 10:40:45 +08002017 dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
2018 table = (struct dt_table*) dt_table_offset;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002019
Matthew Qin49e51fa2015-02-09 10:40:45 +08002020 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
2021 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
2022 return -1;
2023 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002024
P.V. Phani Kumar82916762016-03-09 09:20:19 +05302025 /* Its Error if, dt_hdr_size (table->num_entries * dt_entry size + Dev_Tree Header)
2026 goes beyound hdr->dt_size*/
Parth Dixit4097b622016-03-15 14:42:27 +05302027 if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
P.V. Phani Kumar82916762016-03-09 09:20:19 +05302028 dprintf(CRITICAL, "ERROR: Invalid Device Tree size \n");
2029 return -1;
2030 }
2031
Matthew Qin49e51fa2015-02-09 10:40:45 +08002032 /* Find index of device tree within device tree table */
2033 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
2034 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
2035 return -1;
2036 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002037
P.V. Phani Kumar3c333202016-03-09 11:54:37 +05302038 if(dt_entry.offset > (UINT_MAX - dt_entry.size)) {
2039 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2040 return -1;
2041 }
2042
2043 /* Ensure we are not overshooting dt_size with the dt_entry selected */
Parth Dixit4097b622016-03-15 14:42:27 +05302044 if ((dt_entry.offset + dt_entry.size) > dt_size) {
P.V. Phani Kumar3c333202016-03-09 11:54:37 +05302045 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2046 return -1;
2047 }
2048
Matthew Qin271927e2015-03-31 22:07:07 -04002049 if (is_gzip_package((unsigned char *)dt_table_offset + dt_entry.offset, dt_entry.size))
2050 {
2051 unsigned int compressed_size = 0;
2052 out_addr += out_len;
2053 out_avai_len -= out_len;
Matthew Qin0b15b322015-05-19 05:20:54 -04002054 dprintf(INFO, "decompressing dtb: start\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002055 rc = decompress((unsigned char *)dt_table_offset + dt_entry.offset,
2056 dt_entry.size, out_addr, out_avai_len,
2057 &compressed_size, &dtb_size);
2058 if (rc)
2059 {
Matthew Qin0b15b322015-05-19 05:20:54 -04002060 dprintf(CRITICAL, "decompressing dtb failed!!!\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002061 ASSERT(0);
2062 }
2063
Matthew Qin0b15b322015-05-19 05:20:54 -04002064 dprintf(INFO, "decompressing dtb: done\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002065 best_match_dt_addr = out_addr;
2066 } else {
2067 best_match_dt_addr = (unsigned char *)dt_table_offset + dt_entry.offset;
2068 dtb_size = dt_entry.size;
2069 }
2070
Matthew Qin49e51fa2015-02-09 10:40:45 +08002071 /* Validate and Read device device tree in the tags_addr */
Mayank Grovere559cec2017-10-17 15:12:03 +05302072 if (check_aboot_addr_range_overlap(hdr->tags_addr, dtb_size) ||
2073 check_ddr_addr_range_bound(hdr->tags_addr, dtb_size))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002074 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302075 dprintf(CRITICAL, "Device tree addresses are not valid\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002076 return -1;
2077 }
Shashank Mittal162244e2011-08-08 19:01:25 -07002078
Matthew Qin271927e2015-03-31 22:07:07 -04002079 memmove((void *)hdr->tags_addr, (char *)best_match_dt_addr, dtb_size);
Matthew Qin49e51fa2015-02-09 10:40:45 +08002080 } else {
2081 /* Validate the tags_addr */
Mayank Grovere559cec2017-10-17 15:12:03 +05302082 if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
2083 check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07002084 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302085 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07002086 return -1;
2087 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08002088 /*
2089 * If appended dev tree is found, update the atags with
2090 * memory address to the DTB appended location on RAM.
2091 * Else update with the atags address in the kernel header
Mayank Grover1ed3e8b2018-09-19 15:16:50 +05302092 *
2093 * Make sure everything from scratch address is read before next step!
2094 * In case of dtbo, this API is going to read dtbo on scratch.
Matthew Qin49e51fa2015-02-09 10:40:45 +08002095 */
2096 void *dtb;
Parth Dixit1375d9e2019-07-08 20:56:13 +05302097 image_buf = (void*)(image_addr + page_size + patched_kernel_hdr_size);
2098
Nagireddy Annem0d60bb62019-08-16 19:16:00 +05302099#ifdef OSVERSION_IN_BOOTIMAGE
Parth Dixit1375d9e2019-07-08 20:56:13 +05302100 if ( hdr->header_version == BOOT_HEADER_VERSION_TWO) {
2101
2102 image_buf = (void*)(image_addr);
2103 dtb_offset = dtb_image_offset;
2104 dtb_image_size = imagesize_actual;
2105 }
Nagireddy Annem0d60bb62019-08-16 19:16:00 +05302106#endif
Parth Dixit1375d9e2019-07-08 20:56:13 +05302107
2108 dtb = dev_tree_appended(image_buf, dtb_image_size, dtb_offset,
Ameya Thakur10a33452016-06-13 14:24:26 -07002109 (void *)hdr->tags_addr);
Matthew Qin49e51fa2015-02-09 10:40:45 +08002110 if (!dtb) {
2111 dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07002112 return -1;
2113 }
Shashank Mittalcd98d472011-08-02 14:29:24 -07002114 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08002115 #endif
Shashank Mittal23b8f422010-04-16 19:27:21 -07002116
Stanimir Varbanov69ec5462013-07-18 18:17:42 +03002117 if (boot_into_recovery && !device.is_unlocked && !device.is_tampered)
2118 target_load_ssd_keystore();
2119
Shashank Mittal23b8f422010-04-16 19:27:21 -07002120unified_boot:
Shashank Mittal23b8f422010-04-16 19:27:21 -07002121
Dima Zavin77e41f32013-03-06 16:10:43 -08002122 boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,
Dima Zavinbd3daa02013-03-26 11:06:44 -07002123 (const char *)hdr->cmdline, board_machtype(),
Shashank Mittal23b8f422010-04-16 19:27:21 -07002124 (void *)hdr->ramdisk_addr, hdr->ramdisk_size);
2125
2126 return 0;
2127}
2128
Dima Zavin214cc642009-01-26 11:16:21 -08002129int boot_linux_from_flash(void)
2130{
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302131 boot_img_hdr *hdr = (void*) buf;
Dima Zavin214cc642009-01-26 11:16:21 -08002132 struct ptentry *ptn;
2133 struct ptable *ptable;
2134 unsigned offset = 0;
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08002135
Shashank Mittalcd98d472011-08-02 14:29:24 -07002136 unsigned char *image_addr = 0;
2137 unsigned kernel_actual;
2138 unsigned ramdisk_actual;
2139 unsigned imagesize_actual;
vijay kumar8f53e362015-11-24 13:38:11 +05302140 unsigned second_actual = 0;
Shashank Mittalcd98d472011-08-02 14:29:24 -07002141
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002142#if DEVICE_TREE
Monika Singh292b3e92018-03-17 22:40:23 +05302143 struct dt_table *table = NULL;
Joel Kingaa335dc2013-06-03 16:11:08 -07002144 struct dt_entry dt_entry;
vijay kumar8f53e362015-11-24 13:38:11 +05302145 unsigned dt_table_offset;
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -08002146 uint32_t dt_actual;
Monika Singh292b3e92018-03-17 22:40:23 +05302147 uint32_t dt_hdr_size = 0;
Vivek Kumar07bd0862018-04-10 14:19:23 +05302148 uint32_t dtb_offset = 0;
vijay kumar8f53e362015-11-24 13:38:11 +05302149 unsigned int dtb_size = 0;
2150 unsigned char *best_match_dt_addr = NULL;
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002151#endif
2152
David Ng183a7422009-12-07 14:55:21 -08002153 if (target_is_emmc_boot()) {
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302154 hdr = (boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
David Ng183a7422009-12-07 14:55:21 -08002155 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
2156 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
2157 return -1;
2158 }
2159 goto continue_boot;
2160 }
2161
Dima Zavin214cc642009-01-26 11:16:21 -08002162 ptable = flash_get_ptable();
2163 if (ptable == NULL) {
2164 dprintf(CRITICAL, "ERROR: Partition table not found\n");
2165 return -1;
2166 }
2167
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08002168 if(!boot_into_recovery)
2169 {
2170 ptn = ptable_find(ptable, "boot");
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002171
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08002172 if (ptn == NULL) {
2173 dprintf(CRITICAL, "ERROR: No boot partition found\n");
2174 return -1;
2175 }
2176 }
2177 else
2178 {
2179 ptn = ptable_find(ptable, "recovery");
2180 if (ptn == NULL) {
2181 dprintf(CRITICAL, "ERROR: No recovery partition found\n");
2182 return -1;
2183 }
Dima Zavin214cc642009-01-26 11:16:21 -08002184 }
2185
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302186 /* Read boot.img header from flash */
Shashank Mittaldcc2e352009-11-19 19:11:16 -08002187 if (flash_read(ptn, offset, buf, page_size)) {
Dima Zavin214cc642009-01-26 11:16:21 -08002188 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
2189 return -1;
2190 }
Dima Zavin214cc642009-01-26 11:16:21 -08002191
2192 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07002193 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
Dima Zavin214cc642009-01-26 11:16:21 -08002194 return -1;
2195 }
2196
Shashank Mittaldcc2e352009-11-19 19:11:16 -08002197 if (hdr->page_size != page_size) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07002198 dprintf(CRITICAL, "ERROR: Invalid boot image pagesize. Device pagesize: %d, Image pagesize: %d\n",page_size,hdr->page_size);
Shashank Mittaldcc2e352009-11-19 19:11:16 -08002199 return -1;
2200 }
2201
Kishor PK9e91b592017-05-24 12:14:55 +05302202 image_addr = (unsigned char *)target_get_scratch_address();
2203 memcpy(image_addr, (void *)buf, page_size);
vijay kumar287bb542015-09-29 13:01:52 +05302204
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002205 /*
2206 * Update the kernel/ramdisk/tags address if the boot image header
2207 * has default values, these default values come from mkbootimg when
2208 * the boot image is flashed using fastboot flash:raw
2209 */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08002210 update_ker_tags_rdisk_addr(hdr, false);
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002211
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07002212 /* Get virtual addresses since the hdr saves physical addresses. */
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002213 hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
2214 hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
2215 hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
2216
2217 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
2218 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
Mayank Grover032736f2017-07-14 20:34:51 +05302219 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002220
Kishor PK9e91b592017-05-24 12:14:55 +05302221 /* ensure commandline is terminated */
2222 hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
2223
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002224 /* Check if the addresses in the header are valid. */
2225 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) ||
Mayank Grovere559cec2017-10-17 15:12:03 +05302226 check_ddr_addr_range_bound(hdr->kernel_addr, kernel_actual) ||
2227 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
2228 check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002229 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302230 dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002231 return -1;
2232 }
2233
2234#ifndef DEVICE_TREE
Kishor PKd8ddcad2017-07-27 13:53:57 +05302235 if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + page_size)) {
Mayank Grover032736f2017-07-14 20:34:51 +05302236 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields\n");
2237 return -1;
2238 }
Kishor PKd8ddcad2017-07-27 13:53:57 +05302239 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
Mayank Grover032736f2017-07-14 20:34:51 +05302240
Mayank Grovere559cec2017-10-17 15:12:03 +05302241 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
2242 check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
Vijay Kumar Pendotid3ed20e2016-09-20 00:34:46 +05302243 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302244 dprintf(CRITICAL, "Tags addresses are not valid.\n");
Vijay Kumar Pendotid3ed20e2016-09-20 00:34:46 +05302245 return -1;
2246 }
2247#else
2248
2249#ifndef OSVERSION_IN_BOOTIMAGE
2250 dt_size = hdr->dt_size;
2251#endif
Mayank Grover032736f2017-07-14 20:34:51 +05302252 dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05302253 if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + (uint64_t)dt_actual + page_size)) {
Mayank Grover032736f2017-07-14 20:34:51 +05302254 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields\n");
2255 return -1;
2256 }
2257
Kishor PKd8ddcad2017-07-27 13:53:57 +05302258 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual + dt_actual);
Mayank Grover032736f2017-07-14 20:34:51 +05302259
Mayank Grovere559cec2017-10-17 15:12:03 +05302260 if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_size) ||
2261 check_ddr_addr_range_bound(hdr->tags_addr, dt_size))
Mayank Grover032736f2017-07-14 20:34:51 +05302262 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302263 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
Mayank Grover032736f2017-07-14 20:34:51 +05302264 return -1;
2265 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002266#endif
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07002267
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302268 /* Read full boot.img from flash */
2269 dprintf(INFO, "Loading (%s) image (%d): start\n",
2270 (!boot_into_recovery ? "boot" : "recovery"),imagesize_actual);
2271 bs_set_timestamp(BS_KERNEL_LOAD_START);
2272
2273 if (UINT_MAX - page_size < imagesize_actual)
2274 {
2275 dprintf(CRITICAL,"Integer overflow detected in bootimage header fields %u %s\n", __LINE__,__func__);
2276 return -1;
2277 }
2278
2279 /*Check the availability of RAM before reading boot image + max signature length from flash*/
2280 if (target_get_max_flash_size() < (imagesize_actual + page_size))
2281 {
2282 dprintf(CRITICAL, "bootimage size is greater than DDR can hold\n");
2283 return -1;
2284 }
2285
2286 offset = page_size;
2287 /* Read image without signature and header */
2288 if (flash_read(ptn, offset, (void *)(image_addr + offset), imagesize_actual - page_size))
2289 {
2290 dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
2291 return -1;
2292 }
2293
2294 dprintf(INFO, "Loading (%s) image (%d): done\n",
2295 (!boot_into_recovery ? "boot" : "recovery"), imagesize_actual);
2296 bs_set_timestamp(BS_KERNEL_LOAD_DONE);
2297
Shashank Mittalcd98d472011-08-02 14:29:24 -07002298 /* Authenticate Kernel */
Deepa Dinamani23b60d42013-06-24 18:10:52 -07002299 if(target_use_signed_kernel() && (!device.is_unlocked))
Shashank Mittalcd98d472011-08-02 14:29:24 -07002300 {
Shashank Mittalcd98d472011-08-02 14:29:24 -07002301 offset = imagesize_actual;
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302302
Shashank Mittalcd98d472011-08-02 14:29:24 -07002303 /* Read signature */
2304 if (flash_read(ptn, offset, (void *)(image_addr + offset), page_size))
2305 {
2306 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002307 return -1;
Shashank Mittalcd98d472011-08-02 14:29:24 -07002308 }
Shashank Mittalcd98d472011-08-02 14:29:24 -07002309
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05302310 verify_signed_bootimg((uint32_t)image_addr, imagesize_actual);
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302311 }
2312 offset = page_size;
2313 if(hdr->second_size != 0) {
2314 if (UINT_MAX - offset < second_actual)
2315 {
2316 dprintf(CRITICAL, "ERROR: Integer overflow in boot image header %s\t%d\n",__func__,__LINE__);
2317 return -1;
vijay kumar8f53e362015-11-24 13:38:11 +05302318 }
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302319 offset += second_actual;
2320 /* Second image loading not implemented. */
2321 ASSERT(0);
2322 }
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302323 /* Move kernel and ramdisk to correct address */
2324 memmove((void*) hdr->kernel_addr, (char*) (image_addr + page_size), hdr->kernel_size);
2325 memmove((void*) hdr->ramdisk_addr, (char*) (image_addr + page_size + kernel_actual), hdr->ramdisk_size);
2326
2327#if DEVICE_TREE
2328 if(dt_size != 0) {
2329
2330 dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
2331
2332 table = (struct dt_table*) dt_table_offset;
2333
2334 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
2335 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
2336 return -1;
2337 }
2338
2339 /* Its Error if, dt_hdr_size (table->num_entries * dt_entry size + Dev_Tree Header)
2340 goes beyound hdr->dt_size*/
2341 if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
2342 dprintf(CRITICAL, "ERROR: Invalid Device Tree size \n");
2343 return -1;
2344 }
2345
2346 /* Find index of device tree within device tree table */
2347 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
2348 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
2349 return -1;
2350 }
2351
2352 /* Validate and Read device device tree in the "tags_add */
2353 if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size) ||
2354 check_ddr_addr_range_bound(hdr->tags_addr, dt_entry.size))
2355 {
2356 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
2357 return -1;
2358 }
2359
2360 if(dt_entry.offset > (UINT_MAX - dt_entry.size)) {
2361 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2362 return -1;
2363 }
2364
2365 /* Ensure we are not overshooting dt_size with the dt_entry selected */
2366 if ((dt_entry.offset + dt_entry.size) > dt_size) {
2367 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2368 return -1;
2369 }
2370
2371 best_match_dt_addr = (unsigned char *)table + dt_entry.offset;
2372 dtb_size = dt_entry.size;
2373 memmove((void *)hdr->tags_addr, (char *)best_match_dt_addr, dtb_size);
Vivek Kumar07bd0862018-04-10 14:19:23 +05302374
2375 } else {
2376 /* Validate the tags_addr */
2377 if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
2378 check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
2379 {
2380 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
2381 return -1;
2382 }
2383 /*
2384 * If appended dev tree is found, update the atags with
2385 * memory address to the DTB appended location on RAM.
2386 * Else update with the atags address in the kernel header
Mayank Grover1ed3e8b2018-09-19 15:16:50 +05302387 *
2388 * Make sure everything from scratch address is read before next step!
2389 * In case of dtbo, this API is going to read dtbo on scratch.
Vivek Kumar07bd0862018-04-10 14:19:23 +05302390 */
2391 void *dtb = NULL;
2392 dtb = dev_tree_appended((void*)(image_addr + page_size ),hdr->kernel_size, dtb_offset, (void *)hdr->tags_addr);
2393 if (!dtb) {
2394 dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
2395 return -1;
2396 }
2397 }
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302398#endif
2399 if(target_use_signed_kernel() && (!device.is_unlocked))
2400 {
Shashank Mittal162244e2011-08-08 19:01:25 -07002401 /* Make sure everything from scratch address is read before next step!*/
Shashank Mittala0032282011-08-26 14:50:11 -07002402 if(device.is_tampered)
Shashank Mittal162244e2011-08-08 19:01:25 -07002403 {
2404 write_device_info_flash(&device);
2405 }
Channagoud Kadabi5c86fe32012-02-16 10:58:48 +05302406#if USE_PCOM_SECBOOT
2407 set_tamper_flag(device.is_tampered);
2408#endif
Shashank Mittalcd98d472011-08-02 14:29:24 -07002409 }
David Ng183a7422009-12-07 14:55:21 -08002410continue_boot:
Dima Zavin214cc642009-01-26 11:16:21 -08002411
Dima Zavin214cc642009-01-26 11:16:21 -08002412 /* TODO: create/pass atags to kernel */
2413
Ajay Dudanie28a6072011-07-01 13:59:46 -07002414 boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,
Dima Zavinbd3daa02013-03-26 11:06:44 -07002415 (const char *)hdr->cmdline, board_machtype(),
Dima Zavin214cc642009-01-26 11:16:21 -08002416 (void *)hdr->ramdisk_addr, hdr->ramdisk_size);
2417
2418 return 0;
2419}
Brian Swetland9c4c0752009-01-25 16:23:50 -08002420
Shashank Mittal162244e2011-08-08 19:01:25 -07002421void write_device_info_mmc(device_info *dev)
2422{
Shashank Mittal162244e2011-08-08 19:01:25 -07002423 unsigned long long ptn = 0;
2424 unsigned long long size;
2425 int index = INVALID_PTN;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08002426 uint8_t lun = 0;
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002427 uint32_t ret = 0;
Mayank Groverddd348d2018-01-23 14:07:09 +05302428 uint32_t device_info_sz = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07002429
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002430 if (devinfo_present)
2431 index = partition_get_index("devinfo");
2432 else
2433 index = partition_get_index("aboot");
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07002434
Shashank Mittal162244e2011-08-08 19:01:25 -07002435 ptn = partition_get_offset(index);
2436 if(ptn == 0)
2437 {
2438 return;
2439 }
2440
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08002441 lun = partition_get_lun(index);
2442 mmc_set_lun(lun);
2443
Shashank Mittal162244e2011-08-08 19:01:25 -07002444 size = partition_get_size(index);
2445
Mayank Groverddd348d2018-01-23 14:07:09 +05302446 device_info_sz = ROUND_TO_PAGE(sizeof(struct device_info),
2447 mmc_blocksize_mask);
2448 if (device_info_sz == UINT_MAX)
2449 {
2450 dprintf(CRITICAL, "ERROR: Incorrect blocksize of card\n");
2451 return;
2452 }
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07002453
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002454 if (devinfo_present)
Mayank Groverddd348d2018-01-23 14:07:09 +05302455 ret = mmc_write(ptn, device_info_sz, (void *)info_buf);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002456 else
Mayank Groverddd348d2018-01-23 14:07:09 +05302457 ret = mmc_write((ptn + size - device_info_sz), device_info_sz, (void *)info_buf);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002458 if (ret)
Shashank Mittal162244e2011-08-08 19:01:25 -07002459 {
2460 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
Sridhar Parasurame1a97922015-07-27 15:31:22 -07002461 ASSERT(0);
Shashank Mittal162244e2011-08-08 19:01:25 -07002462 }
2463}
2464
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002465void read_device_info_mmc(struct device_info *info)
Shashank Mittal162244e2011-08-08 19:01:25 -07002466{
Shashank Mittal162244e2011-08-08 19:01:25 -07002467 unsigned long long ptn = 0;
2468 unsigned long long size;
2469 int index = INVALID_PTN;
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002470 uint32_t ret = 0;
Mayank Groverddd348d2018-01-23 14:07:09 +05302471 uint32_t device_info_sz = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07002472
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002473 if ((index = partition_get_index("devinfo")) < 0)
2474 {
2475 devinfo_present = false;
2476 index = partition_get_index("aboot");
2477 }
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07002478
Shashank Mittal162244e2011-08-08 19:01:25 -07002479 ptn = partition_get_offset(index);
2480 if(ptn == 0)
2481 {
2482 return;
2483 }
2484
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07002485 mmc_set_lun(partition_get_lun(index));
2486
Shashank Mittal162244e2011-08-08 19:01:25 -07002487 size = partition_get_size(index);
2488
Mayank Groverddd348d2018-01-23 14:07:09 +05302489 device_info_sz = ROUND_TO_PAGE(sizeof(struct device_info),
2490 mmc_blocksize_mask);
2491 if (device_info_sz == UINT_MAX)
2492 {
2493 dprintf(CRITICAL, "ERROR: Incorrect blocksize of card\n");
2494 return;
2495 }
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07002496
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002497 if (devinfo_present)
Mayank Groverddd348d2018-01-23 14:07:09 +05302498 ret = mmc_read(ptn, (void *)info_buf, device_info_sz);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002499 else
Mayank Groverddd348d2018-01-23 14:07:09 +05302500 ret = mmc_read((ptn + size - device_info_sz), (void *)info_buf, device_info_sz);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002501 if (ret)
Shashank Mittal162244e2011-08-08 19:01:25 -07002502 {
2503 dprintf(CRITICAL, "ERROR: Cannot read device info\n");
Sridhar Parasurame1a97922015-07-27 15:31:22 -07002504 ASSERT(0);
Shashank Mittal162244e2011-08-08 19:01:25 -07002505 }
Shashank Mittal162244e2011-08-08 19:01:25 -07002506}
2507
2508void write_device_info_flash(device_info *dev)
2509{
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002510 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
Shashank Mittal162244e2011-08-08 19:01:25 -07002511 struct ptentry *ptn;
2512 struct ptable *ptable;
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002513 if(info == NULL)
2514 {
2515 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
2516 ASSERT(0);
2517 }
2518 info_buf = info;
Shashank Mittal162244e2011-08-08 19:01:25 -07002519 ptable = flash_get_ptable();
2520 if (ptable == NULL)
2521 {
2522 dprintf(CRITICAL, "ERROR: Partition table not found\n");
2523 return;
2524 }
2525
2526 ptn = ptable_find(ptable, "devinfo");
2527 if (ptn == NULL)
2528 {
Smita Ghosh670c8b82015-05-07 09:30:03 -07002529 dprintf(CRITICAL, "ERROR: No devinfo partition found\n");
Shashank Mittal162244e2011-08-08 19:01:25 -07002530 return;
2531 }
2532
Mayank Groverdedbc892017-10-24 13:41:34 +05302533 memset(info, 0, BOOT_IMG_MAX_PAGE_SIZE);
Shashank Mittal162244e2011-08-08 19:01:25 -07002534 memcpy(info, dev, sizeof(device_info));
2535
2536 if (flash_write(ptn, 0, (void *)info_buf, page_size))
2537 {
2538 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
2539 return;
2540 }
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002541 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07002542}
2543
vijay kumarc65876c2015-04-24 13:29:16 +05302544static int read_allow_oem_unlock(device_info *dev)
2545{
vijay kumarc65876c2015-04-24 13:29:16 +05302546 unsigned offset;
2547 int index;
2548 unsigned long long ptn;
2549 unsigned long long ptn_size;
2550 unsigned blocksize = mmc_get_device_blocksize();
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002551 STACKBUF_DMA_ALIGN(buf, blocksize);
vijay kumarc65876c2015-04-24 13:29:16 +05302552
vijay kumarca2e6812015-07-08 20:28:25 +05302553 index = partition_get_index(frp_ptns[0]);
vijay kumarc65876c2015-04-24 13:29:16 +05302554 if (index == INVALID_PTN)
2555 {
vijay kumarca2e6812015-07-08 20:28:25 +05302556 index = partition_get_index(frp_ptns[1]);
2557 if (index == INVALID_PTN)
2558 {
2559 dprintf(CRITICAL, "Neither '%s' nor '%s' partition found\n", frp_ptns[0],frp_ptns[1]);
2560 return -1;
2561 }
vijay kumarc65876c2015-04-24 13:29:16 +05302562 }
2563
2564 ptn = partition_get_offset(index);
2565 ptn_size = partition_get_size(index);
2566 offset = ptn_size - blocksize;
2567
Mayank Grover48860402016-11-29 12:34:53 +05302568 /* Set Lun for partition */
2569 mmc_set_lun(partition_get_lun(index));
2570
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002571 if (mmc_read(ptn + offset, (void *)buf, blocksize))
vijay kumarc65876c2015-04-24 13:29:16 +05302572 {
2573 dprintf(CRITICAL, "Reading MMC failed\n");
2574 return -1;
2575 }
2576
2577 /*is_allow_unlock is a bool value stored at the LSB of last byte*/
2578 is_allow_unlock = buf[blocksize-1] & 0x01;
2579 return 0;
2580}
2581
2582static int write_allow_oem_unlock(bool allow_unlock)
2583{
vijay kumarc65876c2015-04-24 13:29:16 +05302584 unsigned offset;
vijay kumarc65876c2015-04-24 13:29:16 +05302585 int index;
2586 unsigned long long ptn;
2587 unsigned long long ptn_size;
2588 unsigned blocksize = mmc_get_device_blocksize();
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002589 STACKBUF_DMA_ALIGN(buf, blocksize);
vijay kumarc65876c2015-04-24 13:29:16 +05302590
vijay kumarca2e6812015-07-08 20:28:25 +05302591 index = partition_get_index(frp_ptns[0]);
vijay kumarc65876c2015-04-24 13:29:16 +05302592 if (index == INVALID_PTN)
2593 {
vijay kumarca2e6812015-07-08 20:28:25 +05302594 index = partition_get_index(frp_ptns[1]);
2595 if (index == INVALID_PTN)
2596 {
2597 dprintf(CRITICAL, "Neither '%s' nor '%s' partition found\n", frp_ptns[0],frp_ptns[1]);
2598 return -1;
2599 }
vijay kumarc65876c2015-04-24 13:29:16 +05302600 }
2601
2602 ptn = partition_get_offset(index);
2603 ptn_size = partition_get_size(index);
2604 offset = ptn_size - blocksize;
Mayank Grover48860402016-11-29 12:34:53 +05302605 mmc_set_lun(partition_get_lun(index));
vijay kumarc65876c2015-04-24 13:29:16 +05302606
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002607 if (mmc_read(ptn + offset, (void *)buf, blocksize))
vijay kumarc65876c2015-04-24 13:29:16 +05302608 {
2609 dprintf(CRITICAL, "Reading MMC failed\n");
2610 return -1;
2611 }
2612
2613 /*is_allow_unlock is a bool value stored at the LSB of last byte*/
2614 buf[blocksize-1] = allow_unlock;
2615 if (mmc_write(ptn + offset, blocksize, buf))
2616 {
2617 dprintf(CRITICAL, "Writing MMC failed\n");
2618 return -1;
2619 }
2620
2621 return 0;
2622}
2623
Shashank Mittal162244e2011-08-08 19:01:25 -07002624void read_device_info_flash(device_info *dev)
2625{
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002626 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
Shashank Mittal162244e2011-08-08 19:01:25 -07002627 struct ptentry *ptn;
2628 struct ptable *ptable;
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002629 if(info == NULL)
2630 {
2631 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
2632 ASSERT(0);
2633 }
2634 info_buf = info;
Shashank Mittal162244e2011-08-08 19:01:25 -07002635 ptable = flash_get_ptable();
2636 if (ptable == NULL)
2637 {
2638 dprintf(CRITICAL, "ERROR: Partition table not found\n");
2639 return;
2640 }
2641
2642 ptn = ptable_find(ptable, "devinfo");
2643 if (ptn == NULL)
2644 {
Smita Ghosh670c8b82015-05-07 09:30:03 -07002645 dprintf(CRITICAL, "ERROR: No devinfo partition found\n");
Shashank Mittal162244e2011-08-08 19:01:25 -07002646 return;
2647 }
2648
2649 if (flash_read(ptn, 0, (void *)info_buf, page_size))
2650 {
2651 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
2652 return;
2653 }
2654
2655 if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
2656 {
Shashank Mittal162244e2011-08-08 19:01:25 -07002657 memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
2658 info->is_unlocked = 0;
Shashank Mittala0032282011-08-26 14:50:11 -07002659 info->is_tampered = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07002660 write_device_info_flash(info);
2661 }
2662 memcpy(dev, info, sizeof(device_info));
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002663 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07002664}
2665
2666void write_device_info(device_info *dev)
2667{
2668 if(target_is_emmc_boot())
2669 {
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002670 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
2671 if(info == NULL)
2672 {
2673 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
2674 ASSERT(0);
2675 }
2676 info_buf = info;
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002677 memcpy(info, dev, sizeof(struct device_info));
2678
2679#if USE_RPMB_FOR_DEVINFO
Mayank Grover912eaa62017-10-26 12:08:53 +05302680 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05302681 is_secure_boot_enable()) {
2682 if((write_device_info_rpmb((void*) info, PAGE_SIZE)) < 0)
2683 ASSERT(0);
Sridhar Parasurame1a97922015-07-27 15:31:22 -07002684 }
Channagoud Kadabic80cb492015-04-28 16:08:28 -07002685 else
2686 write_device_info_mmc(info);
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002687#else
2688 write_device_info_mmc(info);
2689#endif
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002690 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07002691 }
2692 else
2693 {
2694 write_device_info_flash(dev);
2695 }
2696}
2697
Monika Singh94316462018-03-15 18:39:01 +05302698int read_rollback_index(uint32_t loc, uint64_t *roll_back_index)
2699{
2700 if (!devinfo_present) {
2701 dprintf(CRITICAL, "DeviceInfo not initalized \n");
2702 return -EINVAL;
2703 }
2704 if (loc >= ARRAY_SIZE(device.rollback_index)) {
2705 dprintf(CRITICAL, "%s() Loc out of range index: %d, array len: %d\n",
2706 __func__, loc, ARRAY_SIZE(device.rollback_index));
2707 ASSERT(0);
2708 }
2709
2710 *roll_back_index = device.rollback_index[loc];
2711 return 0;
2712}
2713
2714int write_rollback_index(uint32_t loc, uint64_t roll_back_index)
2715{
2716 if (!devinfo_present) {
2717 dprintf(CRITICAL, "DeviceInfo not initalized \n");
2718 return -EINVAL;
2719 }
2720 if (loc >= ARRAY_SIZE(device.rollback_index)) {
2721 dprintf(CRITICAL, "%s() Loc out of range index: %d, array len: %d\n",
2722 __func__, loc, ARRAY_SIZE(device.rollback_index));
2723 ASSERT(0);
2724 }
2725
2726 device.rollback_index[loc] = roll_back_index;
2727 write_device_info(&device);
2728 return 0;
2729}
2730
Monika Singhb0fad822018-03-15 18:50:55 +05302731int store_userkey(uint8_t *user_key, uint32_t user_key_size)
2732{
2733 if (!devinfo_present) {
2734 dprintf(CRITICAL, "DeviceInfo not initalized \n");
2735 return -EINVAL;
2736 }
2737
2738 if (user_key_size > ARRAY_SIZE(device.user_public_key)) {
2739 dprintf(CRITICAL, "StoreUserKey, UserKeySize too large!\n");
2740 return -ENODEV;
2741 }
2742
2743 memcpy(device.user_public_key, user_key, user_key_size);
2744 device.user_public_key_length = user_key_size;
2745 write_device_info(&device);
2746 return 0;
2747}
2748
2749int erase_userkey()
2750{
2751 if (!devinfo_present) {
2752 dprintf(CRITICAL, "DeviceInfo not initalized \n");
2753 return -EINVAL;
2754 }
2755 memset(device.user_public_key, 0, ARRAY_SIZE(device.user_public_key));
2756 device.user_public_key_length = 0;
2757 write_device_info(&device);
2758 return 0;
2759}
2760
2761int get_userkey(uint8_t **user_key, uint32_t *user_key_size)
2762{
2763 if (!devinfo_present) {
2764 dprintf(CRITICAL, "DeviceInfo not initalized \n");
2765 return -EINVAL;
2766 }
2767 *user_key = device.user_public_key;
2768 *user_key_size = device.user_public_key_length;
2769 return 0;
2770}
2771
Shashank Mittal162244e2011-08-08 19:01:25 -07002772void read_device_info(device_info *dev)
2773{
2774 if(target_is_emmc_boot())
2775 {
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002776 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
2777 if(info == NULL)
2778 {
2779 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
2780 ASSERT(0);
2781 }
2782 info_buf = info;
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002783
2784#if USE_RPMB_FOR_DEVINFO
Mayank Grover912eaa62017-10-26 12:08:53 +05302785 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05302786 is_secure_boot_enable()) {
2787 if((read_device_info_rpmb((void*) info, PAGE_SIZE)) < 0)
2788 ASSERT(0);
Sridhar Parasurame1a97922015-07-27 15:31:22 -07002789 }
Channagoud Kadabic80cb492015-04-28 16:08:28 -07002790 else
2791 read_device_info_mmc(info);
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002792#else
2793 read_device_info_mmc(info);
2794#endif
2795
2796 if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
2797 {
2798 memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
lijuang511a2b52015-08-14 20:50:51 +08002799 if (is_secure_boot_enable()) {
Channagoud Kadabi05f78ba2015-07-06 11:58:14 -07002800 info->is_unlocked = 0;
Monika Singh292b3e92018-03-17 22:40:23 +05302801#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05302802 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05302803 info->is_unlock_critical = 0;
Parth Dixitddbc7352015-10-18 03:13:31 +05302804#endif
lijuang511a2b52015-08-14 20:50:51 +08002805 } else {
Channagoud Kadabi2fda4092015-07-07 13:34:11 -07002806 info->is_unlocked = 1;
Monika Singh292b3e92018-03-17 22:40:23 +05302807#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05302808 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05302809 info->is_unlock_critical = 1;
Parth Dixitddbc7352015-10-18 03:13:31 +05302810#endif
lijuang511a2b52015-08-14 20:50:51 +08002811 }
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002812 info->is_tampered = 0;
2813 info->charger_screen_enabled = 0;
Monika Singh292b3e92018-03-17 22:40:23 +05302814#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05302815 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05302816 info->verity_mode = 1; //enforcing by default
Parth Dixitddbc7352015-10-18 03:13:31 +05302817#endif
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002818 write_device_info(info);
2819 }
2820 memcpy(dev, info, sizeof(device_info));
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002821 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07002822 }
2823 else
2824 {
2825 read_device_info_flash(dev);
2826 }
2827}
2828
2829void reset_device_info()
2830{
2831 dprintf(ALWAYS, "reset_device_info called.");
Shashank Mittala0032282011-08-26 14:50:11 -07002832 device.is_tampered = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07002833 write_device_info(&device);
2834}
2835
2836void set_device_root()
2837{
2838 dprintf(ALWAYS, "set_device_root called.");
Shashank Mittala0032282011-08-26 14:50:11 -07002839 device.is_tampered = 1;
Shashank Mittal162244e2011-08-08 19:01:25 -07002840 write_device_info(&device);
2841}
2842
lijuang4ece1e72015-08-14 21:02:36 +08002843/* set device unlock value
2844 * Must check FRP before call this function
2845 * Need to wipe data when unlock status changed
2846 * type 0: oem unlock
2847 * type 1: unlock critical
2848 * status 0: unlock as false
2849 * status 1: lock as true
2850 */
2851void set_device_unlock_value(int type, bool status)
lijuang21f12f52015-08-22 16:22:19 +08002852{
lijuang4ece1e72015-08-14 21:02:36 +08002853 if (type == UNLOCK)
2854 device.is_unlocked = status;
Monika Singh292b3e92018-03-17 22:40:23 +05302855#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05302856 else if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05302857 type == UNLOCK_CRITICAL)
2858 device.is_unlock_critical = status;
Parth Dixitddbc7352015-10-18 03:13:31 +05302859#endif
lijuang4ece1e72015-08-14 21:02:36 +08002860 write_device_info(&device);
2861}
2862
2863static void set_device_unlock(int type, bool status)
2864{
2865 int is_unlocked = -1;
2866 char response[MAX_RSP_SIZE];
2867
2868 /* check device unlock status if it is as expected */
2869 if (type == UNLOCK)
2870 is_unlocked = device.is_unlocked;
Monika Singh292b3e92018-03-17 22:40:23 +05302871#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05302872 if(VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05302873 type == UNLOCK_CRITICAL)
2874 {
2875 is_unlocked = device.is_unlock_critical;
2876 }
Parth Dixitddbc7352015-10-18 03:13:31 +05302877#endif
lijuang4ece1e72015-08-14 21:02:36 +08002878 if (is_unlocked == status) {
2879 snprintf(response, sizeof(response), "\tDevice already : %s", (status ? "unlocked!" : "locked!"));
2880 fastboot_info(response);
2881 fastboot_okay("");
2882 return;
2883 }
2884
2885 /* status is true, it means to unlock device */
lijuang07c5d6e2018-04-23 18:32:13 +08002886 if (status && !is_allow_unlock) {
2887 fastboot_fail("oem unlock is not allowed");
2888 return;
2889 }
lijuang21f12f52015-08-22 16:22:19 +08002890
lijuang4ece1e72015-08-14 21:02:36 +08002891#if FBCON_DISPLAY_MSG
lijuang07c5d6e2018-04-23 18:32:13 +08002892 display_unlock_menu(type, status);
2893 fastboot_okay("");
2894 return;
lijuang4ece1e72015-08-14 21:02:36 +08002895#else
lijuang07c5d6e2018-04-23 18:32:13 +08002896 if (status && type == UNLOCK) {
2897 fastboot_fail("Need wipe userdata. Do 'fastboot oem unlock-go'");
2898 return;
lijuang21f12f52015-08-22 16:22:19 +08002899 }
lijuang07c5d6e2018-04-23 18:32:13 +08002900#endif
lijuang4ece1e72015-08-14 21:02:36 +08002901
2902 set_device_unlock_value(type, status);
2903
2904 /* wipe data */
2905 struct recovery_message msg;
Kishor PK60a68212017-05-08 16:55:57 +05302906 memset(&msg, 0, sizeof(msg));
lijuang4ece1e72015-08-14 21:02:36 +08002907 snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
2908 write_misc(0, &msg, sizeof(msg));
2909
2910 fastboot_okay("");
2911 reboot_device(RECOVERY_MODE);
lijuang21f12f52015-08-22 16:22:19 +08002912}
2913
lijuang511a2b52015-08-14 20:50:51 +08002914static bool critical_flash_allowed(const char * entry)
2915{
2916 uint32_t i = 0;
2917 if (entry == NULL)
2918 return false;
2919
2920 for (i = 0; i < ARRAY_SIZE(critical_flash_allowed_ptn); i++) {
2921 if(!strcmp(entry, critical_flash_allowed_ptn[i]))
2922 return true;
2923 }
2924 return false;
Matthew Qin271927e2015-03-31 22:07:07 -04002925}
2926
2927#if DEVICE_TREE
Amol Jadicb524072012-08-09 16:40:18 -07002928int copy_dtb(uint8_t *boot_image_start, unsigned int scratch_offset)
2929{
2930 uint32 dt_image_offset = 0;
Amol Jadicb524072012-08-09 16:40:18 -07002931 uint32_t n;
Monika Singh292b3e92018-03-17 22:40:23 +05302932 struct dt_table *table = NULL;
Amol Jadicb524072012-08-09 16:40:18 -07002933 struct dt_entry dt_entry;
Monika Singh292b3e92018-03-17 22:40:23 +05302934 uint32_t dt_hdr_size = 0;
Amol Jadicb524072012-08-09 16:40:18 -07002935 unsigned int compressed_size = 0;
2936 unsigned int dtb_size = 0;
2937 unsigned int out_avai_len = 0;
2938 unsigned char *out_addr = NULL;
2939 unsigned char *best_match_dt_addr = NULL;
2940 int rc;
2941
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302942 boot_img_hdr *hdr = (boot_img_hdr *) (boot_image_start);
Amol Jadicb524072012-08-09 16:40:18 -07002943
Parth Dixit4097b622016-03-15 14:42:27 +05302944#ifndef OSVERSION_IN_BOOTIMAGE
2945 dt_size = hdr->dt_size;
2946#endif
2947
2948 if(dt_size != 0) {
Amol Jadicb524072012-08-09 16:40:18 -07002949 /* add kernel offset */
2950 dt_image_offset += page_size;
2951 n = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
2952 dt_image_offset += n;
2953
2954 /* add ramdisk offset */
2955 n = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
2956 dt_image_offset += n;
2957
2958 /* add second offset */
2959 if(hdr->second_size != 0) {
2960 n = ROUND_TO_PAGE(hdr->second_size, page_mask);
2961 dt_image_offset += n;
2962 }
2963
2964 /* offset now point to start of dt.img */
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002965 table = (struct dt_table*)(boot_image_start + dt_image_offset);
Amol Jadicb524072012-08-09 16:40:18 -07002966
Deepa Dinamani19648b42013-09-05 17:05:55 -07002967 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
Amol Jadicb524072012-08-09 16:40:18 -07002968 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
2969 return -1;
2970 }
P.V. Phani Kumar82916762016-03-09 09:20:19 +05302971
2972 /* Its Error if, dt_hdr_size (table->num_entries * dt_entry size + Dev_Tree Header)
2973 goes beyound hdr->dt_size*/
Parth Dixit4097b622016-03-15 14:42:27 +05302974 if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
P.V. Phani Kumar82916762016-03-09 09:20:19 +05302975 dprintf(CRITICAL, "ERROR: Invalid Device Tree size \n");
2976 return -1;
2977 }
2978
Joel Kingaa335dc2013-06-03 16:11:08 -07002979 /* Find index of device tree within device tree table */
2980 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
Amol Jadicb524072012-08-09 16:40:18 -07002981 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
2982 return -1;
2983 }
2984
Matthew Qin271927e2015-03-31 22:07:07 -04002985 best_match_dt_addr = (unsigned char *)boot_image_start + dt_image_offset + dt_entry.offset;
2986 if (is_gzip_package(best_match_dt_addr, dt_entry.size))
2987 {
2988 out_addr = (unsigned char *)target_get_scratch_address() + scratch_offset;
2989 out_avai_len = target_get_max_flash_size() - scratch_offset;
Matthew Qin0b15b322015-05-19 05:20:54 -04002990 dprintf(INFO, "decompressing dtb: start\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002991 rc = decompress(best_match_dt_addr,
2992 dt_entry.size, out_addr, out_avai_len,
2993 &compressed_size, &dtb_size);
2994 if (rc)
2995 {
Matthew Qin0b15b322015-05-19 05:20:54 -04002996 dprintf(CRITICAL, "decompressing dtb failed!!!\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002997 ASSERT(0);
2998 }
2999
Matthew Qin0b15b322015-05-19 05:20:54 -04003000 dprintf(INFO, "decompressing dtb: done\n");
Matthew Qin271927e2015-03-31 22:07:07 -04003001 best_match_dt_addr = out_addr;
3002 } else {
3003 dtb_size = dt_entry.size;
3004 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003005 /* Validate and Read device device tree in the "tags_add */
Mayank Grovere559cec2017-10-17 15:12:03 +05303006 if (check_aboot_addr_range_overlap(hdr->tags_addr, dtb_size) ||
3007 check_ddr_addr_range_bound(hdr->tags_addr, dtb_size))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003008 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303009 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003010 return -1;
3011 }
3012
Amol Jadicb524072012-08-09 16:40:18 -07003013 /* Read device device tree in the "tags_add */
Matthew Qin271927e2015-03-31 22:07:07 -04003014 memmove((void*) hdr->tags_addr, (void *)best_match_dt_addr, dtb_size);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003015 } else
3016 return -1;
Amol Jadicb524072012-08-09 16:40:18 -07003017
3018 /* Everything looks fine. Return success. */
3019 return 0;
3020}
3021#endif
3022
Brian Swetland9c4c0752009-01-25 16:23:50 -08003023void cmd_boot(const char *arg, void *data, unsigned sz)
3024{
3025 unsigned kernel_actual;
3026 unsigned ramdisk_actual;
Kishor PKd8ddcad2017-07-27 13:53:57 +05303027 unsigned second_actual;
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003028 uint32_t image_actual;
3029 uint32_t dt_actual = 0;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05303030 boot_img_hdr *hdr = NULL;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003031 struct kernel64_hdr *kptr = NULL;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003032 char *ptr = ((char*) data);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003033 int ret = 0;
3034 uint8_t dtb_copied = 0;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003035 unsigned int out_len = 0;
3036 unsigned int out_avai_len = 0;
3037 unsigned char *out_addr = NULL;
3038 uint32_t dtb_offset = 0;
3039 unsigned char *kernel_start_addr = NULL;
3040 unsigned int kernel_size = 0;
Matthew Qin271927e2015-03-31 22:07:07 -04003041 unsigned int scratch_offset = 0;
Saranya Chidurab4933332018-10-15 17:30:06 +05303042#if VERIFIED_BOOT_2
3043 void *dtbo_image_buf = NULL;
3044 uint32_t dtbo_image_sz = 0;
3045 void *vbmeta_image_buf = NULL;
3046 uint32_t vbmeta_image_sz = 0;
3047#endif
Monika Singh292b3e92018-03-17 22:40:23 +05303048#if !VERIFIED_BOOT_2
3049 uint32_t sig_actual = 0;
3050 uint32_t sig_size = 0;
3051#ifdef MDTP_SUPPORT
3052 static bool is_mdtp_activated = 0;
3053#endif /* MDTP_SUPPORT */
3054#endif
Matthew Qinbb7923d2015-02-09 10:56:09 +08003055
lijuang2008ff22016-03-07 17:56:27 +08003056#if FBCON_DISPLAY_MSG
3057 /* Exit keys' detection thread firstly */
3058 exit_menu_keys_detection();
3059#endif
3060
Monika Singh292b3e92018-03-17 22:40:23 +05303061#if VERIFIED_BOOT || VERIFIED_BOOT_2
Channagoud Kadabi6d5375e2015-06-23 17:15:42 -07003062 if(target_build_variant_user() && !device.is_unlocked)
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003063 {
3064 fastboot_fail("unlock device to use this command");
lijuang2008ff22016-03-07 17:56:27 +08003065 goto boot_failed;
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003066 }
3067#endif
3068
Brian Swetland9c4c0752009-01-25 16:23:50 -08003069 if (sz < sizeof(hdr)) {
3070 fastboot_fail("invalid bootimage header");
lijuang2008ff22016-03-07 17:56:27 +08003071 goto boot_failed;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003072 }
3073
Mayank Grovere1ab96c2018-09-04 20:31:31 +05303074 hdr = (boot_img_hdr *)data;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003075
3076 /* ensure commandline is terminated */
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003077 hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003078
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003079 if(target_is_emmc_boot() && hdr->page_size) {
3080 page_size = hdr->page_size;
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -07003081 page_mask = page_size - 1;
3082 }
3083
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003084 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
3085 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05303086 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003087#if DEVICE_TREE
Parth Dixit4097b622016-03-15 14:42:27 +05303088#ifndef OSVERSION_IN_BOOTIMAGE
3089 dt_size = hdr->dt_size;
3090#endif
3091 dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003092#endif
3093
3094 image_actual = ADD_OF(page_size, kernel_actual);
3095 image_actual = ADD_OF(image_actual, ramdisk_actual);
Kishor PKd8ddcad2017-07-27 13:53:57 +05303096 image_actual = ADD_OF(image_actual, second_actual);
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003097 image_actual = ADD_OF(image_actual, dt_actual);
3098
Kishor PK5134b332017-05-09 17:50:08 +05303099 /* Checking to prevent oob access in read_der_message_length */
3100 if (image_actual > sz) {
3101 fastboot_fail("bootimage header fields are invalid");
3102 goto boot_failed;
3103 }
Saranya Chidurab4933332018-10-15 17:30:06 +05303104
Monika Singh292b3e92018-03-17 22:40:23 +05303105#if VERIFIED_BOOT_2
Mayank Grover1ceaee22019-04-01 17:54:32 +05303106 /* Pass size of boot partition, as imgsize, to avoid
3107 read fewer bytes error */
3108 image_actual = partition_get_size(partition_get_index("boot"));
Saranya Chidurab4933332018-10-15 17:30:06 +05303109
3110 /* load and validate dtbo partition */
3111 load_validate_dtbo_image(&dtbo_image_buf, &dtbo_image_sz);
3112
3113 /* load vbmeta partition */
3114 load_vbmeta_image(&vbmeta_image_buf, &vbmeta_image_sz);
3115
Monika Singh292b3e92018-03-17 22:40:23 +05303116 memset(&info, 0, sizeof(bootinfo));
Saranya Chidurab4933332018-10-15 17:30:06 +05303117
3118 info.images[IMG_BOOT].image_buffer = SUB_SALT_BUFF_OFFSET(data);
3119 info.images[IMG_BOOT].imgsize = image_actual;
3120 info.images[IMG_BOOT].name = "boot";
3121 ++info.num_loaded_images;
3122
3123 /* Pass loaded dtbo image */
3124 if (dtbo_image_buf != NULL) {
3125 info.images[IMG_DTBO].image_buffer = SUB_SALT_BUFF_OFFSET(dtbo_image_buf);
3126 info.images[IMG_DTBO].imgsize = dtbo_image_sz;
3127 info.images[IMG_DTBO].name = "dtbo";
3128 ++info.num_loaded_images;
3129 }
3130
3131 /* Pass loaded vbmeta image */
3132 if (vbmeta_image_buf != NULL) {
3133 info.images[IMG_VBMETA].image_buffer = vbmeta_image_buf;
3134 info.images[IMG_VBMETA].imgsize = vbmeta_image_sz;
3135 info.images[IMG_VBMETA].name = "vbmeta";
3136 ++info.num_loaded_images;
3137 }
3138
Monika Singh292b3e92018-03-17 22:40:23 +05303139 info.multi_slot_boot = partition_multislot_is_supported();
3140 if (load_image_and_auth(&info))
3141 goto boot_failed;
3142 vbcmdline = info.vbcmdline;
Saranya Chidurab4933332018-10-15 17:30:06 +05303143
3144 /* Free the buffer allocated to vbmeta post verification */
3145 if (vbmeta_image_buf != NULL) {
3146 free(vbmeta_image_buf);
3147 --info.num_loaded_images;
3148 }
Monika Singh292b3e92018-03-17 22:40:23 +05303149#else
Kishor PK5134b332017-05-09 17:50:08 +05303150 sig_size = sz - image_actual;
3151
P.V. Phani Kumareecfd822016-03-09 20:09:03 +05303152 if (target_use_signed_kernel() && (!device.is_unlocked)) {
Monika Singh292b3e92018-03-17 22:40:23 +05303153 unsigned chk;
P.V. Phani Kumareecfd822016-03-09 20:09:03 +05303154 /* Calculate the signature length from boot image */
3155 sig_actual = read_der_message_length(
Kishor PK5134b332017-05-09 17:50:08 +05303156 (unsigned char*)(data + image_actual), sig_size);
Monika Singh292b3e92018-03-17 22:40:23 +05303157 chk = ADD_OF(image_actual, sig_actual);
Channagoud Kadabi3d839012014-06-26 14:26:39 -07003158
Monika Singh292b3e92018-03-17 22:40:23 +05303159 if (chk > sz) {
Kishor PK5134b332017-05-09 17:50:08 +05303160 fastboot_fail("bootimage header fields are invalid");
3161 goto boot_failed;
3162 }
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003163 }
3164
Sridhar Parasuram361e4cd2015-09-24 11:19:19 -07003165 // Initialize boot state before trying to verify boot.img
3166#if VERIFIED_BOOT
Channagoud Kadabi699466e2015-11-03 12:37:42 -08003167 boot_verifier_init();
Mayank Groverb337e932017-01-18 20:00:40 +05303168#endif
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -07003169 /* Handle overflow if the input image size is greater than
3170 * boot image buffer can hold
3171 */
Monika Singh292b3e92018-03-17 22:40:23 +05303172 if ((target_get_max_flash_size() - page_size) < image_actual)
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -07003173 {
3174 fastboot_fail("booimage: size is greater than boot image buffer can hold");
lijuang2008ff22016-03-07 17:56:27 +08003175 goto boot_failed;
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -07003176 }
Sridhar Parasuram361e4cd2015-09-24 11:19:19 -07003177
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003178 /* Verify the boot image
3179 * device & page_size are initialized in aboot_init
3180 */
Sridhar Parasuram7ae9fbc2015-09-17 09:56:30 -07003181 if (target_use_signed_kernel() && (!device.is_unlocked)) {
Channagoud Kadabi3d839012014-06-26 14:26:39 -07003182 /* Pass size excluding signature size, otherwise we would try to
3183 * access signature beyond its length
3184 */
Monika Singh292b3e92018-03-17 22:40:23 +05303185 verify_signed_bootimg((uint32_t)data, image_actual);
Sridhar Parasuram7ae9fbc2015-09-17 09:56:30 -07003186 }
Amit Blay4aa292f2015-04-28 21:55:59 +03003187#ifdef MDTP_SUPPORT
3188 else
3189 {
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003190 /* fastboot boot is not allowed when MDTP is activated */
Amit Blay4aa292f2015-04-28 21:55:59 +03003191 mdtp_ext_partition_verification_t ext_partition;
Amit Blay8a510302015-08-17 09:20:01 +03003192
3193 if (!is_mdtp_activated) {
3194 ext_partition.partition = MDTP_PARTITION_NONE;
3195 mdtp_fwlock_verify_lock(&ext_partition);
3196 }
Amit Blay4aa292f2015-04-28 21:55:59 +03003197 }
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003198
Amir Kotzer7c768c02016-04-13 09:08:05 +03003199 /* If mdtp state cannot be validate, block fastboot boot*/
3200 if(mdtp_activated(&is_mdtp_activated)){
3201 dprintf(CRITICAL, "mdtp_activated cannot validate state.\n");
3202 dprintf(CRITICAL, "Can not proceed with fastboot boot command.\n");
3203 goto boot_failed;
3204 }
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003205 if(is_mdtp_activated){
3206 dprintf(CRITICAL, "fastboot boot command is not available.\n");
lijuang2008ff22016-03-07 17:56:27 +08003207 goto boot_failed;
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003208 }
Amit Blay4aa292f2015-04-28 21:55:59 +03003209#endif /* MDTP_SUPPORT */
Monika Singh292b3e92018-03-17 22:40:23 +05303210#endif /* VERIFIED_BOOT_2 else */
Amit Blay4aa292f2015-04-28 21:55:59 +03003211
Sridhar Parasuram361e4cd2015-09-24 11:19:19 -07003212#if VERIFIED_BOOT
Monika Singh292b3e92018-03-17 22:40:23 +05303213 if (VB_M == target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05303214 {
3215 /* set boot and system versions. */
3216 set_os_version((unsigned char *)data);
3217 // send root of trust
3218 if(!send_rot_command((uint32_t)device.is_unlocked))
3219 ASSERT(0);
3220 }
Parth Dixitbc9b6492015-10-18 00:41:38 +05303221#endif
Channagoud Kadabia22144f2013-03-20 11:49:01 -07003222 /*
Matthew Qinbb7923d2015-02-09 10:56:09 +08003223 * Check if the kernel image is a gzip package. If yes, need to decompress it.
3224 * If not, continue booting.
3225 */
3226 if (is_gzip_package((unsigned char *)(data + page_size), hdr->kernel_size))
3227 {
3228 out_addr = (unsigned char *)target_get_scratch_address();
3229 out_addr = (unsigned char *)(out_addr + image_actual + page_size);
3230 out_avai_len = target_get_max_flash_size() - image_actual - page_size;
Saranya Chidurab4933332018-10-15 17:30:06 +05303231#if VERIFIED_BOOT_2
3232 if (dtbo_image_sz)
3233 out_avai_len -= DTBO_IMG_BUF;
3234#endif
Matthew Qin0b15b322015-05-19 05:20:54 -04003235 dprintf(INFO, "decompressing kernel image: start\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08003236 ret = decompress((unsigned char *)(ptr + page_size),
3237 hdr->kernel_size, out_addr, out_avai_len,
3238 &dtb_offset, &out_len);
3239 if (ret)
3240 {
Matthew Qin0b15b322015-05-19 05:20:54 -04003241 dprintf(CRITICAL, "decompressing image failed!!!\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08003242 ASSERT(0);
3243 }
3244
Matthew Qin0b15b322015-05-19 05:20:54 -04003245 dprintf(INFO, "decompressing kernel image: done\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08003246 kptr = (struct kernel64_hdr *)out_addr;
3247 kernel_start_addr = out_addr;
3248 kernel_size = out_len;
3249 } else {
3250 kptr = (struct kernel64_hdr*)((char *)data + page_size);
3251 kernel_start_addr = (unsigned char *)((char *)data + page_size);
3252 kernel_size = hdr->kernel_size;
3253 }
3254
3255 /*
Channagoud Kadabia22144f2013-03-20 11:49:01 -07003256 * Update the kernel/ramdisk/tags address if the boot image header
3257 * has default values, these default values come from mkbootimg when
3258 * the boot image is flashed using fastboot flash:raw
3259 */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08003260 update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr));
Dima Zavin3cadfff2013-03-21 14:30:48 -07003261
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003262 /* Get virtual addresses since the hdr saves physical addresses. */
3263 hdr->kernel_addr = VA(hdr->kernel_addr);
3264 hdr->ramdisk_addr = VA(hdr->ramdisk_addr);
3265 hdr->tags_addr = VA(hdr->tags_addr);
Brian Swetland9c4c0752009-01-25 16:23:50 -08003266
Matthew Qinbb7923d2015-02-09 10:56:09 +08003267 kernel_size = ROUND_TO_PAGE(kernel_size, page_mask);
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003268 /* Check if the addresses in the header are valid. */
Matthew Qinbb7923d2015-02-09 10:56:09 +08003269 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_size) ||
Mayank Grovere559cec2017-10-17 15:12:03 +05303270 check_ddr_addr_range_bound(hdr->kernel_addr, kernel_size) ||
3271 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
3272 check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003273 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303274 dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
lijuang2008ff22016-03-07 17:56:27 +08003275 goto boot_failed;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003276 }
3277
Amol Jadicb524072012-08-09 16:40:18 -07003278#if DEVICE_TREE
Matthew Qin271927e2015-03-31 22:07:07 -04003279 scratch_offset = image_actual + page_size + out_len;
Amol Jadicb524072012-08-09 16:40:18 -07003280 /* find correct dtb and copy it to right location */
Matthew Qin271927e2015-03-31 22:07:07 -04003281 ret = copy_dtb(data, scratch_offset);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003282
3283 dtb_copied = !ret ? 1 : 0;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003284#else
Mayank Grovere559cec2017-10-17 15:12:03 +05303285 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
3286 check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003287 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303288 dprintf(CRITICAL, "Tags addresses are not valid.\n");
lijuang2008ff22016-03-07 17:56:27 +08003289 goto boot_failed;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003290 }
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003291#endif
3292
3293 /* Load ramdisk & kernel */
3294 memmove((void*) hdr->ramdisk_addr, ptr + page_size + kernel_actual, hdr->ramdisk_size);
Matthew Qinbb7923d2015-02-09 10:56:09 +08003295 memmove((void*) hdr->kernel_addr, (char*) (kernel_start_addr), kernel_size);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003296
3297#if DEVICE_TREE
Mayank Grovere559cec2017-10-17 15:12:03 +05303298 if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
3299 check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
Matthew Qinbb7923d2015-02-09 10:56:09 +08003300 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303301 dprintf(CRITICAL, "Tags addresses are not valid.\n");
lijuang2008ff22016-03-07 17:56:27 +08003302 goto boot_failed;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003303 }
3304
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003305 /*
3306 * If dtb is not found look for appended DTB in the kernel.
3307 * If appended dev tree is found, update the atags with
3308 * memory address to the DTB appended location on RAM.
3309 * Else update with the atags address in the kernel header
3310 */
3311 if (!dtb_copied) {
3312 void *dtb;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003313 dtb = dev_tree_appended((void*)(ptr + page_size),
3314 hdr->kernel_size, dtb_offset,
Dima Zavine63e5572013-05-03 12:23:06 -07003315 (void *)hdr->tags_addr);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003316 if (!dtb) {
3317 fastboot_fail("dtb not found");
lijuang2008ff22016-03-07 17:56:27 +08003318 goto boot_failed;
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003319 }
Amol Jadicb524072012-08-09 16:40:18 -07003320 }
3321#endif
Brian Swetland9c4c0752009-01-25 16:23:50 -08003322
3323 fastboot_okay("");
Amol Jadi7c4316c2013-10-07 14:19:26 -07003324 fastboot_stop();
Brian Swetland9c4c0752009-01-25 16:23:50 -08003325
Dima Zavin77e41f32013-03-06 16:10:43 -08003326 boot_linux((void*) hdr->kernel_addr, (void*) hdr->tags_addr,
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003327 (const char*) hdr->cmdline, board_machtype(),
3328 (void*) hdr->ramdisk_addr, hdr->ramdisk_size);
lijuang2008ff22016-03-07 17:56:27 +08003329
3330 /* fastboot already stop, it's no need to show fastboot menu */
3331 return;
3332boot_failed:
3333#if FBCON_DISPLAY_MSG
3334 /* revert to fastboot menu if boot failed */
3335 display_fastboot_menu();
3336#endif
3337 return;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003338}
3339
Sridhar Parasurame94e8152014-10-24 14:06:03 -07003340void cmd_erase_nand(const char *arg, void *data, unsigned sz)
Dima Zavin214cc642009-01-26 11:16:21 -08003341{
3342 struct ptentry *ptn;
3343 struct ptable *ptable;
3344
3345 ptable = flash_get_ptable();
3346 if (ptable == NULL) {
3347 fastboot_fail("partition table doesn't exist");
3348 return;
3349 }
3350
3351 ptn = ptable_find(ptable, arg);
3352 if (ptn == NULL) {
3353 fastboot_fail("unknown partition name");
3354 return;
3355 }
3356
Monika Singh292b3e92018-03-17 22:40:23 +05303357 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
3358 dprintf(INFO, "erasing avb_custom_key\n");
3359 if (erase_userkey()) {
3360 fastboot_fail("Erasing avb_custom_key failed");
3361 } else {
3362 fastboot_okay("");
3363 }
3364 return;
3365 }
3366
Dima Zavin214cc642009-01-26 11:16:21 -08003367 if (flash_erase(ptn)) {
3368 fastboot_fail("failed to erase partition");
3369 return;
3370 }
3371 fastboot_okay("");
3372}
3373
Bikas Gurungd48bd242010-09-04 19:54:32 -07003374
3375void cmd_erase_mmc(const char *arg, void *data, unsigned sz)
3376{
3377 unsigned long long ptn = 0;
Oliver Wangcee448d2013-10-22 18:40:13 +08003378 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07003379 int index = INVALID_PTN;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003380 uint8_t lun = 0;
Vijay Kumar Pendoti0b21f462016-05-02 17:09:18 +05303381 char *footer = NULL;
Bikas Gurungd48bd242010-09-04 19:54:32 -07003382
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003383#if VERIFIED_BOOT
3384 if(!strcmp(arg, KEYSTORE_PTN_NAME))
3385 {
3386 if(!device.is_unlocked)
3387 {
3388 fastboot_fail("unlock device to erase keystore");
3389 return;
3390 }
3391 }
3392#endif
3393
Kinson Chikf1a43512011-07-14 11:28:39 -07003394 index = partition_get_index(arg);
3395 ptn = partition_get_offset(index);
Oliver Wangcee448d2013-10-22 18:40:13 +08003396 size = partition_get_size(index);
Neeti Desaica8c9602011-10-06 11:40:00 -07003397
Monika Singhc4778b72018-05-16 11:16:42 +05303398 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
3399 dprintf(INFO, "erasing avb_custom_key\n");
3400 if (erase_userkey()) {
3401 fastboot_fail("Erasing avb_custom_key failed");
3402 } else {
3403 fastboot_okay("");
3404 }
3405 return;
3406 }
3407
Kinson Chikf1a43512011-07-14 11:28:39 -07003408 if(ptn == 0) {
Neeti Desaica8c9602011-10-06 11:40:00 -07003409 fastboot_fail("Partition table doesn't exist\n");
Bikas Gurungd48bd242010-09-04 19:54:32 -07003410 return;
3411 }
Kun Liang2f1601a2013-08-12 16:29:54 +08003412
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003413 lun = partition_get_lun(index);
3414 mmc_set_lun(lun);
3415
Sridhar Parasuramd7957122015-02-27 11:33:40 -08003416 if (platform_boot_dev_isemmc())
3417 {
3418 if (mmc_erase_card(ptn, size)) {
3419 fastboot_fail("failed to erase partition\n");
3420 return;
3421 }
3422 } else {
3423 BUF_DMA_ALIGN(out, DEFAULT_ERASE_SIZE);
3424 size = partition_get_size(index);
3425 if (size > DEFAULT_ERASE_SIZE)
3426 size = DEFAULT_ERASE_SIZE;
Kun Liang2f1601a2013-08-12 16:29:54 +08003427
Sridhar Parasuramd7957122015-02-27 11:33:40 -08003428 /* Simple inefficient version of erase. Just writing
3429 0 in first several blocks */
3430 if (mmc_write(ptn , size, (unsigned int *)out)) {
3431 fastboot_fail("failed to erase partition");
3432 return;
3433 }
Vijay Kumar Pendoti0b21f462016-05-02 17:09:18 +05303434 /*Erase FDE metadata at the userdata footer*/
3435 if(!(strncmp(arg, "userdata", 8)))
3436 {
3437 footer = memalign(CACHE_LINE, FOOTER_SIZE);
3438 memset((void *)footer, 0, FOOTER_SIZE);
3439
3440 size = partition_get_size(index);
3441
3442 if (mmc_write((ptn + size) - FOOTER_SIZE , FOOTER_SIZE, (unsigned int *)footer)) {
3443 fastboot_fail("failed to erase userdata footer");
3444 free(footer);
3445 return;
3446 }
3447 free(footer);
3448 }
Bikas Gurungd48bd242010-09-04 19:54:32 -07003449 }
Monika Singh292b3e92018-03-17 22:40:23 +05303450#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05303451 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05303452 !(strncmp(arg, "userdata", 8)) &&
3453 send_delete_keys_to_tz())
Sridhar Parasuram32b30662015-07-10 13:33:22 -07003454 ASSERT(0);
3455#endif
Bikas Gurungd48bd242010-09-04 19:54:32 -07003456 fastboot_okay("");
3457}
3458
Sridhar Parasurame94e8152014-10-24 14:06:03 -07003459void cmd_erase(const char *arg, void *data, unsigned sz)
3460{
Monika Singh292b3e92018-03-17 22:40:23 +05303461#if VERIFIED_BOOT || VERIFIED_BOOT_2
Channagoud Kadabi35297672015-06-13 11:09:49 -07003462 if (target_build_variant_user())
Channagoud Kadabice3cf422015-04-17 16:02:30 -07003463 {
Sridhar Parasuramc32d07d2015-07-12 10:57:48 -07003464 if(!device.is_unlocked)
Channagoud Kadabice3cf422015-04-17 16:02:30 -07003465 {
Channagoud Kadabi35297672015-06-13 11:09:49 -07003466 fastboot_fail("device is locked. Cannot erase");
Channagoud Kadabice3cf422015-04-17 16:02:30 -07003467 return;
3468 }
3469 }
3470#endif
3471
Sridhar Parasurame94e8152014-10-24 14:06:03 -07003472 if(target_is_emmc_boot())
3473 cmd_erase_mmc(arg, data, sz);
3474 else
3475 cmd_erase_nand(arg, data, sz);
3476}
Bikas Gurungd48bd242010-09-04 19:54:32 -07003477
Mayank Grover11ff9692018-01-11 11:54:49 +05303478/* Get the size from partiton name */
3479static void get_partition_size(const char *arg, char *response)
3480{
3481 uint64_t ptn = 0;
3482 uint64_t size;
3483 int index = INVALID_PTN;
3484
3485 index = partition_get_index(arg);
3486
3487 if (index == INVALID_PTN)
3488 {
3489 dprintf(CRITICAL, "Invalid partition index\n");
3490 return;
3491 }
3492
3493 ptn = partition_get_offset(index);
3494
3495 if(!ptn)
3496 {
3497 dprintf(CRITICAL, "Invalid partition name %s\n", arg);
3498 return;
3499 }
3500
3501 size = partition_get_size(index);
3502
3503 snprintf(response, MAX_RSP_SIZE, "\t 0x%llx", size);
3504 return;
3505}
3506
Mayank Grover52cd10a2018-03-15 12:57:54 +05303507/* Function to check partition type of a partition*/
3508static fs_signature_type
3509check_partition_fs_signature(const char *arg)
3510{
3511 fs_signature_type ret = NO_FS;
3512 int index;
3513 unsigned long long ptn;
Mayank Grover399826a2018-08-27 12:15:15 +05303514 char *buffer = memalign(CACHE_LINE, mmc_blocksize);
3515 uint32_t sb_blk_offset = 0;
3516 char *sb_buffer = buffer;
3517
Mayank Grover52cd10a2018-03-15 12:57:54 +05303518 if (!sb_buffer)
3519 {
3520 dprintf(CRITICAL, "ERROR: Failed to allocate buffer for superblock\n");
3521 goto out;
3522 }
3523
3524 /* Read super block */
3525 if ((index = partition_get_index(arg)) < 0)
3526 {
3527 dprintf(CRITICAL, "ERROR: %s() doesn't exsit\n", arg);
3528 goto out;
3529 }
3530 ptn = partition_get_offset(index);
3531 mmc_set_lun(partition_get_lun(index));
Mayank Grover399826a2018-08-27 12:15:15 +05303532 sb_blk_offset = (FS_SUPERBLOCK_OFFSET/mmc_blocksize);
3533
3534 if(mmc_read(ptn + (sb_blk_offset * mmc_blocksize),
Mayank Grover52cd10a2018-03-15 12:57:54 +05303535 (void *)sb_buffer, mmc_blocksize))
3536 {
3537 dprintf(CRITICAL, "ERROR: Failed to read Superblock\n");
3538 goto out;
3539 }
3540
Mayank Grover399826a2018-08-27 12:15:15 +05303541 if (sb_blk_offset == 0)
3542 sb_buffer += FS_SUPERBLOCK_OFFSET;
3543
3544 if (*((uint16 *)(&sb_buffer[EXT_MAGIC_OFFSET_SB])) == (uint16)EXT_MAGIC)
Mayank Grover52cd10a2018-03-15 12:57:54 +05303545 {
3546 dprintf(SPEW, "%s() Found EXT FS\n", arg);
3547 ret = EXT_FS_SIGNATURE;
3548 }
Mayank Grover399826a2018-08-27 12:15:15 +05303549 else if (*((uint32 *)(&sb_buffer[F2FS_MAGIC_OFFSET_SB])) == F2FS_MAGIC)
Mayank Grover52cd10a2018-03-15 12:57:54 +05303550 {
3551 dprintf(SPEW, "%s() Found F2FS FS\n", arg);
3552 ret = EXT_F2FS_SIGNATURE;
3553 }
3554 else
3555 {
3556 dprintf(SPEW, "%s() Reverting to default 0x%x\n",
3557 arg, *((uint16 *)(&sb_buffer[EXT_MAGIC_OFFSET_SB])));
3558 ret = NO_FS;
3559 }
3560
3561out:
Mayank Grover399826a2018-08-27 12:15:15 +05303562 if(buffer)
3563 free(buffer);
Mayank Grover52cd10a2018-03-15 12:57:54 +05303564 return ret;
3565}
3566
Mayank Groverd38fe012018-03-13 15:33:16 +05303567/* Function to get partition type */
3568static void get_partition_type(const char *arg, char *response)
3569{
3570 uint n = 0;
Mayank Grover52cd10a2018-03-15 12:57:54 +05303571 fs_signature_type fs_signature;
Mayank Groverd38fe012018-03-13 15:33:16 +05303572
3573 if (arg == NULL ||
3574 response == NULL)
3575 {
3576 dprintf(CRITICAL, "Invalid input parameter\n");
3577 return;
3578 }
3579
3580 /* By default copy raw to response */
Mayank Grover0e559042018-04-11 17:49:30 +05303581 strlcpy(response, RAW_STR, MAX_RSP_SIZE);
Mayank Groverd38fe012018-03-13 15:33:16 +05303582
3583 /* Mark partiton type for known paritions only */
3584 for (n=0; n < ARRAY_SIZE(part_type_known); n++)
3585 {
3586 if (!strncmp(part_type_known[n].part_name, arg, strlen(arg)))
3587 {
Mayank Grover52cd10a2018-03-15 12:57:54 +05303588 /* Check partition for FS signature */
3589 fs_signature = check_partition_fs_signature(arg);
3590 switch (fs_signature)
3591 {
3592 case EXT_FS_SIGNATURE:
Mayank Grover0e559042018-04-11 17:49:30 +05303593 strlcpy(response, EXT_STR, MAX_RSP_SIZE);
Mayank Grover52cd10a2018-03-15 12:57:54 +05303594 break;
3595 case EXT_F2FS_SIGNATURE:
Mayank Grover0e559042018-04-11 17:49:30 +05303596 strlcpy(response, F2FS_STR, MAX_RSP_SIZE);
Mayank Grover52cd10a2018-03-15 12:57:54 +05303597 break;
3598 case NO_FS:
Mayank Grover0e559042018-04-11 17:49:30 +05303599 strlcpy(response, part_type_known[n].type_response, MAX_RSP_SIZE);
Mayank Grover52cd10a2018-03-15 12:57:54 +05303600 }
Mayank Groverd38fe012018-03-13 15:33:16 +05303601 }
3602 }
3603 return;
3604}
3605
Mayank Grover11ff9692018-01-11 11:54:49 +05303606/*
3607 * Publish the partition type & size info
3608 * fastboot getvar will publish the required information.
3609 * fastboot getvar partition_size:<partition_name>: partition size in hex
3610 * fastboot getvar partition_type:<partition_name>: partition type (ext/fat)
3611 */
3612static void publish_getvar_partition_info(struct getvar_partition_info *info, uint8_t num_parts)
3613{
Mayank Groverd38fe012018-03-13 15:33:16 +05303614 uint8_t i;
Mayank Grover11ff9692018-01-11 11:54:49 +05303615 static bool published = false;
3616 struct partition_entry *ptn_entry =
3617 partition_get_partition_entries();
3618 memset(info, 0, sizeof(struct getvar_partition_info)* num_parts);
3619
3620 for (i = 0; i < num_parts; i++) {
3621 strlcat(info[i].part_name, (const char *)ptn_entry[i].name, MAX_RSP_SIZE);
3622 strlcat(info[i].getvar_size, "partition-size:", MAX_GET_VAR_NAME_SIZE);
3623 strlcat(info[i].getvar_type, "partition-type:", MAX_GET_VAR_NAME_SIZE);
3624
Mayank Groverd38fe012018-03-13 15:33:16 +05303625 get_partition_type(info[i].part_name, info[i].type_response);
Mayank Grover11ff9692018-01-11 11:54:49 +05303626 get_partition_size(info[i].part_name, info[i].size_response);
Mayank Grover11ff9692018-01-11 11:54:49 +05303627 if (strlcat(info[i].getvar_size, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
3628 {
3629 dprintf(CRITICAL, "partition size name truncated\n");
3630 return;
3631 }
3632 if (strlcat(info[i].getvar_type, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
3633 {
3634 dprintf(CRITICAL, "partition type name truncated\n");
3635 return;
3636 }
3637
3638 if (!published)
3639 {
3640 /* publish partition size & type info */
3641 fastboot_publish((const char *) info[i].getvar_size, (const char *) info[i].size_response);
3642 fastboot_publish((const char *) info[i].getvar_type, (const char *) info[i].type_response);
3643 }
3644 }
3645 if (!published)
3646 published = true;
3647}
3648
3649
Ajay Dudani5c761132011-04-07 20:19:04 -07003650void cmd_flash_mmc_img(const char *arg, void *data, unsigned sz)
Shashank Mittal23b8f422010-04-16 19:27:21 -07003651{
3652 unsigned long long ptn = 0;
Subbaraman Narayanamurthyc95b5b12010-08-31 13:19:48 -07003653 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07003654 int index = INVALID_PTN;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003655 char *token = NULL;
3656 char *pname = NULL;
Sridhar Parasuramefc133f2015-05-04 13:35:41 -07003657 char *sp;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003658 uint8_t lun = 0;
3659 bool lun_set = false;
Mayank Grover351a75e2017-05-30 20:06:08 +05303660 int current_active_slot = INVALID;
Subbaraman Narayanamurthyc95b5b12010-08-31 13:19:48 -07003661
Sridhar Parasuramefc133f2015-05-04 13:35:41 -07003662 token = strtok_r((char *)arg, ":", &sp);
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003663 pname = token;
Sridhar Parasuramefc133f2015-05-04 13:35:41 -07003664 token = strtok_r(NULL, ":", &sp);
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003665 if(token)
3666 {
3667 lun = atoi(token);
3668 mmc_set_lun(lun);
3669 lun_set = true;
3670 }
3671
Mao Jinlong226f33a2014-07-04 17:24:10 +08003672 if (pname)
Greg Grisco6e754772011-06-23 12:19:39 -07003673 {
Channagoud Kadabiad259832015-05-29 11:14:17 -07003674 if (!strncmp(pname, "frp-unlock", strlen("frp-unlock")))
3675 {
3676 if (!aboot_frp_unlock(pname, data, sz))
3677 {
3678 fastboot_info("FRP unlock successful");
3679 fastboot_okay("");
3680 }
3681 else
3682 fastboot_fail("Secret key is invalid, please update the bootloader with secret key");
3683
3684 return;
3685 }
3686
Mao Jinlong226f33a2014-07-04 17:24:10 +08003687 if (!strcmp(pname, "partition"))
3688 {
3689 dprintf(INFO, "Attempt to write partition image.\n");
3690 if (write_partition(sz, (unsigned char *) data)) {
3691 fastboot_fail("failed to write partition");
Greg Grisco6e754772011-06-23 12:19:39 -07003692 return;
3693 }
Mayank Grover11ff9692018-01-11 11:54:49 +05303694 /* Re-publish partition table */
3695 publish_getvar_partition_info(part_info, partition_get_partition_count());
Mayank Grover351a75e2017-05-30 20:06:08 +05303696
3697 /* Rescan partition table to ensure we have multislot support*/
3698 if (partition_scan_for_multislot())
3699 {
3700 current_active_slot = partition_find_active_slot();
3701 dprintf(INFO, "Multislot supported: Slot %s active",
3702 (SUFFIX_SLOT(current_active_slot)));
3703 }
3704 partition_mark_active_slot(current_active_slot);
Greg Grisco6e754772011-06-23 12:19:39 -07003705 }
Mao Jinlong226f33a2014-07-04 17:24:10 +08003706 else
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003707 {
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003708#if VERIFIED_BOOT
3709 if(!strcmp(pname, KEYSTORE_PTN_NAME))
3710 {
3711 if(!device.is_unlocked)
3712 {
3713 fastboot_fail("unlock device to flash keystore");
3714 return;
3715 }
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +05303716 if(!boot_verify_validate_keystore((unsigned char *)data,sz))
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003717 {
3718 fastboot_fail("image is not a keystore file");
3719 return;
3720 }
3721 }
3722#endif
Mao Jinlong226f33a2014-07-04 17:24:10 +08003723 index = partition_get_index(pname);
3724 ptn = partition_get_offset(index);
3725 if(ptn == 0) {
3726 fastboot_fail("partition table doesn't exist");
3727 return;
3728 }
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003729
Mayank Grover351a75e2017-05-30 20:06:08 +05303730 if (!strncmp(pname, "boot", strlen("boot"))
3731 || !strcmp(pname, "recovery"))
3732 {
Mao Jinlong226f33a2014-07-04 17:24:10 +08003733 if (memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
3734 fastboot_fail("image is not a boot image");
3735 return;
3736 }
Mayank Grover351a75e2017-05-30 20:06:08 +05303737
3738 /* Reset multislot_partition attributes in case of flashing boot */
3739 if (partition_multislot_is_supported())
3740 {
3741 partition_reset_attributes(index);
3742 }
Mao Jinlong226f33a2014-07-04 17:24:10 +08003743 }
3744
3745 if(!lun_set)
3746 {
3747 lun = partition_get_lun(index);
3748 mmc_set_lun(lun);
3749 }
3750
3751 size = partition_get_size(index);
Gaurav Nebhwani4d2389c2016-03-17 21:10:05 +05303752 if (ROUND_TO_PAGE(sz, mmc_blocksize_mask) > size) {
Mao Jinlong226f33a2014-07-04 17:24:10 +08003753 fastboot_fail("size too large");
3754 return;
3755 }
3756 else if (mmc_write(ptn , sz, (unsigned int *)data)) {
3757 fastboot_fail("flash write failure");
3758 return;
3759 }
Greg Grisco6e754772011-06-23 12:19:39 -07003760 }
Shashank Mittal23b8f422010-04-16 19:27:21 -07003761 }
3762 fastboot_okay("");
3763 return;
3764}
3765
Ajay Dudanide984792015-03-02 09:57:41 -08003766void cmd_flash_meta_img(const char *arg, void *data, unsigned sz)
3767{
3768 int i, images;
3769 meta_header_t *meta_header;
3770 img_header_entry_t *img_header_entry;
Parth Dixit3e2d3032016-03-04 17:11:52 +05303771 /*End of the image address*/
3772 uintptr_t data_end;
3773
3774 if( (UINT_MAX - sz) > (uintptr_t)data )
3775 data_end = (uintptr_t)data + sz;
3776 else
3777 {
3778 fastboot_fail("Cannot flash: image header corrupt");
3779 return;
3780 }
3781
3782 if( data_end < ((uintptr_t)data + sizeof(meta_header_t)))
3783 {
3784 fastboot_fail("Cannot flash: image header corrupt");
3785 return;
3786 }
Ajay Dudanide984792015-03-02 09:57:41 -08003787
lijuang8ee21882016-04-19 16:57:11 +08003788 /* If device is locked:
3789 * Forbid to flash image to avoid the device to bypass the image
3790 * which with "any" name other than bootloader. Because it maybe
3791 * a meta package of all partitions.
3792 */
Monika Singh292b3e92018-03-17 22:40:23 +05303793#if VERIFIED_BOOT || VERIFIED_BOOT_2
lijuang8ee21882016-04-19 16:57:11 +08003794 if (target_build_variant_user()) {
3795 if (!device.is_unlocked) {
3796 fastboot_fail("Device is locked, meta image flashing is not allowed");
3797 return;
3798 }
Mayank Grover889be1b2017-09-12 20:12:23 +05303799
Mayank Grover912eaa62017-10-26 12:08:53 +05303800 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05303801 !device.is_unlock_critical)
3802 {
lijuang8ee21882016-04-19 16:57:11 +08003803 fastboot_fail("Device is critical locked, Meta image flashing is not allowed");
3804 return;
3805 }
lijuang8ee21882016-04-19 16:57:11 +08003806 }
3807#endif
3808
Ajay Dudanide984792015-03-02 09:57:41 -08003809 meta_header = (meta_header_t*) data;
Parth Dixit3e2d3032016-03-04 17:11:52 +05303810 if( data_end < ((uintptr_t)data + meta_header->img_hdr_sz))
3811 {
3812 fastboot_fail("Cannot flash: image header corrupt");
3813 return;
3814 }
Ajay Dudanide984792015-03-02 09:57:41 -08003815 img_header_entry = (img_header_entry_t*) (data+sizeof(meta_header_t));
3816
3817 images = meta_header->img_hdr_sz / sizeof(img_header_entry_t);
3818
3819 for (i=0; i<images; i++) {
3820
3821 if((img_header_entry[i].ptn_name == NULL) ||
3822 (img_header_entry[i].start_offset == 0) ||
3823 (img_header_entry[i].size == 0))
3824 break;
Kishor PK49831502017-04-21 17:55:43 +05303825 if ((UINT_MAX - img_header_entry[i].start_offset) < (uintptr_t)data) {
3826 fastboot_fail("Integer overflow detected in start_offset of img");
3827 break;
3828 }
3829 else if ((UINT_MAX - (img_header_entry[i].start_offset + (uintptr_t)data)) < img_header_entry[i].size) {
3830 fastboot_fail("Integer overflow detected in size of img");
3831 break;
3832 }
Parth Dixit3e2d3032016-03-04 17:11:52 +05303833 if( data_end < ((uintptr_t)data + img_header_entry[i].start_offset
3834 + img_header_entry[i].size) )
3835 {
3836 fastboot_fail("Cannot flash: image size mismatch");
3837 break;
3838 }
3839
Ajay Dudanide984792015-03-02 09:57:41 -08003840 cmd_flash_mmc_img(img_header_entry[i].ptn_name,
3841 (void *) data + img_header_entry[i].start_offset,
3842 img_header_entry[i].size);
3843 }
3844
Channagoud Kadabiaafbbfc2015-03-04 17:52:56 -08003845 if (!strncmp(arg, "bootloader", strlen("bootloader")))
3846 {
3847 strlcpy(device.bootloader_version, TARGET(BOARD), MAX_VERSION_LEN);
3848 strlcat(device.bootloader_version, "-", MAX_VERSION_LEN);
3849 strlcat(device.bootloader_version, meta_header->img_version, MAX_VERSION_LEN);
3850 }
3851 else
3852 {
3853 strlcpy(device.radio_version, TARGET(BOARD), MAX_VERSION_LEN);
3854 strlcat(device.radio_version, "-", MAX_VERSION_LEN);
3855 strlcat(device.radio_version, meta_header->img_version, MAX_VERSION_LEN);
3856 }
3857
3858 write_device_info(&device);
Ajay Dudanide984792015-03-02 09:57:41 -08003859 fastboot_okay("");
3860 return;
3861}
3862
Ajay Dudani5c761132011-04-07 20:19:04 -07003863void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
3864{
3865 unsigned int chunk;
wufeng.jiang813dc352015-06-02 23:02:46 -04003866 uint64_t chunk_data_sz;
Channagoud Kadabif627cf82013-09-09 14:08:20 -07003867 uint32_t *fill_buf = NULL;
3868 uint32_t fill_val;
Mayank Grover4f50bba2017-07-19 18:17:08 +05303869 uint32_t blk_sz_actual = 0;
Ajay Dudani5c761132011-04-07 20:19:04 -07003870 sparse_header_t *sparse_header;
3871 chunk_header_t *chunk_header;
Ajay Dudaniab18f022011-05-12 14:39:22 -07003872 uint32_t total_blocks = 0;
Ajay Dudani5c761132011-04-07 20:19:04 -07003873 unsigned long long ptn = 0;
Channagoud Kadabi65b91002011-10-11 17:34:33 +05303874 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07003875 int index = INVALID_PTN;
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05303876 uint32_t i;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003877 uint8_t lun = 0;
vijay kumar800255e2015-04-24 20:26:19 +05303878 /*End of the sparse image address*/
Parth Dixit64b1a482016-03-07 16:31:26 +05303879 uintptr_t data_end = (uintptr_t)data + sz;
Ajay Dudani5c761132011-04-07 20:19:04 -07003880
Kinson Chikf1a43512011-07-14 11:28:39 -07003881 index = partition_get_index(arg);
3882 ptn = partition_get_offset(index);
3883 if(ptn == 0) {
Ajay Dudani5c761132011-04-07 20:19:04 -07003884 fastboot_fail("partition table doesn't exist");
3885 return;
3886 }
3887
Channagoud Kadabi65b91002011-10-11 17:34:33 +05303888 size = partition_get_size(index);
Channagoud Kadabi65b91002011-10-11 17:34:33 +05303889
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003890 lun = partition_get_lun(index);
3891 mmc_set_lun(lun);
3892
vijay kumar800255e2015-04-24 20:26:19 +05303893 if (sz < sizeof(sparse_header_t)) {
3894 fastboot_fail("size too low");
3895 return;
3896 }
3897
Ajay Dudani5c761132011-04-07 20:19:04 -07003898 /* Read and skip over sparse image header */
3899 sparse_header = (sparse_header_t *) data;
vijay kumar800255e2015-04-24 20:26:19 +05303900
Mayank Grover48bd9bb2017-07-19 12:04:16 +05303901 if (!sparse_header->blk_sz || (sparse_header->blk_sz % 4)){
3902 fastboot_fail("Invalid block size\n");
3903 return;
3904 }
3905
vijay kumar1321f342015-03-27 12:13:42 +05303906 if (((uint64_t)sparse_header->total_blks * (uint64_t)sparse_header->blk_sz) > size) {
Ajay Dudani876b3282012-12-21 14:12:17 -08003907 fastboot_fail("size too large");
3908 return;
3909 }
3910
vijay kumarde4fcf62015-04-23 13:05:49 +05303911 data += sizeof(sparse_header_t);
vijay kumar800255e2015-04-24 20:26:19 +05303912
Parth Dixit64b1a482016-03-07 16:31:26 +05303913 if (data_end < (uintptr_t)data) {
vijay kumar800255e2015-04-24 20:26:19 +05303914 fastboot_fail("buffer overreads occured due to invalid sparse header");
3915 return;
3916 }
3917
vijay kumarde4fcf62015-04-23 13:05:49 +05303918 if(sparse_header->file_hdr_sz != sizeof(sparse_header_t))
Ajay Dudani5c761132011-04-07 20:19:04 -07003919 {
vijay kumarde4fcf62015-04-23 13:05:49 +05303920 fastboot_fail("sparse header size mismatch");
3921 return;
Ajay Dudani5c761132011-04-07 20:19:04 -07003922 }
3923
Ajay Dudanib06c05f2011-05-12 14:46:10 -07003924 dprintf (SPEW, "=== Sparse Image Header ===\n");
3925 dprintf (SPEW, "magic: 0x%x\n", sparse_header->magic);
3926 dprintf (SPEW, "major_version: 0x%x\n", sparse_header->major_version);
3927 dprintf (SPEW, "minor_version: 0x%x\n", sparse_header->minor_version);
3928 dprintf (SPEW, "file_hdr_sz: %d\n", sparse_header->file_hdr_sz);
3929 dprintf (SPEW, "chunk_hdr_sz: %d\n", sparse_header->chunk_hdr_sz);
3930 dprintf (SPEW, "blk_sz: %d\n", sparse_header->blk_sz);
3931 dprintf (SPEW, "total_blks: %d\n", sparse_header->total_blks);
3932 dprintf (SPEW, "total_chunks: %d\n", sparse_header->total_chunks);
Ajay Dudani5c761132011-04-07 20:19:04 -07003933
3934 /* Start processing chunks */
3935 for (chunk=0; chunk<sparse_header->total_chunks; chunk++)
3936 {
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05303937 /* Make sure the total image size does not exceed the partition size */
3938 if(((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz) >= size) {
3939 fastboot_fail("size too large");
3940 return;
3941 }
Ajay Dudani5c761132011-04-07 20:19:04 -07003942 /* Read and skip over chunk header */
3943 chunk_header = (chunk_header_t *) data;
3944 data += sizeof(chunk_header_t);
3945
Parth Dixit64b1a482016-03-07 16:31:26 +05303946 if (data_end < (uintptr_t)data) {
vijay kumar800255e2015-04-24 20:26:19 +05303947 fastboot_fail("buffer overreads occured due to invalid sparse header");
3948 return;
3949 }
3950
Ajay Dudani5c761132011-04-07 20:19:04 -07003951 dprintf (SPEW, "=== Chunk Header ===\n");
3952 dprintf (SPEW, "chunk_type: 0x%x\n", chunk_header->chunk_type);
3953 dprintf (SPEW, "chunk_data_sz: 0x%x\n", chunk_header->chunk_sz);
3954 dprintf (SPEW, "total_size: 0x%x\n", chunk_header->total_sz);
3955
vijay kumar800255e2015-04-24 20:26:19 +05303956 if(sparse_header->chunk_hdr_sz != sizeof(chunk_header_t))
Ajay Dudani5c761132011-04-07 20:19:04 -07003957 {
vijay kumar800255e2015-04-24 20:26:19 +05303958 fastboot_fail("chunk header size mismatch");
3959 return;
Ajay Dudani5c761132011-04-07 20:19:04 -07003960 }
3961
wufeng.jiang813dc352015-06-02 23:02:46 -04003962 chunk_data_sz = (uint64_t)sparse_header->blk_sz * chunk_header->chunk_sz;
3963
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05303964 /* Make sure that the chunk size calculated from sparse image does not
3965 * exceed partition size
3966 */
3967 if ((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz + chunk_data_sz > size)
3968 {
3969 fastboot_fail("Chunk data size exceeds partition size");
3970 return;
3971 }
3972
Ajay Dudani5c761132011-04-07 20:19:04 -07003973 switch (chunk_header->chunk_type)
3974 {
3975 case CHUNK_TYPE_RAW:
wufeng.jiang813dc352015-06-02 23:02:46 -04003976 if((uint64_t)chunk_header->total_sz != ((uint64_t)sparse_header->chunk_hdr_sz +
Ajay Dudani5c761132011-04-07 20:19:04 -07003977 chunk_data_sz))
3978 {
3979 fastboot_fail("Bogus chunk size for chunk type Raw");
3980 return;
3981 }
3982
Parth Dixit64b1a482016-03-07 16:31:26 +05303983 if (data_end < (uintptr_t)data + chunk_data_sz) {
vijay kumar800255e2015-04-24 20:26:19 +05303984 fastboot_fail("buffer overreads occured due to invalid sparse header");
3985 return;
3986 }
3987
wufeng.jiang813dc352015-06-02 23:02:46 -04003988 /* chunk_header->total_sz is uint32,So chunk_data_sz is now less than 2^32
3989 otherwise it will return in the line above
3990 */
Ajay Dudaniab18f022011-05-12 14:39:22 -07003991 if(mmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
wufeng.jiang813dc352015-06-02 23:02:46 -04003992 (uint32_t)chunk_data_sz,
Ajay Dudaniab18f022011-05-12 14:39:22 -07003993 (unsigned int*)data))
Ajay Dudani5c761132011-04-07 20:19:04 -07003994 {
3995 fastboot_fail("flash write failure");
3996 return;
3997 }
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05303998 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
3999 fastboot_fail("Bogus size for RAW chunk type");
4000 return;
4001 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004002 total_blocks += chunk_header->chunk_sz;
wufeng.jiang813dc352015-06-02 23:02:46 -04004003 data += (uint32_t)chunk_data_sz;
Ajay Dudani5c761132011-04-07 20:19:04 -07004004 break;
4005
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004006 case CHUNK_TYPE_FILL:
4007 if(chunk_header->total_sz != (sparse_header->chunk_hdr_sz +
4008 sizeof(uint32_t)))
4009 {
4010 fastboot_fail("Bogus chunk size for chunk type FILL");
4011 return;
4012 }
4013
Mayank Grover4f50bba2017-07-19 18:17:08 +05304014 blk_sz_actual = ROUNDUP(sparse_header->blk_sz, CACHE_LINE);
4015 /* Integer overflow detected */
4016 if (blk_sz_actual < sparse_header->blk_sz)
4017 {
4018 fastboot_fail("Invalid block size");
4019 return;
4020 }
4021
4022 fill_buf = (uint32_t *)memalign(CACHE_LINE, blk_sz_actual);
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004023 if (!fill_buf)
4024 {
4025 fastboot_fail("Malloc failed for: CHUNK_TYPE_FILL");
4026 return;
4027 }
4028
Parth Dixit64b1a482016-03-07 16:31:26 +05304029 if (data_end < (uintptr_t)data + sizeof(uint32_t)) {
vijay kumar800255e2015-04-24 20:26:19 +05304030 fastboot_fail("buffer overreads occured due to invalid sparse header");
Gaurav Nebhwani163cbf82016-03-17 21:21:27 +05304031 free(fill_buf);
vijay kumar800255e2015-04-24 20:26:19 +05304032 return;
4033 }
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004034 fill_val = *(uint32_t *)data;
4035 data = (char *) data + sizeof(uint32_t);
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004036
4037 for (i = 0; i < (sparse_header->blk_sz / sizeof(fill_val)); i++)
4038 {
4039 fill_buf[i] = fill_val;
4040 }
4041
Gaurav Nebhwanie94cbe12016-03-17 21:16:34 +05304042 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz))
4043 {
4044 fastboot_fail("bogus size for chunk FILL type");
4045 free(fill_buf);
4046 return;
4047 }
4048
wufeng.jiang813dc352015-06-02 23:02:46 -04004049 for (i = 0; i < chunk_header->chunk_sz; i++)
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004050 {
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304051 /* Make sure that the data written to partition does not exceed partition size */
4052 if ((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz + sparse_header->blk_sz > size)
4053 {
4054 fastboot_fail("Chunk data size for fill type exceeds partition size");
Gaurav Nebhwani163cbf82016-03-17 21:21:27 +05304055 free(fill_buf);
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304056 return;
4057 }
4058
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004059 if(mmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
4060 sparse_header->blk_sz,
4061 fill_buf))
4062 {
4063 fastboot_fail("flash write failure");
4064 free(fill_buf);
4065 return;
4066 }
4067
4068 total_blocks++;
4069 }
4070
4071 free(fill_buf);
4072 break;
4073
Ajay Dudani5c761132011-04-07 20:19:04 -07004074 case CHUNK_TYPE_DONT_CARE:
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304075 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
4076 fastboot_fail("bogus size for chunk DONT CARE type");
4077 return;
4078 }
Kinson Chik kchik@codeaurora.orgda29b1e2011-05-06 17:36:39 -07004079 total_blocks += chunk_header->chunk_sz;
4080 break;
4081
Ajay Dudani5c761132011-04-07 20:19:04 -07004082 case CHUNK_TYPE_CRC:
4083 if(chunk_header->total_sz != sparse_header->chunk_hdr_sz)
4084 {
wufeng.jiang813dc352015-06-02 23:02:46 -04004085 fastboot_fail("Bogus chunk size for chunk type CRC");
Ajay Dudani5c761132011-04-07 20:19:04 -07004086 return;
4087 }
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304088 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
4089 fastboot_fail("bogus size for chunk CRC type");
4090 return;
4091 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004092 total_blocks += chunk_header->chunk_sz;
Parth Dixit64b1a482016-03-07 16:31:26 +05304093 if ((uintptr_t)data > UINT_MAX - chunk_data_sz) {
vijay kumar800255e2015-04-24 20:26:19 +05304094 fastboot_fail("integer overflow occured");
4095 return;
4096 }
wufeng.jiang813dc352015-06-02 23:02:46 -04004097 data += (uint32_t)chunk_data_sz;
Parth Dixit64b1a482016-03-07 16:31:26 +05304098 if (data_end < (uintptr_t)data) {
vijay kumar800255e2015-04-24 20:26:19 +05304099 fastboot_fail("buffer overreads occured due to invalid sparse header");
4100 return;
4101 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004102 break;
4103
Kinson Chik kchik@codeaurora.orgda29b1e2011-05-06 17:36:39 -07004104 default:
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004105 dprintf(CRITICAL, "Unkown chunk type: %x\n",chunk_header->chunk_type);
Ajay Dudani5c761132011-04-07 20:19:04 -07004106 fastboot_fail("Unknown chunk type");
4107 return;
4108 }
4109 }
4110
Ajay Dudani0c6927b2011-05-18 11:12:16 -07004111 dprintf(INFO, "Wrote %d blocks, expected to write %d blocks\n",
4112 total_blocks, sparse_header->total_blks);
4113
4114 if(total_blocks != sparse_header->total_blks)
4115 {
4116 fastboot_fail("sparse image write failure");
4117 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004118
4119 fastboot_okay("");
4120 return;
4121}
4122
4123void cmd_flash_mmc(const char *arg, void *data, unsigned sz)
4124{
4125 sparse_header_t *sparse_header;
Ajay Dudanide984792015-03-02 09:57:41 -08004126 meta_header_t *meta_header;
Ajay Dudani5c761132011-04-07 20:19:04 -07004127
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07004128#ifdef SSD_ENABLE
Veera Sundaram Sankaranf9915462014-12-09 11:54:59 -08004129 /* 8 Byte Magic + 2048 Byte xml + Encrypted Data */
4130 unsigned int *magic_number = (unsigned int *) data;
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004131 int ret=0;
4132 uint32 major_version=0;
4133 uint32 minor_version=0;
4134
4135 ret = scm_svc_version(&major_version,&minor_version);
4136 if(!ret)
4137 {
4138 if(major_version >= 2)
4139 {
Amir Samuelovbb65ce02013-05-05 12:20:18 +03004140 if( !strcmp(arg, "ssd") || !strcmp(arg, "tqs") )
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004141 {
4142 ret = encrypt_scm((uint32 **) &data, &sz);
4143 if (ret != 0) {
4144 dprintf(CRITICAL, "ERROR: Encryption Failure\n");
4145 return;
4146 }
4147
Amir Samuelovbb65ce02013-05-05 12:20:18 +03004148 /* Protect only for SSD */
4149 if (!strcmp(arg, "ssd")) {
4150 ret = scm_protect_keystore((uint32 *) data, sz);
4151 if (ret != 0) {
4152 dprintf(CRITICAL, "ERROR: scm_protect_keystore Failed\n");
4153 return;
4154 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004155 }
4156 }
4157 else
4158 {
4159 ret = decrypt_scm_v2((uint32 **) &data, &sz);
4160 if(ret != 0)
4161 {
4162 dprintf(CRITICAL,"ERROR: Decryption Failure\n");
4163 return;
4164 }
4165 }
4166 }
4167 else
4168 {
4169 if (magic_number[0] == DECRYPT_MAGIC_0 &&
4170 magic_number[1] == DECRYPT_MAGIC_1)
4171 {
4172 ret = decrypt_scm((uint32 **) &data, &sz);
4173 if (ret != 0) {
4174 dprintf(CRITICAL, "ERROR: Invalid secure image\n");
4175 return;
4176 }
4177 }
4178 else if (magic_number[0] == ENCRYPT_MAGIC_0 &&
4179 magic_number[1] == ENCRYPT_MAGIC_1)
4180 {
4181 ret = encrypt_scm((uint32 **) &data, &sz);
4182 if (ret != 0) {
4183 dprintf(CRITICAL, "ERROR: Encryption Failure\n");
4184 return;
4185 }
4186 }
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07004187 }
4188 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004189 else
Neeti Desai127b9e02012-03-20 16:11:23 -07004190 {
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004191 dprintf(CRITICAL,"INVALID SVC Version\n");
4192 return;
Neeti Desai127b9e02012-03-20 16:11:23 -07004193 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004194#endif /* SSD_ENABLE */
Neeti Desai127b9e02012-03-20 16:11:23 -07004195
Monika Singh292b3e92018-03-17 22:40:23 +05304196#if VERIFIED_BOOT || VERIFIED_BOOT_2
Channagoud Kadabi35297672015-06-13 11:09:49 -07004197 if (target_build_variant_user())
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004198 {
lijuang511a2b52015-08-14 20:50:51 +08004199 /* if device is locked:
4200 * common partition will not allow to be flashed
4201 * critical partition will allow to flash image.
4202 */
4203 if(!device.is_unlocked && !critical_flash_allowed(arg)) {
4204 fastboot_fail("Partition flashing is not allowed");
4205 return;
4206 }
Mayank Grover889be1b2017-09-12 20:12:23 +05304207
lijuang511a2b52015-08-14 20:50:51 +08004208 /* if device critical is locked:
4209 * common partition will allow to be flashed
4210 * critical partition will not allow to flash image.
4211 */
Mayank Grover912eaa62017-10-26 12:08:53 +05304212 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05304213 !device.is_unlock_critical &&
4214 critical_flash_allowed(arg)) {
4215 fastboot_fail("Critical partition flashing is not allowed");
4216 return;
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004217 }
4218 }
4219#endif
Monika Singh292b3e92018-03-17 22:40:23 +05304220 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
4221 dprintf(INFO, "flashing avb_custom_key\n");
4222 if (store_userkey(data, sz)) {
4223 fastboot_fail("Flashing avb_custom_key failed");
4224 } else {
4225 fastboot_okay("");
4226 }
4227 return;
4228 }
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004229
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07004230 sparse_header = (sparse_header_t *) data;
Ajay Dudanide984792015-03-02 09:57:41 -08004231 meta_header = (meta_header_t *) data;
4232 if (sparse_header->magic == SPARSE_HEADER_MAGIC)
Ajay Dudani5c761132011-04-07 20:19:04 -07004233 cmd_flash_mmc_sparse_img(arg, data, sz);
Ajay Dudanide984792015-03-02 09:57:41 -08004234 else if (meta_header->magic == META_HEADER_MAGIC)
4235 cmd_flash_meta_img(arg, data, sz);
4236 else
4237 cmd_flash_mmc_img(arg, data, sz);
Sridhar Parasuramd69f7902015-07-10 13:31:17 -07004238
4239#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +05304240 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05304241 (!strncmp(arg, "system", 6)) &&
4242 !device.verity_mode)
Sridhar Parasuramd69f7902015-07-10 13:31:17 -07004243 // reset dm_verity mode to enforcing
4244 device.verity_mode = 1;
4245 write_device_info(&device);
Parth Dixitddbc7352015-10-18 03:13:31 +05304246#endif
Sridhar Parasuramd69f7902015-07-10 13:31:17 -07004247
Ajay Dudani5c761132011-04-07 20:19:04 -07004248 return;
4249}
4250
Tanya Brokhman84eaaf62015-02-24 21:57:06 +02004251void cmd_updatevol(const char *vol_name, void *data, unsigned sz)
4252{
4253 struct ptentry *sys_ptn;
4254 struct ptable *ptable;
4255
4256 ptable = flash_get_ptable();
4257 if (ptable == NULL) {
4258 fastboot_fail("partition table doesn't exist");
4259 return;
4260 }
4261
4262 sys_ptn = ptable_find(ptable, "system");
4263 if (sys_ptn == NULL) {
4264 fastboot_fail("system partition not found");
4265 return;
4266 }
4267
4268 sz = ROUND_TO_PAGE(sz, page_mask);
4269 if (update_ubi_vol(sys_ptn, vol_name, data, sz))
4270 fastboot_fail("update_ubi_vol failed");
4271 else
4272 fastboot_okay("");
4273}
4274
Sridhar Parasurame94e8152014-10-24 14:06:03 -07004275void cmd_flash_nand(const char *arg, void *data, unsigned sz)
Dima Zavin214cc642009-01-26 11:16:21 -08004276{
4277 struct ptentry *ptn;
4278 struct ptable *ptable;
4279 unsigned extra = 0;
Gaurav Nebhwanid9730712016-05-06 14:28:29 +05304280 uint64_t partition_size = 0;
Vijay Kumar Pendotic6f22a72017-05-19 22:44:34 +05304281 unsigned bytes_to_round_page = 0;
4282 unsigned rounded_size = 0;
Dima Zavin214cc642009-01-26 11:16:21 -08004283
Kishor PK38ed93d2017-04-25 14:19:26 +05304284 if((uintptr_t)data > (UINT_MAX - sz)) {
4285 fastboot_fail("Cannot flash: image header corrupt");
4286 return;
4287 }
4288
Dima Zavin214cc642009-01-26 11:16:21 -08004289 ptable = flash_get_ptable();
4290 if (ptable == NULL) {
4291 fastboot_fail("partition table doesn't exist");
4292 return;
4293 }
4294
4295 ptn = ptable_find(ptable, arg);
4296 if (ptn == NULL) {
Tanya Brokhman84eaaf62015-02-24 21:57:06 +02004297 dprintf(INFO, "unknown partition name (%s). Trying updatevol\n",
4298 arg);
4299 cmd_updatevol(arg, data, sz);
Dima Zavin214cc642009-01-26 11:16:21 -08004300 return;
4301 }
4302
Monika Singh292b3e92018-03-17 22:40:23 +05304303 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
4304 dprintf(INFO, "flashing avb_custom_key\n");
4305 if (store_userkey(data, sz)) {
4306 fastboot_fail("Flashing avb_custom_key failed");
4307 } else {
4308 fastboot_okay("");
4309 }
4310 return;
4311 }
4312
Dima Zavin214cc642009-01-26 11:16:21 -08004313 if (!strcmp(ptn->name, "boot") || !strcmp(ptn->name, "recovery")) {
Kishor PK38ed93d2017-04-25 14:19:26 +05304314 if((sz > BOOT_MAGIC_SIZE) && (!memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE))) {
4315 dprintf(INFO, "Verified the BOOT_MAGIC in image header \n");
4316 } else {
4317 fastboot_fail("Image is not a boot image");
Dima Zavin214cc642009-01-26 11:16:21 -08004318 return;
4319 }
4320 }
4321
Amol Jadi5c61a952012-05-04 17:05:35 -07004322 if (!strcmp(ptn->name, "system")
Deepa Dinamani13e32c42012-03-12 14:34:17 -07004323 || !strcmp(ptn->name, "userdata")
4324 || !strcmp(ptn->name, "persist")
Sundarajan Srinivasanb063a852013-11-19 14:02:27 -08004325 || !strcmp(ptn->name, "recoveryfs")
Sundarajan Srinivasan595b71e2013-11-05 12:44:34 -08004326 || !strcmp(ptn->name, "modem"))
Tanya Brokhman1c94f1a2015-02-15 09:05:03 +02004327 extra = 1;
Kishor PK38ed93d2017-04-25 14:19:26 +05304328 else {
Vijay Kumar Pendotic6f22a72017-05-19 22:44:34 +05304329 rounded_size = ROUNDUP(sz, page_size);
4330 bytes_to_round_page = rounded_size - sz;
4331 if (bytes_to_round_page) {
4332 if (((uintptr_t)data + sz ) > (UINT_MAX - bytes_to_round_page)) {
4333 fastboot_fail("Integer overflow detected");
4334 return;
4335 }
4336 if (((uintptr_t)data + sz + bytes_to_round_page) >
4337 ((uintptr_t)target_get_scratch_address() + target_get_max_flash_size())) {
4338 fastboot_fail("Buffer size is not aligned to page_size");
4339 return;
4340 }
4341 else {
4342 memset(data + sz, 0, bytes_to_round_page);
4343 sz = rounded_size;
4344 }
Kishor PK38ed93d2017-04-25 14:19:26 +05304345 }
Gaurav Nebhwanid9730712016-05-06 14:28:29 +05304346 }
4347
Kishor PK38ed93d2017-04-25 14:19:26 +05304348 /*Checking partition_size for the possible integer overflow */
4349 partition_size = validate_partition_size(ptn);
4350
Gaurav Nebhwanid9730712016-05-06 14:28:29 +05304351 if (sz > partition_size) {
4352 fastboot_fail("Image size too large");
4353 return;
4354 }
4355
Dima Zavin214cc642009-01-26 11:16:21 -08004356 dprintf(INFO, "writing %d bytes to '%s'\n", sz, ptn->name);
Mayank Grover6cde9352017-06-06 18:45:23 +05304357 if ((sz > UBI_EC_HDR_SIZE) &&
4358 (!memcmp((void *)data, UBI_MAGIC, UBI_MAGIC_SIZE))) {
Tanya Brokhman1c94f1a2015-02-15 09:05:03 +02004359 if (flash_ubi_img(ptn, data, sz)) {
4360 fastboot_fail("flash write failure");
4361 return;
4362 }
4363 } else {
4364 if (flash_write(ptn, extra, data, sz)) {
4365 fastboot_fail("flash write failure");
4366 return;
4367 }
Dima Zavin214cc642009-01-26 11:16:21 -08004368 }
4369 dprintf(INFO, "partition '%s' updated\n", ptn->name);
4370 fastboot_okay("");
4371}
4372
Kishor PK38ed93d2017-04-25 14:19:26 +05304373
4374static inline uint64_t validate_partition_size(struct ptentry *ptn)
4375{
4376 if (ptn->length && flash_num_pages_per_blk() && page_size) {
4377 if ((ptn->length < ( UINT_MAX / flash_num_pages_per_blk())) && ((ptn->length * flash_num_pages_per_blk()) < ( UINT_MAX / page_size))) {
4378 return ptn->length * flash_num_pages_per_blk() * page_size;
4379 }
4380 }
4381 return 0;
4382}
4383
4384
Sridhar Parasurame94e8152014-10-24 14:06:03 -07004385void cmd_flash(const char *arg, void *data, unsigned sz)
4386{
4387 if(target_is_emmc_boot())
4388 cmd_flash_mmc(arg, data, sz);
4389 else
4390 cmd_flash_nand(arg, data, sz);
4391}
4392
Dima Zavin214cc642009-01-26 11:16:21 -08004393void cmd_continue(const char *arg, void *data, unsigned sz)
4394{
4395 fastboot_okay("");
Amol Jadi7c4316c2013-10-07 14:19:26 -07004396 fastboot_stop();
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004397
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004398 if (target_is_emmc_boot())
4399 {
lijuanga40d6302015-07-20 20:10:13 +08004400#if FBCON_DISPLAY_MSG
lijuangde34d502016-02-26 16:04:50 +08004401 /* Exit keys' detection thread firstly */
4402 exit_menu_keys_detection();
lijuanga40d6302015-07-20 20:10:13 +08004403#endif
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004404 boot_linux_from_mmc();
4405 }
4406 else
4407 {
4408 boot_linux_from_flash();
4409 }
Dima Zavin214cc642009-01-26 11:16:21 -08004410}
4411
Chandan Uddaraju94183c02010-01-15 15:13:59 -08004412void cmd_reboot(const char *arg, void *data, unsigned sz)
4413{
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004414 dprintf(INFO, "rebooting the device\n");
Chandan Uddaraju94183c02010-01-15 15:13:59 -08004415 fastboot_okay("");
4416 reboot_device(0);
4417}
4418
Mayank Grover351a75e2017-05-30 20:06:08 +05304419void cmd_set_active(const char *arg, void *data, unsigned sz)
4420{
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304421 char *p, *sp = NULL;
Mayank Grover351a75e2017-05-30 20:06:08 +05304422 unsigned i,current_active_slot;
4423 const char *current_slot_suffix;
4424
4425 if (!partition_multislot_is_supported())
4426 {
4427 fastboot_fail("Command not supported");
4428 return;
4429 }
4430
4431 if (arg)
4432 {
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304433 p = strtok_r((char *)arg, ":", &sp);
Mayank Grover5eb5f692017-07-19 20:16:04 +05304434 if (p)
Mayank Grover351a75e2017-05-30 20:06:08 +05304435 {
4436 current_active_slot = partition_find_active_slot();
4437
4438 /* Check if trying to make curent slot active */
4439 current_slot_suffix = SUFFIX_SLOT(current_active_slot);
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304440 current_slot_suffix = strtok_r((char *)current_slot_suffix,
4441 (char *)suffix_delimiter, &sp);
4442
Mayank Grover5eb5f692017-07-19 20:16:04 +05304443 if (current_slot_suffix &&
4444 !strncmp(p, current_slot_suffix, strlen(current_slot_suffix)))
Mayank Grover351a75e2017-05-30 20:06:08 +05304445 {
4446 fastboot_okay("Slot already set active");
4447 return;
4448 }
4449 else
4450 {
4451 for (i = 0; i < AB_SUPPORTED_SLOTS; i++)
4452 {
4453 current_slot_suffix = SUFFIX_SLOT(i);
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304454 current_slot_suffix = strtok_r((char *)current_slot_suffix,
4455 (char *)suffix_delimiter, &sp);
Mayank Grover5eb5f692017-07-19 20:16:04 +05304456 if (current_slot_suffix &&
4457 !strncmp(p, current_slot_suffix, strlen(current_slot_suffix)))
Mayank Grover351a75e2017-05-30 20:06:08 +05304458 {
lijuang8b03e5f2019-07-12 18:16:19 +08004459 partition_switch_slots(current_active_slot, i, true);
Mayank Grover351a75e2017-05-30 20:06:08 +05304460 publish_getvar_multislot_vars();
4461 fastboot_okay("");
4462 return;
4463 }
4464 }
4465 }
4466 }
4467 }
4468 fastboot_fail("Invalid slot suffix.");
4469 return;
4470}
4471
Mayank Grover98c4c742019-04-25 17:21:37 +05304472#if DYNAMIC_PARTITION_SUPPORT
4473void cmd_reboot_fastboot(const char *arg, void *data, unsigned sz)
4474{
4475 dprintf(INFO, "rebooting the device - userspace fastboot\n");
4476 if (send_recovery_cmd(RECOVERY_BOOT_FASTBOOT_CMD)) {
4477 dprintf(CRITICAL, "ERROR: Failed to update recovery commands\n");
4478 fastboot_fail("Failed to update recovery command");
4479 return;
4480 }
4481 fastboot_okay("");
4482 reboot_device(REBOOT_MODE_UNKNOWN);
4483
4484 //shouldn't come here.
4485 dprintf(CRITICAL, "ERROR: Failed to reboot device\n");
4486 return;
4487}
4488
4489void cmd_reboot_recovery(const char *arg, void *data, unsigned sz)
4490{
4491 dprintf(INFO, "rebooting the device - recovery\n");
4492 if (send_recovery_cmd(RECOVERY_BOOT_RECOVERY_CMD)) {
4493 dprintf(CRITICAL, "ERROR: Failed to update recovery commands\n");
4494 fastboot_fail("Failed to update recovery command");
4495 return;
4496 }
4497 fastboot_okay("");
4498 reboot_device(REBOOT_MODE_UNKNOWN);
4499
4500 //shouldn't come here.
4501 dprintf(CRITICAL, "ERROR: Failed to reboot device\n");
4502 return;
4503}
4504#endif
4505
Chandan Uddaraju94183c02010-01-15 15:13:59 -08004506void cmd_reboot_bootloader(const char *arg, void *data, unsigned sz)
4507{
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004508 dprintf(INFO, "rebooting the device\n");
Chandan Uddaraju94183c02010-01-15 15:13:59 -08004509 fastboot_okay("");
4510 reboot_device(FASTBOOT_MODE);
4511}
4512
Ameya Thakur11cf1a62013-08-05 12:44:48 -07004513void cmd_oem_enable_charger_screen(const char *arg, void *data, unsigned size)
4514{
4515 dprintf(INFO, "Enabling charger screen check\n");
4516 device.charger_screen_enabled = 1;
4517 write_device_info(&device);
4518 fastboot_okay("");
4519}
4520
4521void cmd_oem_disable_charger_screen(const char *arg, void *data, unsigned size)
4522{
4523 dprintf(INFO, "Disabling charger screen check\n");
4524 device.charger_screen_enabled = 0;
4525 write_device_info(&device);
4526 fastboot_okay("");
4527}
4528
lijuanga25d8bb2015-09-16 13:11:52 +08004529void cmd_oem_off_mode_charger(const char *arg, void *data, unsigned size)
4530{
4531 char *p = NULL;
4532 const char *delim = " \t\n\r";
Parth Dixit407f15b2016-01-07 14:47:37 +05304533 char *sp;
lijuanga25d8bb2015-09-16 13:11:52 +08004534
4535 if (arg) {
Parth Dixit407f15b2016-01-07 14:47:37 +05304536 p = strtok_r((char *)arg, delim, &sp);
lijuanga25d8bb2015-09-16 13:11:52 +08004537 if (p) {
4538 if (!strncmp(p, "0", 1)) {
4539 device.charger_screen_enabled = 0;
4540 } else if (!strncmp(p, "1", 1)) {
4541 device.charger_screen_enabled = 1;
4542 }
4543 }
4544 }
4545
4546 /* update charger_screen_enabled value for getvar
4547 * command
4548 */
4549 snprintf(charger_screen_enabled, MAX_RSP_SIZE, "%d",
4550 device.charger_screen_enabled);
4551
4552 write_device_info(&device);
4553 fastboot_okay("");
4554}
4555
Unnati Gandhi62c8ab82014-01-24 11:01:01 +05304556void cmd_oem_select_display_panel(const char *arg, void *data, unsigned size)
4557{
4558 dprintf(INFO, "Selecting display panel %s\n", arg);
4559 if (arg)
4560 strlcpy(device.display_panel, arg,
4561 sizeof(device.display_panel));
4562 write_device_info(&device);
4563 fastboot_okay("");
4564}
4565
AnilKumar Chimata7fb62f92017-07-11 12:30:17 +05304566#if QSEECOM_TEST_SUPPORT
4567void cmd_oem_qseecom_test_cmd_handler(const char *arg, void *data, unsigned size)
4568{
4569 if (arg){
4570 dprintf(INFO, "Validating qseecom app %s\n", arg);
4571 qseecom_test_cmd_handler(arg);
4572 } else {
4573 dprintf(INFO, "Unsupported command\n");
4574 }
4575 fastboot_okay("");
4576}
4577#else
4578void cmd_oem_qseecom_test_cmd_handler(const char *arg, void *data, unsigned size)
4579{
4580 return;
4581}
4582#endif
4583
Shashank Mittal162244e2011-08-08 19:01:25 -07004584void cmd_oem_unlock(const char *arg, void *data, unsigned sz)
4585{
lijuang4ece1e72015-08-14 21:02:36 +08004586 set_device_unlock(UNLOCK, TRUE);
vijay kumarc65876c2015-04-24 13:29:16 +05304587}
4588
4589void cmd_oem_unlock_go(const char *arg, void *data, unsigned sz)
4590{
lijuang4ece1e72015-08-14 21:02:36 +08004591 if(!device.is_unlocked) {
vijay kumarc65876c2015-04-24 13:29:16 +05304592 if(!is_allow_unlock) {
4593 fastboot_fail("oem unlock is not allowed");
4594 return;
4595 }
4596
lijuang4ece1e72015-08-14 21:02:36 +08004597 set_device_unlock_value(UNLOCK, TRUE);
vijay kumarc65876c2015-04-24 13:29:16 +05304598
lijuang4ece1e72015-08-14 21:02:36 +08004599 /* wipe data */
vijay kumarc65876c2015-04-24 13:29:16 +05304600 struct recovery_message msg;
Kishor PK60a68212017-05-08 16:55:57 +05304601 memset(&msg, 0, sizeof(msg));
vijay kumarc65876c2015-04-24 13:29:16 +05304602 snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
4603 write_misc(0, &msg, sizeof(msg));
4604
4605 fastboot_okay("");
4606 reboot_device(RECOVERY_MODE);
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004607 }
4608 fastboot_okay("");
4609}
4610
Channagoud Kadabiad259832015-05-29 11:14:17 -07004611static int aboot_frp_unlock(char *pname, void *data, unsigned sz)
4612{
Mayank Grover70f8b0e2017-05-17 11:49:00 +05304613 int ret=1;
4614 bool authentication_success=false;
Channagoud Kadabiad259832015-05-29 11:14:17 -07004615
Mayank Grover70f8b0e2017-05-17 11:49:00 +05304616 /*
4617 Authentication method not implemented.
4618
4619 OEM to implement, authentication system which on successful validataion,
4620 calls write_allow_oem_unlock() with is_allow_unlock.
4621 */
4622#if 0
4623 authentication_success = oem_specific_auth_mthd();
4624#endif
4625
4626 if (authentication_success)
Channagoud Kadabiad259832015-05-29 11:14:17 -07004627 {
Mayank Grover70f8b0e2017-05-17 11:49:00 +05304628 is_allow_unlock = true;
4629 write_allow_oem_unlock(is_allow_unlock);
4630 ret = 0;
Channagoud Kadabiad259832015-05-29 11:14:17 -07004631 }
4632 return ret;
4633}
4634
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004635void cmd_oem_lock(const char *arg, void *data, unsigned sz)
4636{
lijuang4ece1e72015-08-14 21:02:36 +08004637 set_device_unlock(UNLOCK, FALSE);
Shashank Mittal162244e2011-08-08 19:01:25 -07004638}
4639
Shashank Mittala0032282011-08-26 14:50:11 -07004640void cmd_oem_devinfo(const char *arg, void *data, unsigned sz)
4641{
lijuang511a2b52015-08-14 20:50:51 +08004642 char response[MAX_RSP_SIZE];
Ameya Thakur11cf1a62013-08-05 12:44:48 -07004643 snprintf(response, sizeof(response), "\tDevice tampered: %s", (device.is_tampered ? "true" : "false"));
Shashank Mittala0032282011-08-26 14:50:11 -07004644 fastboot_info(response);
Ameya Thakur11cf1a62013-08-05 12:44:48 -07004645 snprintf(response, sizeof(response), "\tDevice unlocked: %s", (device.is_unlocked ? "true" : "false"));
4646 fastboot_info(response);
Monika Singh292b3e92018-03-17 22:40:23 +05304647#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05304648 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05304649 {
4650 snprintf(response, sizeof(response), "\tDevice critical unlocked: %s",
4651 (device.is_unlock_critical ? "true" : "false"));
4652 fastboot_info(response);
4653 }
Parth Dixitddbc7352015-10-18 03:13:31 +05304654#endif
Ameya Thakur11cf1a62013-08-05 12:44:48 -07004655 snprintf(response, sizeof(response), "\tCharger screen enabled: %s", (device.charger_screen_enabled ? "true" : "false"));
Shashank Mittala0032282011-08-26 14:50:11 -07004656 fastboot_info(response);
Unnati Gandhi62c8ab82014-01-24 11:01:01 +05304657 snprintf(response, sizeof(response), "\tDisplay panel: %s", (device.display_panel));
4658 fastboot_info(response);
Shashank Mittala0032282011-08-26 14:50:11 -07004659 fastboot_okay("");
4660}
4661
lijuang511a2b52015-08-14 20:50:51 +08004662void cmd_flashing_get_unlock_ability(const char *arg, void *data, unsigned sz)
4663{
4664 char response[MAX_RSP_SIZE];
4665 snprintf(response, sizeof(response), "\tget_unlock_ability: %d", is_allow_unlock);
4666 fastboot_info(response);
4667 fastboot_okay("");
4668}
4669
4670void cmd_flashing_lock_critical(const char *arg, void *data, unsigned sz)
4671{
lijuang4ece1e72015-08-14 21:02:36 +08004672 set_device_unlock(UNLOCK_CRITICAL, FALSE);
lijuang511a2b52015-08-14 20:50:51 +08004673}
4674
4675void cmd_flashing_unlock_critical(const char *arg, void *data, unsigned sz)
4676{
lijuang4ece1e72015-08-14 21:02:36 +08004677 set_device_unlock(UNLOCK_CRITICAL, TRUE);
lijuang511a2b52015-08-14 20:50:51 +08004678}
4679
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -07004680void cmd_preflash(const char *arg, void *data, unsigned sz)
4681{
4682 fastboot_okay("");
4683}
4684
Mao Flynn7b379f32015-04-20 00:28:30 +08004685static uint8_t logo_header[LOGO_IMG_HEADER_SIZE];
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304686
Mao Flynn7b379f32015-04-20 00:28:30 +08004687int splash_screen_check_header(logo_img_header *header)
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304688{
Mao Flynn7b379f32015-04-20 00:28:30 +08004689 if (memcmp(header->magic, LOGO_IMG_MAGIC, 8))
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304690 return -1;
Mao Flynn7b379f32015-04-20 00:28:30 +08004691 if (header->width == 0 || header->height == 0)
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304692 return -1;
4693 return 0;
4694}
4695
Mao Flynn7b379f32015-04-20 00:28:30 +08004696int splash_screen_flash()
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07004697{
4698 struct ptentry *ptn;
4699 struct ptable *ptable;
Mao Flynn7b379f32015-04-20 00:28:30 +08004700 struct logo_img_header *header;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07004701 struct fbcon_config *fb_display = NULL;
Channagoud Kadabib3ccf5c2014-12-03 12:39:29 -08004702
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304703 ptable = flash_get_ptable();
4704 if (ptable == NULL) {
Mao Flynn7b379f32015-04-20 00:28:30 +08004705 dprintf(CRITICAL, "ERROR: Partition table not found\n");
4706 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304707 }
Mao Flynn7b379f32015-04-20 00:28:30 +08004708
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304709 ptn = ptable_find(ptable, "splash");
4710 if (ptn == NULL) {
4711 dprintf(CRITICAL, "ERROR: splash Partition not found\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004712 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304713 }
Mao Flynn7b379f32015-04-20 00:28:30 +08004714 if (flash_read(ptn, 0, (void *)logo_header, LOGO_IMG_HEADER_SIZE)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304715 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004716 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304717 }
4718
Mao Flynn7b379f32015-04-20 00:28:30 +08004719 header = (struct logo_img_header *)logo_header;
4720 if (splash_screen_check_header(header)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304721 dprintf(CRITICAL, "ERROR: Boot image header invalid\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004722 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304723 }
4724
4725 fb_display = fbcon_display();
4726 if (fb_display) {
raghavendra ambadas554f4fd2018-10-09 15:50:40 +05304727 if (header->type && (header->blocks != 0) &&
4728 (UINT_MAX >= header->blocks * 512) &&
4729 ((header->blocks * 512) <= (fb_display->width *
4730 fb_display->height * (fb_display->bpp / 8)))) {
4731 /* RLE24 compressed data */
Mao Flynn7b379f32015-04-20 00:28:30 +08004732 uint8_t *base = (uint8_t *) fb_display->base + LOGO_IMG_OFFSET;
4733
4734 /* if the logo is full-screen size, remove "fbcon_clear()" */
4735 if ((header->width != fb_display->width)
4736 || (header->height != fb_display->height))
4737 fbcon_clear();
4738
4739 if (flash_read(ptn + LOGO_IMG_HEADER_SIZE, 0,
4740 (uint32_t *)base,
4741 (header->blocks * 512))) {
4742 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
4743 return -1;
4744 }
4745 fbcon_extract_to_screen(header, base);
4746 return 0;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07004747 }
Mao Flynn7b379f32015-04-20 00:28:30 +08004748
Veera Sundaram Sankaranc33416f2015-09-28 10:25:55 -07004749 if ((header->width > fb_display->width) || (header->height > fb_display->height)) {
4750 dprintf(CRITICAL, "Logo config greater than fb config. Fall back default logo\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004751 return -1;
4752 }
4753
Vineet Bajaj99291ed2014-09-09 12:29:46 +05304754 uint8_t *base = (uint8_t *) fb_display->base;
Sachin Bhayare619e9e42017-05-15 13:10:31 +05304755 uint32_t fb_size = ROUNDUP(fb_display->width *
4756 fb_display->height *
4757 (fb_display->bpp / 8), 4096);
4758 uint32_t splash_size = ((((header->width * header->height *
4759 fb_display->bpp/8) + 511) >> 9) << 9);
4760
4761 if (splash_size > fb_size) {
4762 dprintf(CRITICAL, "ERROR: Splash image size invalid\n");
4763 return -1;
4764 }
4765
Mao Flynn7b379f32015-04-20 00:28:30 +08004766 if (flash_read(ptn + LOGO_IMG_HEADER_SIZE, 0,
4767 (uint32_t *)base,
4768 ((((header->width * header->height * fb_display->bpp/8) + 511) >> 9) << 9))) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304769 fbcon_clear();
Vineet Bajaj99291ed2014-09-09 12:29:46 +05304770 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004771 return -1;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07004772 }
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304773 }
4774
Mao Flynn7b379f32015-04-20 00:28:30 +08004775 return 0;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304776}
4777
Mao Flynn7b379f32015-04-20 00:28:30 +08004778int splash_screen_mmc()
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304779{
4780 int index = INVALID_PTN;
4781 unsigned long long ptn = 0;
4782 struct fbcon_config *fb_display = NULL;
Mao Flynn7b379f32015-04-20 00:28:30 +08004783 struct logo_img_header *header;
Mao Flynn1893a7f2015-06-03 12:03:36 +08004784 uint32_t blocksize, realsize, readsize;
4785 uint8_t *base;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304786
4787 index = partition_get_index("splash");
4788 if (index == 0) {
4789 dprintf(CRITICAL, "ERROR: splash Partition table not found\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004790 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304791 }
4792
4793 ptn = partition_get_offset(index);
4794 if (ptn == 0) {
4795 dprintf(CRITICAL, "ERROR: splash Partition invalid\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004796 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304797 }
4798
Mao Flynn1893a7f2015-06-03 12:03:36 +08004799 mmc_set_lun(partition_get_lun(index));
4800
4801 blocksize = mmc_get_device_blocksize();
4802 if (blocksize == 0) {
4803 dprintf(CRITICAL, "ERROR:splash Partition invalid blocksize\n");
4804 return -1;
4805 }
4806
4807 fb_display = fbcon_display();
Channagoud Kadabidaf10a62015-07-22 11:51:55 -07004808 if (!fb_display)
4809 {
4810 dprintf(CRITICAL, "ERROR: fb config is not allocated\n");
4811 return -1;
4812 }
4813
Mao Flynn1893a7f2015-06-03 12:03:36 +08004814 base = (uint8_t *) fb_display->base;
4815
Kishor PKee5c0a32018-03-06 16:49:46 +05304816 if (mmc_read(ptn + PLL_CODES_OFFSET, (uint32_t *)(base + LOGO_IMG_OFFSET), blocksize)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304817 dprintf(CRITICAL, "ERROR: Cannot read splash image header\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004818 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304819 }
4820
Mao Flynn1893a7f2015-06-03 12:03:36 +08004821 header = (struct logo_img_header *)(base + LOGO_IMG_OFFSET);
Mao Flynn7b379f32015-04-20 00:28:30 +08004822 if (splash_screen_check_header(header)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304823 dprintf(CRITICAL, "ERROR: Splash image header invalid\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004824 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304825 }
4826
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304827 if (fb_display) {
raghavendra ambadas554f4fd2018-10-09 15:50:40 +05304828 if (header->type && (header->blocks != 0) &&
4829 (UINT_MAX >= header->blocks * 512 + LOGO_IMG_HEADER_SIZE) &&
4830 ((header->blocks * 512) <= (fb_display->width *
4831 fb_display->height * (fb_display->bpp / 8)))) {
4832 /* 1 RLE24 compressed data */
Mao Flynn1893a7f2015-06-03 12:03:36 +08004833 base += LOGO_IMG_OFFSET;
Mao Flynn7b379f32015-04-20 00:28:30 +08004834
Mao Flynn1893a7f2015-06-03 12:03:36 +08004835 realsize = header->blocks * 512;
4836 readsize = ROUNDUP((realsize + LOGO_IMG_HEADER_SIZE), blocksize) - blocksize;
4837
4838 /* if the logo is not full-screen size, clean screen */
Mao Flynn7b379f32015-04-20 00:28:30 +08004839 if ((header->width != fb_display->width)
4840 || (header->height != fb_display->height))
4841 fbcon_clear();
4842
Sachin Bhayare619e9e42017-05-15 13:10:31 +05304843 uint32_t fb_size = ROUNDUP(fb_display->width *
4844 fb_display->height *
4845 (fb_display->bpp / 8), 4096);
4846
4847 if (readsize > fb_size) {
4848 dprintf(CRITICAL, "ERROR: Splash image size invalid\n");
4849 return -1;
4850 }
4851
Kishor PKee5c0a32018-03-06 16:49:46 +05304852 if (mmc_read(ptn + PLL_CODES_OFFSET + blocksize, (uint32_t *)(base + blocksize), readsize)) {
Mao Flynn7b379f32015-04-20 00:28:30 +08004853 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
4854 return -1;
4855 }
Mao Flynn7b379f32015-04-20 00:28:30 +08004856
Mao Flynn1893a7f2015-06-03 12:03:36 +08004857 fbcon_extract_to_screen(header, (base + LOGO_IMG_HEADER_SIZE));
4858 } else { /* 2 Raw BGR data */
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304859
Veera Sundaram Sankaranc33416f2015-09-28 10:25:55 -07004860 if ((header->width > fb_display->width) || (header->height > fb_display->height)) {
4861 dprintf(CRITICAL, "Logo config greater than fb config. Fall back default logo\n");
Mao Flynn1893a7f2015-06-03 12:03:36 +08004862 return -1;
4863 }
4864
4865 realsize = header->width * header->height * fb_display->bpp / 8;
4866 readsize = ROUNDUP((realsize + LOGO_IMG_HEADER_SIZE), blocksize) - blocksize;
4867
4868 if (blocksize == LOGO_IMG_HEADER_SIZE) { /* read the content directly */
Kishor PKee5c0a32018-03-06 16:49:46 +05304869 if (mmc_read((ptn + PLL_CODES_OFFSET + LOGO_IMG_HEADER_SIZE), (uint32_t *)base, readsize)) {
Mao Flynn1893a7f2015-06-03 12:03:36 +08004870 fbcon_clear();
4871 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
4872 return -1;
4873 }
4874 } else {
Kishor PKee5c0a32018-03-06 16:49:46 +05304875 if (mmc_read(ptn + PLL_CODES_OFFSET + blocksize ,
Mao Flynn1893a7f2015-06-03 12:03:36 +08004876 (uint32_t *)(base + LOGO_IMG_OFFSET + blocksize), readsize)) {
4877 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
4878 return -1;
4879 }
4880 memmove(base, (base + LOGO_IMG_OFFSET + LOGO_IMG_HEADER_SIZE), realsize);
4881 }
4882 }
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304883 }
4884
Mao Flynn7b379f32015-04-20 00:28:30 +08004885 return 0;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304886}
4887
Mao Flynn7b379f32015-04-20 00:28:30 +08004888int fetch_image_from_partition()
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304889{
4890 if (target_is_emmc_boot()) {
4891 return splash_screen_mmc();
4892 } else {
4893 return splash_screen_flash();
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07004894 }
4895}
4896
Mayank Grover351a75e2017-05-30 20:06:08 +05304897void publish_getvar_multislot_vars()
4898{
4899 int i,count;
4900 static bool published = false;
4901 static char slot_count[MAX_RSP_SIZE];
4902 static struct ab_slot_info slot_info[AB_SUPPORTED_SLOTS];
4903 static char active_slot_suffix[MAX_RSP_SIZE];
4904 static char has_slot_pname[NUM_PARTITIONS][MAX_GET_VAR_NAME_SIZE];
4905 static char has_slot_reply[NUM_PARTITIONS][MAX_RSP_SIZE];
4906 const char *tmp;
4907 char tmpbuff[MAX_GET_VAR_NAME_SIZE];
Mayank Grover2bd84bb2017-06-20 11:06:07 +05304908 signed active_slt;
Mayank Grover351a75e2017-05-30 20:06:08 +05304909
4910 if (!published)
4911 {
4912 /* Update slot meta info */
4913 count = partition_fill_partition_meta(has_slot_pname, has_slot_reply,
4914 partition_get_partition_count());
4915 for(i=0; i<count; i++)
4916 {
4917 memset(tmpbuff, 0, MAX_GET_VAR_NAME_SIZE);
Mayank Grover2bd84bb2017-06-20 11:06:07 +05304918 snprintf(tmpbuff, MAX_GET_VAR_NAME_SIZE,"has-slot:%s",
4919 has_slot_pname[i]);
4920 strlcpy(has_slot_pname[i], tmpbuff, MAX_GET_VAR_NAME_SIZE);
Mayank Grover351a75e2017-05-30 20:06:08 +05304921 fastboot_publish(has_slot_pname[i], has_slot_reply[i]);
4922 }
4923
4924 for (i=0; i<AB_SUPPORTED_SLOTS; i++)
4925 {
4926 tmp = SUFFIX_SLOT(i);
Mayank Grover7b8a8f82017-10-27 13:07:59 +05304927 tmp++; // to remove "_" from slot_suffix.
Mayank Grover2bd84bb2017-06-20 11:06:07 +05304928 snprintf(slot_info[i].slot_is_unbootable, sizeof(slot_info[i].slot_is_unbootable),
4929 "slot-unbootable:%s", tmp);
4930 snprintf(slot_info[i].slot_is_active, sizeof(slot_info[i].slot_is_active),
4931 "slot-active:%s", tmp);
4932 snprintf(slot_info[i].slot_is_succesful, sizeof(slot_info[i].slot_is_succesful),
4933 "slot-success:%s", tmp);
4934 snprintf(slot_info[i].slot_retry_count, sizeof(slot_info[i].slot_retry_count),
4935 "slot-retry-count:%s", tmp);
Mayank Grover351a75e2017-05-30 20:06:08 +05304936 fastboot_publish(slot_info[i].slot_is_unbootable,
4937 slot_info[i].slot_is_unbootable_rsp);
4938 fastboot_publish(slot_info[i].slot_is_active,
4939 slot_info[i].slot_is_active_rsp);
4940 fastboot_publish(slot_info[i].slot_is_succesful,
4941 slot_info[i].slot_is_succesful_rsp);
4942 fastboot_publish(slot_info[i].slot_retry_count,
4943 slot_info[i].slot_retry_count_rsp);
4944 }
4945 fastboot_publish("current-slot", active_slot_suffix);
4946 snprintf(slot_count, sizeof(slot_count),"%d", AB_SUPPORTED_SLOTS);
4947 fastboot_publish("slot-count", slot_count);
4948 published = true;
4949 }
4950
Mayank Grover2bd84bb2017-06-20 11:06:07 +05304951 active_slt = partition_find_active_slot();
4952 if (active_slt != INVALID)
Mayank Grover7b8a8f82017-10-27 13:07:59 +05304953 {
4954 tmp = SUFFIX_SLOT(active_slt);
4955 tmp++; // to remove "_" from slot_suffix.
4956 snprintf(active_slot_suffix, sizeof(active_slot_suffix), "%s", tmp);
4957 }
Mayank Grover2bd84bb2017-06-20 11:06:07 +05304958 else
4959 strlcpy(active_slot_suffix, "INVALID", sizeof(active_slot_suffix));
4960
Mayank Grover351a75e2017-05-30 20:06:08 +05304961 /* Update partition meta information */
4962 partition_fill_slot_meta(slot_info);
4963 return;
4964}
4965
lijuang4ece1e72015-08-14 21:02:36 +08004966void get_product_name(unsigned char *buf)
4967{
4968 snprintf((char*)buf, MAX_RSP_SIZE, "%s", TARGET(BOARD));
4969 return;
4970}
4971
Mayank Grover7b8a8f82017-10-27 13:07:59 +05304972#if PRODUCT_IOT
4973void get_bootloader_version_iot(unsigned char *buf)
4974{
4975 if (buf != NULL)
4976 {
4977 strlcpy(buf, TARGET(BOARD), MAX_VERSION_LEN);
4978 strlcat(buf, "-", MAX_VERSION_LEN);
4979 strlcat(buf, PRODUCT_IOT_VERSION, MAX_VERSION_LEN);
4980 }
4981 return;
4982}
4983#endif
4984
lijuang4ece1e72015-08-14 21:02:36 +08004985void get_bootloader_version(unsigned char *buf)
4986{
4987 snprintf((char*)buf, MAX_RSP_SIZE, "%s", device.bootloader_version);
4988 return;
4989}
4990
4991void get_baseband_version(unsigned char *buf)
4992{
4993 snprintf((char*)buf, MAX_RSP_SIZE, "%s", device.radio_version);
4994 return;
4995}
4996
Monika Singh32a09f72018-03-14 13:08:29 +05304997bool is_device_locked_critical()
4998{
4999 return device.is_unlock_critical ? false:true;
5000}
5001
lijuang4ece1e72015-08-14 21:02:36 +08005002bool is_device_locked()
5003{
5004 return device.is_unlocked ? false:true;
5005}
5006
Monika Singh32a09f72018-03-14 13:08:29 +05305007bool is_verity_enforcing()
5008{
5009 return device.verity_mode ? true:false;
5010}
5011
Amol Jadi5edf3552013-07-23 14:15:34 -07005012/* register commands and variables for fastboot */
5013void aboot_fastboot_register_commands(void)
5014{
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005015 int i;
lijuangf16461c2015-08-03 17:09:34 +08005016 char hw_platform_buf[MAX_RSP_SIZE];
Amol Jadi5edf3552013-07-23 14:15:34 -07005017
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005018 struct fastboot_cmd_desc cmd_list[] = {
lijuang511a2b52015-08-14 20:50:51 +08005019 /* By default the enabled list is empty. */
5020 {"", NULL},
5021 /* move commands enclosed within the below ifndef to here
5022 * if they need to be enabled in user build.
5023 */
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005024#ifndef DISABLE_FASTBOOT_CMDS
lijuang511a2b52015-08-14 20:50:51 +08005025 /* Register the following commands only for non-user builds */
5026 {"flash:", cmd_flash},
5027 {"erase:", cmd_erase},
5028 {"boot", cmd_boot},
5029 {"continue", cmd_continue},
5030 {"reboot", cmd_reboot},
5031 {"reboot-bootloader", cmd_reboot_bootloader},
5032 {"oem unlock", cmd_oem_unlock},
5033 {"oem unlock-go", cmd_oem_unlock_go},
5034 {"oem lock", cmd_oem_lock},
5035 {"flashing unlock", cmd_oem_unlock},
5036 {"flashing lock", cmd_oem_lock},
5037 {"flashing lock_critical", cmd_flashing_lock_critical},
5038 {"flashing unlock_critical", cmd_flashing_unlock_critical},
5039 {"flashing get_unlock_ability", cmd_flashing_get_unlock_ability},
5040 {"oem device-info", cmd_oem_devinfo},
5041 {"preflash", cmd_preflash},
5042 {"oem enable-charger-screen", cmd_oem_enable_charger_screen},
5043 {"oem disable-charger-screen", cmd_oem_disable_charger_screen},
lijuanga25d8bb2015-09-16 13:11:52 +08005044 {"oem off-mode-charge", cmd_oem_off_mode_charger},
lijuang511a2b52015-08-14 20:50:51 +08005045 {"oem select-display-panel", cmd_oem_select_display_panel},
Mayank Grover6ccc1c92017-07-04 17:36:46 +05305046 {"set_active",cmd_set_active},
Mayank Grover98c4c742019-04-25 17:21:37 +05305047#if DYNAMIC_PARTITION_SUPPORT
5048 {"reboot-fastboot",cmd_reboot_fastboot},
5049 {"reboot-recovery",cmd_reboot_recovery},
5050#endif
AnilKumar Chimata7fb62f92017-07-11 12:30:17 +05305051 {"oem qseecom-test", cmd_oem_qseecom_test_cmd_handler},
Channagoud Kadabi736c4962015-08-21 11:56:52 -07005052#if UNITTEST_FW_SUPPORT
Channagoud Kadabid5ddf482015-09-28 10:31:35 -07005053 {"oem run-tests", cmd_oem_runtests},
Channagoud Kadabi736c4962015-08-21 11:56:52 -07005054#endif
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005055#endif
lijuang511a2b52015-08-14 20:50:51 +08005056 };
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005057
5058 int fastboot_cmds_count = sizeof(cmd_list)/sizeof(cmd_list[0]);
5059 for (i = 1; i < fastboot_cmds_count; i++)
5060 fastboot_register(cmd_list[i].name,cmd_list[i].cb);
5061
Amol Jadi5edf3552013-07-23 14:15:34 -07005062 /* publish variables and their values */
5063 fastboot_publish("product", TARGET(BOARD));
5064 fastboot_publish("kernel", "lk");
5065 fastboot_publish("serialno", sn_buf);
5066
Mayank Grovera64dfbe2018-05-17 14:06:34 +05305067 /*publish hw-revision major(upper 16 bits) and minor(lower 16 bits)*/
5068 snprintf(soc_version_str, MAX_RSP_SIZE, "%x", board_soc_version());
5069 fastboot_publish("hw-revision", soc_version_str);
5070
Amol Jadi5edf3552013-07-23 14:15:34 -07005071 /*
5072 * partition info is supported only for emmc partitions
5073 * Calling this for NAND prints some error messages which
5074 * is harmless but misleading. Avoid calling this for NAND
5075 * devices.
5076 */
5077 if (target_is_emmc_boot())
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305078 publish_getvar_partition_info(part_info, partition_get_partition_count());
Amol Jadi5edf3552013-07-23 14:15:34 -07005079
Mayank Grover351a75e2017-05-30 20:06:08 +05305080 if (partition_multislot_is_supported())
5081 publish_getvar_multislot_vars();
5082
Amol Jadi5edf3552013-07-23 14:15:34 -07005083 /* Max download size supported */
lijuang2fbed912019-07-12 14:15:05 +08005084#if !VERIFIED_BOOT_2
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005085 snprintf(max_download_size, MAX_RSP_SIZE, "\t0x%x",
5086 target_get_max_flash_size());
lijuang2fbed912019-07-12 14:15:05 +08005087#else
5088 snprintf(max_download_size, MAX_RSP_SIZE, "\t0x%x",
5089 SUB_SALT_BUFF_OFFSET(target_get_max_flash_size()));
5090#endif
5091
Amol Jadi5edf3552013-07-23 14:15:34 -07005092 fastboot_publish("max-download-size", (const char *) max_download_size);
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005093 /* Is the charger screen check enabled */
5094 snprintf(charger_screen_enabled, MAX_RSP_SIZE, "%d",
5095 device.charger_screen_enabled);
5096 fastboot_publish("charger-screen-enabled",
5097 (const char *) charger_screen_enabled);
lijuanga25d8bb2015-09-16 13:11:52 +08005098 fastboot_publish("off-mode-charge", (const char *) charger_screen_enabled);
Unnati Gandhi62c8ab82014-01-24 11:01:01 +05305099 snprintf(panel_display_mode, MAX_RSP_SIZE, "%s",
5100 device.display_panel);
5101 fastboot_publish("display-panel",
5102 (const char *) panel_display_mode);
Mukesh Ojhabb6e7f32018-03-02 15:04:06 +05305103
5104 if (target_is_emmc_boot())
5105 {
5106 mmc_blocksize = mmc_get_device_blocksize();
5107 }
5108 else
5109 {
5110 mmc_blocksize = flash_block_size();
5111 }
5112 snprintf(block_size_string, MAX_RSP_SIZE, "0x%x", mmc_blocksize);
5113 fastboot_publish("erase-block-size", (const char *) block_size_string);
5114 fastboot_publish("logical-block-size", (const char *) block_size_string);
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305115#if PRODUCT_IOT
5116 get_bootloader_version_iot(&bootloader_version_string);
5117 fastboot_publish("version-bootloader", (const char *) bootloader_version_string);
5118
5119 /* Version baseband is n/a for apq iot devices */
5120 fastboot_publish("version-baseband", "N/A");
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305121#else
Channagoud Kadabiaafbbfc2015-03-04 17:52:56 -08005122 fastboot_publish("version-bootloader", (const char *) device.bootloader_version);
5123 fastboot_publish("version-baseband", (const char *) device.radio_version);
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305124#endif
lijuangf16461c2015-08-03 17:09:34 +08005125 fastboot_publish("secure", is_secure_boot_enable()? "yes":"no");
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305126 fastboot_publish("unlocked", device.is_unlocked ? "yes":"no");
lijuangf16461c2015-08-03 17:09:34 +08005127 smem_get_hw_platform_name((unsigned char *) hw_platform_buf, sizeof(hw_platform_buf));
5128 snprintf(get_variant, MAX_RSP_SIZE, "%s %s", hw_platform_buf,
5129 target_is_emmc_boot()? "eMMC":"UFS");
5130 fastboot_publish("variant", (const char *) get_variant);
lijuang65c5a822015-08-29 16:35:36 +08005131#if CHECK_BAT_VOLTAGE
lijuang102dfa92015-10-09 18:31:03 +08005132 update_battery_status();
lijuang65c5a822015-08-29 16:35:36 +08005133 fastboot_publish("battery-voltage", (const char *) battery_voltage);
lijuang102dfa92015-10-09 18:31:03 +08005134 fastboot_publish("battery-soc-ok", (const char *) battery_soc_ok);
lijuang65c5a822015-08-29 16:35:36 +08005135#endif
Mayank Grover98c4c742019-04-25 17:21:37 +05305136 if (target_dynamic_partition_supported())
5137 fastboot_publish("is-userspace", "no");
Amol Jadi5edf3552013-07-23 14:15:34 -07005138}
5139
Brian Swetland9c4c0752009-01-25 16:23:50 -08005140void aboot_init(const struct app_descriptor *app)
5141{
Shashank Mittal4f99a882010-02-01 13:58:50 -08005142 unsigned reboot_mode = 0;
Mayank Grover351a75e2017-05-30 20:06:08 +05305143 int boot_err_type = 0;
5144 int boot_slot = INVALID;
Chandan Uddarajubedca152010-06-02 23:05:15 -07005145
lijuang39831732016-01-08 17:49:02 +08005146 /* Initialise wdog to catch early lk crashes */
5147#if WDOG_SUPPORT
5148 msm_wdog_init();
5149#endif
5150
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07005151 /* Setup page size information for nv storage */
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005152 if (target_is_emmc_boot())
5153 {
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07005154 page_size = mmc_page_size();
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005155 page_mask = page_size - 1;
Gaurav Nebhwani4d2389c2016-03-17 21:10:05 +05305156 mmc_blocksize = mmc_get_device_blocksize();
5157 mmc_blocksize_mask = mmc_blocksize - 1;
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005158 }
5159 else
5160 {
5161 page_size = flash_page_size();
5162 page_mask = page_size - 1;
5163 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07005164 ASSERT((MEMBASE + MEMSIZE) > MEMBASE);
5165
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005166 read_device_info(&device);
vijay kumarc65876c2015-04-24 13:29:16 +05305167 read_allow_oem_unlock(&device);
Shashank Mittal162244e2011-08-08 19:01:25 -07005168
Mayank Grover351a75e2017-05-30 20:06:08 +05305169 /* Detect multi-slot support */
5170 if (partition_multislot_is_supported())
5171 {
5172 boot_slot = partition_find_active_slot();
5173 if (boot_slot == INVALID)
5174 {
5175 boot_into_fastboot = true;
5176 dprintf(INFO, "Active Slot: (INVALID)\n");
5177 }
5178 else
5179 {
5180 /* Setting the state of system to boot active slot */
5181 partition_mark_active_slot(boot_slot);
5182 dprintf(INFO, "Active Slot: (%s)\n", SUFFIX_SLOT(boot_slot));
5183 }
5184 }
5185
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08005186 /* Display splash screen if enabled */
5187#if DISPLAY_SPLASH_SCREEN
lijuang99c02d82015-02-13 19:04:34 +08005188#if NO_ALARM_DISPLAY
5189 if (!check_alarm_boot()) {
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08005190#endif
lijuang99c02d82015-02-13 19:04:34 +08005191 dprintf(SPEW, "Display Init: Start\n");
Ajay Singh Parmara7865a82015-04-16 21:27:52 -07005192#if DISPLAY_HDMI_PRIMARY
5193 if (!strlen(device.display_panel))
5194 strlcpy(device.display_panel, DISPLAY_PANEL_HDMI,
5195 sizeof(device.display_panel));
5196#endif
Channagoud Kadabi90869ce2015-04-27 11:15:14 -07005197#if ENABLE_WBC
Channagoud Kadabid801ac72015-08-26 11:21:51 -07005198 /* Wait if the display shutdown is in progress */
5199 while(pm_app_display_shutdown_in_prgs());
Channagoud Kadabi90869ce2015-04-27 11:15:14 -07005200 if (!pm_appsbl_display_init_done())
5201 target_display_init(device.display_panel);
5202 else
5203 display_image_on_screen();
5204#else
lijuang99c02d82015-02-13 19:04:34 +08005205 target_display_init(device.display_panel);
Channagoud Kadabi90869ce2015-04-27 11:15:14 -07005206#endif
lijuang99c02d82015-02-13 19:04:34 +08005207 dprintf(SPEW, "Display Init: Done\n");
5208#if NO_ALARM_DISPLAY
5209 }
5210#endif
5211#endif
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08005212
Greg Griscod6250552011-06-29 14:40:23 -07005213 target_serialno((unsigned char *) sn_buf);
Ajay Dudanib06c05f2011-05-12 14:46:10 -07005214 dprintf(SPEW,"serial number: %s\n",sn_buf);
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -08005215
Dhaval Patel223ec952013-07-18 14:49:44 -07005216 memset(display_panel_buf, '\0', MAX_PANEL_BUF_SIZE);
5217
Matthew Qindefd5562014-07-11 18:02:40 +08005218 /*
5219 * Check power off reason if user force reset,
5220 * if yes phone will do normal boot.
5221 */
5222 if (is_user_force_reset())
5223 goto normal_boot;
5224
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005225 /* Check if we should do something other than booting up */
Ameya Thakur0b9c2442013-05-10 13:22:56 -07005226 if (keys_get_state(KEY_VOLUMEUP) && keys_get_state(KEY_VOLUMEDOWN))
Subbaraman Narayanamurthy0e445b02011-06-19 21:34:46 -07005227 {
Pavel Nedeva4c9d3a2013-05-15 14:42:34 +03005228 dprintf(ALWAYS,"dload mode key sequence detected\n");
lijuang395b5e62015-11-19 17:39:44 +08005229 reboot_device(EMERGENCY_DLOAD);
5230 dprintf(CRITICAL,"Failed to reboot into dload mode\n");
5231
Ameya Thakur0b9c2442013-05-10 13:22:56 -07005232 boot_into_fastboot = true;
5233 }
5234 if (!boot_into_fastboot)
5235 {
5236 if (keys_get_state(KEY_HOME) || keys_get_state(KEY_VOLUMEUP))
5237 boot_into_recovery = 1;
5238 if (!boot_into_recovery &&
5239 (keys_get_state(KEY_BACK) || keys_get_state(KEY_VOLUMEDOWN)))
Pavel Nedev5d91d412013-04-29 11:34:24 +03005240 boot_into_fastboot = true;
Subbaraman Narayanamurthy0e445b02011-06-19 21:34:46 -07005241 }
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005242 #if NO_KEYPAD_DRIVER
Kinson Chik0b1c8162011-08-31 16:31:57 -07005243 if (fastboot_trigger())
Pavel Nedev5d91d412013-04-29 11:34:24 +03005244 boot_into_fastboot = true;
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005245 #endif
Chandan Uddarajubedca152010-06-02 23:05:15 -07005246
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005247#if USE_PON_REBOOT_REG
5248 reboot_mode = check_hard_reboot_mode();
5249#else
Ajay Dudani77421292010-10-27 19:34:06 -07005250 reboot_mode = check_reboot_mode();
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005251#endif
5252 if (reboot_mode == RECOVERY_MODE)
5253 {
Ajay Dudani77421292010-10-27 19:34:06 -07005254 boot_into_recovery = 1;
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005255 }
5256 else if(reboot_mode == FASTBOOT_MODE)
5257 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005258 boot_into_fastboot = true;
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005259 }
5260 else if(reboot_mode == ALARM_BOOT)
5261 {
Matthew Qind886f3c2014-01-17 16:52:01 +08005262 boot_reason_alarm = true;
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005263 }
Monika Singhb0db4b82018-09-26 12:18:02 +05305264#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05305265 else if (VB_M <= target_get_vb_version())
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005266 {
Mayank Grover889be1b2017-09-12 20:12:23 +05305267 if (reboot_mode == DM_VERITY_ENFORCING)
5268 {
5269 device.verity_mode = 1;
5270 write_device_info(&device);
5271 }
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07005272#if ENABLE_VB_ATTEST
Mayank Grover889be1b2017-09-12 20:12:23 +05305273 else if (reboot_mode == DM_VERITY_EIO)
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07005274#else
Mayank Grover889be1b2017-09-12 20:12:23 +05305275 else if (reboot_mode == DM_VERITY_LOGGING)
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07005276#endif
Mayank Grover889be1b2017-09-12 20:12:23 +05305277 {
5278 device.verity_mode = 0;
5279 write_device_info(&device);
5280 }
5281 else if (reboot_mode == DM_VERITY_KEYSCLEAR)
5282 {
5283 if(send_delete_keys_to_tz())
5284 ASSERT(0);
5285 }
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005286 }
Parth Dixitddbc7352015-10-18 03:13:31 +05305287#endif
Ajay Dudani77421292010-10-27 19:34:06 -07005288
Matthew Qindefd5562014-07-11 18:02:40 +08005289normal_boot:
Pavel Nedev5d91d412013-04-29 11:34:24 +03005290 if (!boot_into_fastboot)
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005291 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005292 if (target_is_emmc_boot())
Shashank Mittala0032282011-08-26 14:50:11 -07005293 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005294 if(emmc_recovery_init())
5295 dprintf(ALWAYS,"error in emmc_recovery_init\n");
5296 if(target_use_signed_kernel())
Shashank Mittala0032282011-08-26 14:50:11 -07005297 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005298 if((device.is_unlocked) || (device.is_tampered))
5299 {
5300 #ifdef TZ_TAMPER_FUSE
Monika Singh98257462018-06-06 11:28:49 +05305301 set_tamper_fuse_cmd(HLOS_IMG_TAMPER_FUSE);
Pavel Nedev5d91d412013-04-29 11:34:24 +03005302 #endif
5303 #if USE_PCOM_SECBOOT
5304 set_tamper_flag(device.is_tampered);
5305 #endif
5306 }
Shashank Mittala0032282011-08-26 14:50:11 -07005307 }
Amit Blay6281ebc2015-01-11 14:44:08 +02005308
Mayank Grover351a75e2017-05-30 20:06:08 +05305309retry_boot:
5310 /* Trying to boot active partition */
5311 if (partition_multislot_is_supported())
5312 {
5313 boot_slot = partition_find_boot_slot();
5314 partition_mark_active_slot(boot_slot);
5315 if (boot_slot == INVALID)
5316 goto fastboot;
5317 }
5318
5319 boot_err_type = boot_linux_from_mmc();
5320 switch (boot_err_type)
5321 {
5322 case ERR_INVALID_PAGE_SIZE:
5323 case ERR_DT_PARSE:
5324 case ERR_ABOOT_ADDR_OVERLAP:
Mayank Grover10cabbe2017-10-30 19:11:05 +05305325 case ERR_INVALID_BOOT_MAGIC:
Mayank Grover351a75e2017-05-30 20:06:08 +05305326 if(partition_multislot_is_supported())
Mayank Grover10cabbe2017-10-30 19:11:05 +05305327 {
5328 /*
5329 * Deactivate current slot, as it failed to
5330 * boot, and retry next slot.
5331 */
5332 partition_deactivate_slot(boot_slot);
Mayank Grover351a75e2017-05-30 20:06:08 +05305333 goto retry_boot;
Mayank Grover10cabbe2017-10-30 19:11:05 +05305334 }
Mayank Grover351a75e2017-05-30 20:06:08 +05305335 else
5336 break;
Mayank Grover351a75e2017-05-30 20:06:08 +05305337 default:
5338 break;
5339 /* going to fastboot menu */
5340 }
Shashank Mittala0032282011-08-26 14:50:11 -07005341 }
Pavel Nedev5d91d412013-04-29 11:34:24 +03005342 else
5343 {
5344 recovery_init();
5345 #if USE_PCOM_SECBOOT
5346 if((device.is_unlocked) || (device.is_tampered))
5347 set_tamper_flag(device.is_tampered);
5348 #endif
5349 boot_linux_from_flash();
5350 }
5351 dprintf(CRITICAL, "ERROR: Could not do normal boot. Reverting "
5352 "to fastboot mode.\n");
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005353 }
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005354
Mayank Grover351a75e2017-05-30 20:06:08 +05305355fastboot:
Amol Jadi5edf3552013-07-23 14:15:34 -07005356 /* We are here means regular boot did not happen. Start fastboot. */
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -07005357
Amol Jadi5edf3552013-07-23 14:15:34 -07005358 /* register aboot specific fastboot commands */
5359 aboot_fastboot_register_commands();
Amol Jadi57abe4c2011-05-24 15:47:27 -07005360
Amol Jadi5edf3552013-07-23 14:15:34 -07005361 /* dump partition table for debug info */
Kinson Chikf1a43512011-07-14 11:28:39 -07005362 partition_dump();
Amol Jadi5edf3552013-07-23 14:15:34 -07005363
5364 /* initialize and start fastboot */
Saranya Chidura41b34532018-10-16 12:29:52 +05305365#if !VERIFIED_BOOT_2
Amol Jadi5edf3552013-07-23 14:15:34 -07005366 fastboot_init(target_get_scratch_address(), target_get_max_flash_size());
Saranya Chidura41b34532018-10-16 12:29:52 +05305367#else
5368 /* Add salt buffer offset at start of image address to copy VB salt */
5369 fastboot_init(ADD_SALT_BUFF_OFFSET(target_get_scratch_address()),
5370 SUB_SALT_BUFF_OFFSET(target_get_max_flash_size()));
5371#endif
lijuang4ece1e72015-08-14 21:02:36 +08005372#if FBCON_DISPLAY_MSG
lijuang9a7d3b92015-11-30 14:41:24 +08005373 display_fastboot_menu();
lijuang4ece1e72015-08-14 21:02:36 +08005374#endif
Brian Swetland9c4c0752009-01-25 16:23:50 -08005375}
5376
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07005377uint32_t get_page_size()
5378{
5379 return page_size;
5380}
5381
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005382/*
5383 * Calculated and save hash (SHA256) for non-signed boot image.
5384 *
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005385 * @param image_addr - Boot image address
5386 * @param image_size - Size of the boot image
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005387 *
5388 * @return int - 0 on success, negative value on failure.
5389 */
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005390static int aboot_save_boot_hash_mmc(uint32_t image_addr, uint32_t image_size)
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005391{
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005392 unsigned int digest[8];
5393#if IMAGE_VERIF_ALGO_SHA1
5394 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA1;
5395#else
5396 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
5397#endif
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005398
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005399 target_crypto_init_params();
Veera Sundaram Sankaranf9915462014-12-09 11:54:59 -08005400 hash_find((unsigned char *) image_addr, image_size, (unsigned char *)&digest, auth_algo);
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005401
5402 save_kernel_hash_cmd(digest);
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005403 dprintf(INFO, "aboot_save_boot_hash_mmc: imagesize_actual size %d bytes.\n", (int) image_size);
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005404
5405 return 0;
5406}
5407
Mayank Grover351a75e2017-05-30 20:06:08 +05305408
Brian Swetland9c4c0752009-01-25 16:23:50 -08005409APP_START(aboot)
5410 .init = aboot_init,
5411APP_END